MINOR: stream-int: Notify mux when the buffer is not stuck when calling rcv_buf

The transient flag CO_RFL_BUF_NOT_STUCK should now be set when the mux's
rcv_buf() function is called, in si_cs_recv(), to be sure the mux is able to
perform some optimisation during data copy. This flag is set when we are
sure the channel buffer is not stuck. Concretely, it happens when there are
data scheduled to be sent.

It is not a fix and this flag is not used for now. But it makes sense to have
this info to be sure to be able to do some optimisations if necessary.

This patch is related to the issue #1362. It may be backported to 2.4 to
ease future backports.
This commit is contained in:
Christopher Faulet 2021-09-21 15:50:55 +02:00
parent 2bc364c191
commit 564e39c4c6
6 changed files with 54 additions and 9 deletions

View File

@ -276,10 +276,11 @@ enum {
/* flags that can be passed to xprt->rcv_buf() and mux->rcv_buf() */
enum {
CO_RFL_BUF_WET = 0x0001, /* Buffer still has some output data present */
CO_RFL_BUF_FLUSH = 0x0002, /* Flush mux's buffers but don't read more data */
CO_RFL_READ_ONCE = 0x0004, /* don't loop even if the request/response is small */
CO_RFL_KEEP_RECV = 0x0008, /* Instruct the mux to still wait for read events */
CO_RFL_BUF_WET = 0x0001, /* Buffer still has some output data present */
CO_RFL_BUF_FLUSH = 0x0002, /* Flush mux's buffers but don't read more data */
CO_RFL_READ_ONCE = 0x0004, /* don't loop even if the request/response is small */
CO_RFL_KEEP_RECV = 0x0008, /* Instruct the mux to still wait for read events */
CO_RFL_BUF_NOT_STUCK = 0x0010, /* Buffer is not stuck. Optims are possible during data copy */
};
/* flags that can be passed to xprt->snd_buf() and mux->snd_buf() */

View File

@ -3910,7 +3910,18 @@ static int fcgi_unsubscribe(struct conn_stream *cs, int event_type, struct wait_
return 0;
}
/* Called from the upper layer, to receive data */
/* Called from the upper layer, to receive data
*
* The caller is responsible for defragmenting <buf> if necessary. But <flags>
* must be tested to know the calling context. If CO_RFL_BUF_FLUSH is set, it
* means the caller wants to flush input data (from the mux buffer and the
* channel buffer) to be able to use kernel splicing or any kind of mux-to-mux
* xfer. If CO_RFL_KEEP_RECV is set, the mux must always subscribe for read
* events before giving back. CO_RFL_BUF_WET is set if <buf> is congested with
* data scheduled for leaving soon. CO_RFL_BUF_NOT_STUCK is set to instruct the
* mux it may optimize the data copy to <buf> if necessary. Otherwise, it should
* copy as much data as possible.
*/
static size_t fcgi_rcv_buf(struct conn_stream *cs, struct buffer *buf, size_t count, int flags)
{
struct fcgi_strm *fstrm = cs->ctx;

View File

@ -3337,7 +3337,18 @@ static int h1_subscribe(struct conn_stream *cs, int event_type, struct wait_even
return 0;
}
/* Called from the upper layer, to receive data */
/* Called from the upper layer, to receive data.
*
* The caller is responsible for defragmenting <buf> if necessary. But <flags>
* must be tested to know the calling context. If CO_RFL_BUF_FLUSH is set, it
* means the caller wants to flush input data (from the mux buffer and the
* channel buffer) to be able to use kernel splicing or any kind of mux-to-mux
* xfer. If CO_RFL_KEEP_RECV is set, the mux must always subscribe for read
* events before giving back. CO_RFL_BUF_WET is set if <buf> is congested with
* data scheduled for leaving soon. CO_RFL_BUF_NOT_STUCK is set to instruct the
* mux it may optimize the data copy to <buf> if necessary. Otherwise, it should
* copy as much data as possible.
*/
static size_t h1_rcv_buf(struct conn_stream *cs, struct buffer *buf, size_t count, int flags)
{
struct h1s *h1s = cs->ctx;

View File

@ -6255,7 +6255,18 @@ static int h2_unsubscribe(struct conn_stream *cs, int event_type, struct wait_ev
}
/* Called from the upper layer, to receive data */
/* Called from the upper layer, to receive data
*
* The caller is responsible for defragmenting <buf> if necessary. But <flags>
* must be tested to know the calling context. If CO_RFL_BUF_FLUSH is set, it
* means the caller wants to flush input data (from the mux buffer and the
* channel buffer) to be able to use kernel splicing or any kind of mux-to-mux
* xfer. If CO_RFL_KEEP_RECV is set, the mux must always subscribe for read
* events before giving back. CO_RFL_BUF_WET is set if <buf> is congested with
* data scheduled for leaving soon. CO_RFL_BUF_NOT_STUCK is set to instruct the
* mux it may optimize the data copy to <buf> if necessary. Otherwise, it should
* copy as much data as possible.
*/
static size_t h2_rcv_buf(struct conn_stream *cs, struct buffer *buf, size_t count, int flags)
{
struct h2s *h2s = cs->ctx;

View File

@ -484,6 +484,16 @@ static void mux_pt_shutw(struct conn_stream *cs, enum cs_shw_mode mode)
/*
* Called from the upper layer, to get more data
*
* The caller is responsible for defragmenting <buf> if necessary. But <flags>
* must be tested to know the calling context. If CO_RFL_BUF_FLUSH is set, it
* means the caller wants to flush input data (from the mux buffer and the
* channel buffer) to be able to use kernel splicing or any kind of mux-to-mux
* xfer. If CO_RFL_KEEP_RECV is set, the mux must always subscribe for read
* events before giving back. CO_RFL_BUF_WET is set if <buf> is congested with
* data scheduled for leaving soon. CO_RFL_BUF_NOT_STUCK is set to instruct the
* mux it may optimize the data copy to <buf> if necessary. Otherwise, it should
* copy as much data as possible.
*/
static size_t mux_pt_rcv_buf(struct conn_stream *cs, struct buffer *buf, size_t count, int flags)
{

View File

@ -1366,8 +1366,9 @@ int si_cs_recv(struct conn_stream *cs)
int cur_flags = flags;
/* Compute transient CO_RFL_* flags */
if (co_data(ic))
cur_flags |= CO_RFL_BUF_WET;
if (co_data(ic)) {
cur_flags |= (CO_RFL_BUF_WET | CO_RFL_BUF_NOT_STUCK);
}
/* <max> may be null. This is the mux responsibility to set
* CS_FL_RCV_MORE on the CS if more space is needed.