OPTIM: mux-h2: make h2_send() report more accurate wake up conditions
h2_send() used to report non-zero every time any data were sent, and this was used from h2_snd_buf() or h2_done_ff() to trigger a wakeup, which possibly can do nothing. Restricting this wakeup to either a successful send() combined with the ability to demux, or an error. Doing this makes the number of h2_io_cb() wakeups drop from 422k to 245k for 1000 1MB objects delivered over 100 streams between two H2 proxies, without any behavior change nor performance change. In practice, most send() calls do not result in a wakeup anymore but synchronous errors still do. A local test downloading 10k 1MB objects from an H1 server with a single connection shows this change: before after caller 1547 1467 h2_process_demux() 2138 0 h2_done_ff() <--- 38 1453 ssl_sock_io_cb() <--- 18 0 h2_snd_buf() 1 1 h2_init() 3742 2921 -- total -- In practice the ssl_sock_io_cb() wakeups are those notifying about SUB_RETRY_RECV, which are not accounted for when h2_done_ff() performs the wakeup because the tasklet is already queued (a counter placed there shows that it's nonetheless called). So there's no transfer and h2_done_ff() was only hiding the other one. Another test involving 4 connections with 10 concurrent streams each and 20000 1MB objects total shows a total disparition of the wakeups from h2_snd_buf and h2_done_ff, which used to account together for 50% of the wakeups, resulting in effectively halving the number of wakeups which, based on their avg process time, were not doing anything: Before: function calls cpu_tot cpu_avg h2_io_cb 2571208 7.406s 2.880us <- h2c_restart_reading@src/mux_h2.c:940 tasklet_wakeup h2_io_cb 2536949 251.4ms 99.00ns <- h2_snd_buf@src/mux_h2.c:7573 tasklet_wakeup ### h2_io_cb 41100 5.622ms 136.0ns <- h2_done_ff@src/mux_h2.c:7779 tasklet_wakeup ### h2_io_cb 38979 852.8ms 21.88us <- sock_conn_iocb@src/sock.c:1007 tasklet_wakeup h2_io_cb 12519 90.28ms 7.211us <- ssl_sock_io_cb@src/ssl_sock.c:5721 tasklet_wakeup h2_io_cb 1 13.81us 13.81us <- sock_conn_iocb@src/sock.c:986 tasklet_wakeup h2_io_cb 5200756 8.606s 1.654us --total-- After: h2_io_cb 2562340 8.157s 3.183us <- h2c_restart_reading@src/mux_h2.c:957 tasklet_wakeup h2_io_cb 30109 840.9ms 27.93us <- sock_conn_iocb@src/sock.c:1007 tasklet_wakeup h2_io_cb 16105 106.4ms 6.607us <- ssl_sock_io_cb@src/ssl_sock.c:5721 tasklet_wakeup h2_io_cb 1 11.75us 11.75us <- sock_conn_iocb@src/sock.c:986 tasklet_wakeup h2_io_cb 2608555 9.104s 3.490us --total--
This commit is contained in:
parent
633c41c621
commit
9fbc01710a
|
@ -4567,7 +4567,10 @@ static int h2_recv(struct h2c *h2c)
|
|||
}
|
||||
|
||||
/* Try to send data if possible.
|
||||
* The function returns 1 if data have been sent, otherwise zero.
|
||||
* The function returns non-zero if some state changes require to call the
|
||||
* tasklet handler to deal with changes, otherwise zero. Reasons for a wakeup
|
||||
* are non-zero data sent and ability to demux (indicating a previous blocking)
|
||||
* or report of a an error.
|
||||
*/
|
||||
static int h2_send(struct h2c *h2c)
|
||||
{
|
||||
|
@ -4706,7 +4709,7 @@ static int h2_send(struct h2c *h2c)
|
|||
}
|
||||
TRACE_DEVEL("leaving with some data left to send", H2_EV_H2C_SEND, h2c->conn);
|
||||
end:
|
||||
return sent || (h2c->flags & (H2_CF_ERR_PENDING|H2_CF_ERROR));
|
||||
return (sent && h2_may_demux(h2c)) || (h2c->flags & (H2_CF_ERR_PENDING|H2_CF_ERROR));
|
||||
}
|
||||
|
||||
/* this is the tasklet referenced in h2c->wait_event.tasklet */
|
||||
|
|
Loading…
Reference in New Issue