diff --git a/include/haproxy/stream-t.h b/include/haproxy/stream-t.h index 72b5f3a43..f942823de 100644 --- a/include/haproxy/stream-t.h +++ b/include/haproxy/stream-t.h @@ -143,7 +143,7 @@ struct stream { struct list back_refs; /* list of users tracking this stream */ struct buffer_wait buffer_wait; /* position in the list of objects waiting for a buffer */ - struct freq_ctr call_rate; /* stream task call rate */ + struct freq_ctr call_rate; /* stream task call rate without making progress */ short store_count; enum obj_type obj_type; /* object type == OBJ_TYPE_STREAM */ diff --git a/src/stream.c b/src/stream.c index 8f1da7625..d10b76e5d 100644 --- a/src/stream.c +++ b/src/stream.c @@ -1628,9 +1628,14 @@ struct task *process_stream(struct task *t, void *context, unsigned int state) si_sync_recv(si_f); si_sync_recv(si_b); - rate = update_freq_ctr(&s->call_rate, 1); - if (rate >= 100000 && s->call_rate.prev_ctr) { // make sure to wait at least a full second - stream_dump_and_crash(&s->obj_type, read_freq_ctr(&s->call_rate)); + /* Let's check if we're looping without making any progress, e.g. due + * to a bogus analyser or the fact that we're ignoring a read0. The + * call_rate counter only counts calls with no progress made. + */ + if (!((req->flags | res->flags) & (CF_READ_PARTIAL|CF_WRITE_PARTIAL))) { + rate = update_freq_ctr(&s->call_rate, 1); + if (rate >= 100000 && s->call_rate.prev_ctr) // make sure to wait at least a full second + stream_dump_and_crash(&s->obj_type, read_freq_ctr(&s->call_rate)); } /* this data may be no longer valid, clear it */