mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-11-25 21:01:09 +01:00
MINOR: server: ensure max_events_at_once > 0 in server_atomic_sync()
In 8f1fd96 ("BUG/MEDIUM: server/addr: fix tune.events.max-events-at-once
event miss and leak"), we added a comment saying that
tune.events.max-events-at-once is assumed to be strictly positive.
It is so because the keyword parser forces values between 1 and 10000:
we don't want less than 1 because it wouldn't make any sense, and 10k
max because beyond that we could create contention in server_atomic_sync()
Now as the above commit implements a do..while it heavily relies on the
fact that the budget is at least 1. Upon soft-stop, we break away from
the loop without decrementing the budget. With all that in mind, it is
safe to assume that the 'remain' counter will only fall to 0 if the task
runs out of budget while doing work, in which case the task still exists
and must be rescheduled.
As seen in GH #2667 this assumption was ambiguous, so let's make it
official by adding a pair of BUG_ON() that make it explicit that it
works because remain 'cannot' be 0 unless the entire budget was
consumed.
No backport needed.
This commit is contained in:
parent
3ef1ee477d
commit
a6d1eb8f5d
@ -227,6 +227,8 @@ static struct task *server_atomic_sync(struct task *task, void *context, unsigne
|
|||||||
unsigned int remain = event_hdl_tune.max_events_at_once; // to limit max number of events per batch
|
unsigned int remain = event_hdl_tune.max_events_at_once; // to limit max number of events per batch
|
||||||
struct event_hdl_async_event *event;
|
struct event_hdl_async_event *event;
|
||||||
|
|
||||||
|
BUG_ON(remain == 0); // event_hdl_tune.max_events_at_once is expected to be > 0
|
||||||
|
|
||||||
/* check for new server events that we care about */
|
/* check for new server events that we care about */
|
||||||
do {
|
do {
|
||||||
event = event_hdl_async_equeue_pop(&server_atomic_sync_queue);
|
event = event_hdl_async_equeue_pop(&server_atomic_sync_queue);
|
||||||
@ -317,7 +319,7 @@ static struct task *server_atomic_sync(struct task *task, void *context, unsigne
|
|||||||
srv_set_addr_desc(srv, 1);
|
srv_set_addr_desc(srv, 1);
|
||||||
}
|
}
|
||||||
event_hdl_async_free_event(event);
|
event_hdl_async_free_event(event);
|
||||||
} while (--remain); // event_hdl_tune.max_events_at_once is expected to be > 0
|
} while (--remain);
|
||||||
|
|
||||||
/* some events possibly required thread_isolation:
|
/* some events possibly required thread_isolation:
|
||||||
* now that we are done, we must leave thread isolation before
|
* now that we are done, we must leave thread isolation before
|
||||||
@ -334,6 +336,7 @@ static struct task *server_atomic_sync(struct task *task, void *context, unsigne
|
|||||||
* Reschedule the task to finish where we left off if
|
* Reschedule the task to finish where we left off if
|
||||||
* there are remaining events in the queue.
|
* there are remaining events in the queue.
|
||||||
*/
|
*/
|
||||||
|
BUG_ON(task == NULL); // ending event doesn't decrement remain
|
||||||
if (!event_hdl_async_equeue_isempty(&server_atomic_sync_queue))
|
if (!event_hdl_async_equeue_isempty(&server_atomic_sync_queue))
|
||||||
task_wakeup(task, TASK_WOKEN_OTHER);
|
task_wakeup(task, TASK_WOKEN_OTHER);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user