#define CF_STREAMER_FAST 0x00020000 /* the consumer seems to eat the stream very fast */
#define CF_WROTE_DATA 0x00040000 /* some data were sent from this buffer */
-/* unused 0x00080000 - 0x00100000 */
-#define CF_KERN_SPLICING 0x00200000 /* kernel splicing desired for this channel */
-/* unused 0x00400000 */
+/* unused 0x00080000 - 0x00400000 */
#define CF_AUTO_CONNECT 0x00800000 /* consumer may attempt to establish a new connection */
#define CF_DONT_READ 0x01000000 /* disable reading for now */
_(CF_WRITE_TIMEOUT,
_(CF_WAKE_WRITE, _(CF_AUTO_CLOSE,
_(CF_STREAMER, _(CF_STREAMER_FAST, _(CF_WROTE_DATA,
- _(CF_KERN_SPLICING,
_(CF_AUTO_CONNECT, _(CF_DONT_READ,
_(CF_WAKE_ONCE, _(CF_FLT_ANALYZE,
- _(CF_ISRESP)))))))))))))));
+ _(CF_ISRESP))))))))))))));
/* epilogue */
_(~0U);
return buf;
feature ignore_unknown_macro
#REGTEST_TYPE=slow
+#REGTEST_TYPE=broken
server s1 {
rxreq
feature ignore_unknown_macro
#REGTEST_TYPE=slow
+#REGTEST_TYPE=broken
server s1 {
rxreq
ic->flags &= ~(CF_STREAMER | CF_STREAMER_FAST);
}
- /* First, let's see if we may splice data across the channel without
- * using a buffer.
- */
- if (sc_ep_test(sc, SE_FL_MAY_FASTFWD) &&
- (sc_ep_have_ff_data(sc_opposite(sc)) || ic->to_forward >= MIN_SPLICE_FORWARD) &&
- ic->flags & CF_KERN_SPLICING) {
- if (c_data(ic)) {
- /* We're embarrassed, there are already data pending in
- * the buffer and we don't want to have them at two
- * locations at a time. Let's indicate we need some
- * place and ask the consumer to hurry.
- */
- flags |= CO_RFL_BUF_FLUSH;
- goto abort_splice;
- }
-
- if (unlikely(sc_opposite(sc)->sedesc->iobuf.pipe == NULL)) {
- if (pipes_used >= global.maxpipes || !(sc_opposite(sc)->sedesc->iobuf.pipe = get_pipe())) {
- ic->flags &= ~CF_KERN_SPLICING;
- goto abort_splice;
- }
- }
-
- ret = conn->mux->rcv_pipe(sc, sc_opposite(sc)->sedesc->iobuf.pipe, ic->to_forward);
- if (ret < 0) {
- /* splice not supported on this end, let's disable it */
- ic->flags &= ~CF_KERN_SPLICING;
- goto abort_splice;
- }
-
- if (ret > 0) {
- if (ic->to_forward != CHN_INFINITE_FORWARD)
- ic->to_forward -= ret;
- ic->total += ret;
- cur_read += ret;
- ic->flags |= CF_READ_EVENT;
- }
-
- if (sc_ep_test(sc, SE_FL_EOS | SE_FL_ERROR))
- goto end_recv;
-
- if (conn->flags & CO_FL_WAIT_ROOM) {
- /* the pipe is full or we have read enough data that it
- * could soon be full. Let's stop before needing to poll.
- */
- sc_need_room(sc, 0);
- goto done_recv;
- }
-
- /* splice not possible (anymore), let's go on on standard copy */
- }
-
- abort_splice:
- if (sc_ep_have_ff_data(sc_opposite(sc)) && unlikely(!sc_ep_ff_data(sc_opposite(sc)))) {
- put_pipe(sc_opposite(sc)->sedesc->iobuf.pipe);
- sc_opposite(sc)->sedesc->iobuf.pipe = NULL;
- }
-
if (sc_ep_have_ff_data(sc_opposite(sc)) && ic->to_forward &&
!(flags & CO_RFL_BUF_FLUSH) && sc_ep_test(sc, SE_FL_MAY_FASTFWD)) {
/* don't break splicing by reading, but still call rcv_buf()
if (!conn->mux)
return 0;
- if (sc_ep_have_ff_data(sc) && conn->xprt->snd_pipe && conn->mux->snd_pipe) {
- ret = conn->mux->snd_pipe(sc, sc->sedesc->iobuf.pipe);
- if (ret > 0)
- did_send = 1;
-
- if (!sc_ep_ff_data(sc)) {
- put_pipe(sc->sedesc->iobuf.pipe);
- sc->sedesc->iobuf.pipe = NULL;
- }
- else
- goto end;
- }
-
/* At this point, the pipe is empty, but we may still have data pending
* in the normal buffer.
*/
}
}
- /* check if it is wise to enable kernel splicing to forward request data */
- if (!(req->flags & CF_KERN_SPLICING) &&
- !(scf->flags & (SC_FL_EOS|SC_FL_ABRT_DONE)) &&
- req->to_forward &&
- (global.tune.options & GTUNE_USE_SPLICE) &&
- (sc_conn(scf) && __sc_conn(scf)->xprt && __sc_conn(scf)->xprt->rcv_pipe &&
- __sc_conn(scf)->mux && __sc_conn(scf)->mux->rcv_pipe) &&
- (sc_conn(scb) && __sc_conn(scb)->xprt && __sc_conn(scb)->xprt->snd_pipe &&
- __sc_conn(scb)->mux && __sc_conn(scb)->mux->snd_pipe) &&
- (pipes_used < global.maxpipes) &&
- (((sess->fe->options2|s->be->options2) & PR_O2_SPLIC_REQ) ||
- (((sess->fe->options2|s->be->options2) & PR_O2_SPLIC_AUT) &&
- (req->flags & CF_STREAMER_FAST)))) {
- req->flags |= CF_KERN_SPLICING;
- }
-
/* reflect what the L7 analysers have seen last */
rqf_last = req->flags;
scf_flags = (scf_flags & ~(SC_FL_EOS|SC_FL_ABRT_DONE|SC_FL_ABRT_WANTED)) | (scf->flags & (SC_FL_EOS|SC_FL_ABRT_DONE|SC_FL_ABRT_WANTED));
}
}
- /* check if it is wise to enable kernel splicing to forward response data */
- if (!(res->flags & CF_KERN_SPLICING) &&
- !(scb->flags & (SC_FL_EOS|SC_FL_ABRT_DONE)) &&
- res->to_forward &&
- (global.tune.options & GTUNE_USE_SPLICE) &&
- (sc_conn(scf) && __sc_conn(scf)->xprt && __sc_conn(scf)->xprt->snd_pipe &&
- __sc_conn(scf)->mux && __sc_conn(scf)->mux->snd_pipe) &&
- (sc_conn(scb) && __sc_conn(scb)->xprt && __sc_conn(scb)->xprt->rcv_pipe &&
- __sc_conn(scb)->mux && __sc_conn(scb)->mux->rcv_pipe) &&
- (pipes_used < global.maxpipes) &&
- (((sess->fe->options2|s->be->options2) & PR_O2_SPLIC_RTR) ||
- (((sess->fe->options2|s->be->options2) & PR_O2_SPLIC_AUT) &&
- (res->flags & CF_STREAMER_FAST)))) {
- res->flags |= CF_KERN_SPLICING;
- }
-
/* reflect what the L7 analysers have seen last */
rpf_last = res->flags;
scb_flags = (scb_flags & ~(SC_FL_EOS|SC_FL_ABRT_DONE|SC_FL_ABRT_WANTED)) | (scb->flags & (SC_FL_EOS|SC_FL_ABRT_DONE|SC_FL_ABRT_WANTED));