MINOR: mux-quic: realign Tx buffer if possible

A major reorganization of QUIC MUX sending has been implemented. Now
data transfer occur over a single QCS buffer. This has improve
performance but at the cost of restrictions on snd_buf. Indeed, buffer
instances are now shared from stream callback snd_buf up to quic-conn
layer.

As such, snd_buf cannot manipulate freely already present data buffer.
In particular, realign has been completely removed by the previous
patches.

This commit reintroduces a partial realign support. This is only done if
the buffer contains only unsent data, via a new MUX function
qcc_realign_stream_txbuf() which is called during snd_buf.
This commit is contained in:
Amaury Denoyelle 2024-01-17 16:01:00 +01:00
parent 4513787d0d
commit 4b5f557283
3 changed files with 30 additions and 3 deletions

View File

@ -25,6 +25,7 @@ int qcc_notify_buf(struct qcc *qcc);
struct buffer *qcc_get_stream_rxbuf(struct qcs *qcs);
struct buffer *qcc_get_stream_txbuf(struct qcs *qcs, int *err);
int qcc_realign_stream_txbuf(const struct qcs *qcs, struct buffer *out);
int qcc_release_stream_txbuf(struct qcs *qcs);
int qcc_stream_can_send(const struct qcs *qcs);
void qcc_reset_stream(struct qcs *qcs, int err);

View File

@ -1900,8 +1900,14 @@ static int h3_resp_data_send(struct qcs *qcs, struct htx *htx,
if (fsize > count)
fsize = count;
/* TODO buffer can be realign only if no data waiting for ACK. */
outbuf = b_make(b_tail(res), b_contig_space(res), 0, 0);
while (1) {
b_reset(&outbuf);
outbuf = b_make(b_tail(res), b_contig_space(res), 0, 0);
if (b_size(&outbuf) > hsize || !b_space_wraps(res))
break;
if (qcc_realign_stream_txbuf(qcs, res))
break;
}
/* Not enough room for headers and at least one data byte, try to
* release the current buffer and allocate a new one. If not possible,
@ -2082,7 +2088,12 @@ static size_t h3_nego_ff(struct qcs *qcs, size_t count)
/* h3 DATA headers : 1-byte frame type + varint frame length */
hsize = 1 + QUIC_VARINT_MAX_SIZE;
/* TODO buffer can be realign only if no data waiting for ACK. */
while (1) {
if (b_contig_space(res) >= hsize || !b_space_wraps(res))
break;
if (qcc_realign_stream_txbuf(qcs, res))
break;
}
/* Not enough room for headers and at least one data byte, block the
* stream. It is expected that the stream connector layer will subscribe

View File

@ -1019,6 +1019,21 @@ static uint64_t qcs_prep_bytes(const struct qcs *qcs)
return b_data(out) - diff;
}
/* Try to realign <out> buffer for <qcs> stream. This is done only if there is
* no data waiting for ACK.
*
* Returns 0 if realign was performed else non-zero.
*/
int qcc_realign_stream_txbuf(const struct qcs *qcs, struct buffer *out)
{
if (qcs_prep_bytes(qcs) == b_data(out)) {
b_slow_realign(out, trash.area, b_data(out));
return 0;
}
return 1;
}
/* Release the current <qcs> Tx buffer. This is useful if space left is not
* enough anymore. A new instance can then be allocated to continue sending.
*