*/
CO_FL_WAIT_ROOM = 0x00000800, /* data sink is full */
- /* These flags are used to report whether the from/to addresses are set or not */
- /* unused: 0x00001000 */
+ CO_FL_WANT_SPLICING = 0x00001000, /* we wish to use splicing on the connection when possible */
/* unused: 0x00002000 */
CO_FL_EARLY_SSL_HS = 0x00004000, /* We have early data pending, don't start SSL handshake yet */
* supported to mix data.
*/
if (!b_data(input) && !b_data(&h1c->obuf) && (flags & NEGO_FF_FL_MAY_SPLICE)) {
+ int can_splice = XPRT_CONN_CAN_NOT_SPLICE;
#if defined(USE_LINUX_SPLICE)
- if (h1c->conn->xprt->snd_pipe && (h1s->sd->iobuf.pipe || (pipes_used < global.maxpipes && (h1s->sd->iobuf.pipe = get_pipe())))) {
+
+ if (h1c->conn->xprt->snd_pipe &&
+ h1c->conn->xprt->get_capability &&
+ h1c->conn->xprt->get_capability(h1c->conn, h1c->conn->xprt_ctx, XPRT_CAN_SPLICE, &can_splice) == 0 &&
+ can_splice == XPRT_CONN_CAN_SPLICE &&
+ (h1s->sd->iobuf.pipe || (pipes_used < global.maxpipes && (h1s->sd->iobuf.pipe = get_pipe())))) {
h1s->sd->iobuf.offset = 0;
h1s->sd->iobuf.data = 0;
ret = count;
goto out;
}
#endif
- h1s->sd->iobuf.flags |= IOBUF_FL_NO_SPLICING;
- TRACE_DEVEL("Unable to allocate pipe for splicing, fallback to buffer", H1_EV_STRM_SEND, h1c->conn, h1s);
+ /*
+ * If can_splice is XPRT_CONN_COULD_SPLICE, it means
+ * that it can not splice right now, but it may at a later
+ * time, so don't disable it completely, just do not attempt
+ * to splice right now. If we got that, then no pipe has
+ * been allowed, so we should not try to splice.
+ * Set CO_FL_WANT_SPLICING to let the upper layers know that
+ * we would love to be able to use splicing if possible.
+ */
+ if (can_splice == XPRT_CONN_COULD_SPLICE) {
+ h1c->conn->flags |= CO_FL_WANT_SPLICING;
+ } else {
+ h1s->sd->iobuf.flags |= IOBUF_FL_NO_SPLICING;
+ TRACE_DEVEL("Unable to allocate pipe for splicing, fallback to buffer", H1_EV_STRM_SEND, h1c->conn, h1s);
+ }
}
no_splicing:
count = h1m->curr_len;
}
- if (h1c->conn->xprt->rcv_pipe && !!(flags & CO_RFL_MAY_SPLICE) && !(sdo->iobuf.flags & IOBUF_FL_NO_SPLICING))
- nego_flags |= NEGO_FF_FL_MAY_SPLICE;
+ if (h1c->conn->xprt->rcv_pipe && !!(flags & CO_RFL_MAY_SPLICE) && !(sdo->iobuf.flags & IOBUF_FL_NO_SPLICING)) {
+ int can_splice = XPRT_CONN_CAN_NOT_SPLICE;
+
+ if (h1c->conn->xprt->get_capability &&
+ h1c->conn->xprt->get_capability(h1c->conn, h1c->conn->xprt_ctx, XPRT_CAN_SPLICE, &can_splice) == 0 &&
+ can_splice == XPRT_CONN_CAN_SPLICE)
+ nego_flags |= NEGO_FF_FL_MAY_SPLICE;
+ else if (can_splice == XPRT_CONN_COULD_SPLICE)
+ h1c->conn->flags |= CO_FL_WANT_SPLICING;
+ }
try = se_nego_ff(sdo, &h1c->ibuf, count, nego_flags);
if (b_room(&h1c->ibuf) && (h1c->flags & H1C_F_IN_FULL)) {
* supported to mix data.
*/
if (!b_data(input) && (flags & NEGO_FF_FL_MAY_SPLICE)) {
- if (conn->xprt->snd_pipe && (ctx->sd->iobuf.pipe || (pipes_used < global.maxpipes && (ctx->sd->iobuf.pipe = get_pipe())))) {
+ int can_splice = XPRT_CONN_CAN_NOT_SPLICE;
+
+ if (conn->xprt->snd_pipe && conn->xprt->get_capability &&
+ conn->xprt->get_capability(conn, conn->xprt_ctx, XPRT_CAN_SPLICE, &can_splice) == 0 &&
+ can_splice == XPRT_CONN_CAN_SPLICE &&
+ (ctx->sd->iobuf.pipe || (pipes_used < global.maxpipes && (ctx->sd->iobuf.pipe = get_pipe())))) {
ctx->sd->iobuf.offset = 0;
ctx->sd->iobuf.data = 0;
ret = count;
goto out;
}
- ctx->sd->iobuf.flags |= IOBUF_FL_NO_SPLICING;
- TRACE_DEVEL("Unable to allocate pipe for splicing, fallback to buffer", PT_EV_TX_DATA, conn, sc);
+ /*
+ * If can_splice is XPRT_CONN_COULD, it means
+ * that it can not splice right now, but it may at a later
+ * time, so don't disable it completely, just do not attempt
+ * to splice right now. If we got that, then no pipe has
+ * been allowed, so we should not try to splice.
+ * Set CO_FL_WANT_SPLICING to let the upper layers know that
+ * we would love to be able to use splicing if possible.
+ */
+ if (can_splice == XPRT_CONN_COULD_SPLICE) {
+ conn->flags |= CO_FL_WANT_SPLICING;
+ } else {
+ ctx->sd->iobuf.flags |= IOBUF_FL_NO_SPLICING;
+ TRACE_DEVEL("Unable to allocate pipe for splicing, fallback to buffer", PT_EV_TX_DATA, conn, sc);
+ }
}
-
/* No buffer case */
out:
goto out;
}
- if (conn->xprt->rcv_pipe && !!(flags & CO_RFL_MAY_SPLICE) && !(sdo->iobuf.flags & IOBUF_FL_NO_SPLICING))
- nego_flags |= NEGO_FF_FL_MAY_SPLICE;
+ if (conn->xprt->rcv_pipe && !!(flags & CO_RFL_MAY_SPLICE) && !(sdo->iobuf.flags & IOBUF_FL_NO_SPLICING)) {
+ int can_splice = XPRT_CONN_CAN_NOT_SPLICE;
+
+ if (conn->xprt->get_capability &&
+ conn->xprt->get_capability(conn, conn->xprt_ctx, XPRT_CAN_SPLICE, &can_splice) == 0 &&
+ can_splice == XPRT_CONN_CAN_SPLICE)
+ nego_flags |= NEGO_FF_FL_MAY_SPLICE;
+ else if (can_splice == XPRT_CONN_COULD_SPLICE)
+ conn->flags |= CO_FL_WANT_SPLICING;
+ }
+
try = se_nego_ff(sdo, &BUF_NULL, count, nego_flags);
if (sdo->iobuf.flags & IOBUF_FL_NO_FF) {