]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: tree-wide: Change sc API to specify required free space to progress
authorChristopher Faulet <cfaulet@haproxy.com>
Fri, 5 May 2023 09:28:45 +0000 (11:28 +0200)
committerChristopher Faulet <cfaulet@haproxy.com>
Fri, 5 May 2023 13:44:23 +0000 (15:44 +0200)
sc_need_room() now takes the required free space to receive more data as
parameter. All calls to this function are updated accordingly. For now, this
value is set but not used. When we are waiting for a buffer, 0 is used. So
we expect to be unblocked ASAP. However this must be reviewed because
SC_FL_NEED_BUF is probably enough in this case and this flag is already set
if the input buffer allocation fails.

14 files changed:
addons/promex/service-prometheus.c
include/haproxy/applet.h
include/haproxy/stconn.h
src/cache.c
src/cli.c
src/dns.c
src/flt_spoe.c
src/hlua.c
src/http_client.c
src/peers.c
src/proxy.c
src/resolvers.c
src/stats.c
src/stconn.c

index d03399c086924187dccae7edeebe38aa971aa73d..e02e8c0c78e432ee07d520a1c63c24d96b81e86f 100644 (file)
@@ -1365,7 +1365,7 @@ static int promex_dump_metrics(struct appctx *appctx, struct stconn *sc, struct
        return 1;
 
   full:
-       sc_need_room(sc);
+       sc_need_room(sc, channel_htx_recv_max(sc_ic(appctx_sc(appctx)), htx) + 1);
        return 0;
   error:
        /* unrecoverable error */
@@ -1512,7 +1512,7 @@ static int promex_send_headers(struct appctx *appctx, struct stconn *sc, struct
        return 1;
   full:
        htx_reset(htx);
-       sc_need_room(sc);
+       sc_need_room(sc, 0);
        return 0;
 }
 
@@ -1544,7 +1544,7 @@ static void promex_appctx_handle_io(struct appctx *appctx)
 
        /* Check if the input buffer is available. */
        if (!b_size(&res->buf)) {
-               sc_need_room(sc);
+               sc_need_room(sc, 0);
                goto out;
        }
 
@@ -1585,7 +1585,7 @@ static void promex_appctx_handle_io(struct appctx *appctx)
                         */
                        if (htx_is_empty(res_htx)) {
                                if (!htx_add_endof(res_htx, HTX_BLK_EOT)) {
-                                       sc_need_room(sc);
+                                       sc_need_room(sc, sizeof(struct htx_blk) + 1);
                                        goto out;
                                }
                                channel_add_input(res, 1);
index b805440e6b8a156b096d8f93dca7b4b205e54bf9..62df5c833c48f23a72e5b8162cd90c1fd682a1fe 100644 (file)
@@ -178,7 +178,7 @@ static inline int applet_putchk(struct appctx *appctx, struct buffer *chunk)
 
        ret = ci_putchk(sc_ic(se->sc), chunk);
        if (ret == -1)
-               sc_need_room(se->sc);
+               sc_need_room(se->sc, chunk->data);
 
        return ret;
 }
@@ -194,7 +194,7 @@ static inline int applet_putblk(struct appctx *appctx, const char *blk, int len)
 
        ret = ci_putblk(sc_ic(se->sc), blk, len);
        if (ret == -1)
-               sc_need_room(se->sc);
+               sc_need_room(se->sc, len);
 
        return ret;
 }
@@ -211,7 +211,7 @@ static inline int applet_putstr(struct appctx *appctx, const char *str)
 
        ret = ci_putstr(sc_ic(se->sc), str);
        if (ret == -1)
-               sc_need_room(se->sc);
+               sc_need_room(se->sc, strlen(str));
 
        return ret;
 }
@@ -227,7 +227,7 @@ static inline int applet_putchr(struct appctx *appctx, char chr)
 
        ret = ci_putchr(sc_ic(se->sc), chr);
        if (ret == -1)
-               sc_need_room(se->sc);
+               sc_need_room(se->sc, 1);
 
        return ret;
 }
index 5ee73d0f2f0828e0d11b291f534bed9b45135333..acc22977b9295cb9b69a1e32e80095a08d6d0e04 100644 (file)
@@ -433,6 +433,7 @@ static inline void sc_have_room(struct stconn *sc)
 {
        if (sc->flags & SC_FL_NEED_ROOM) {
                sc->flags &= ~SC_FL_NEED_ROOM;
+               sc->room_needed = 0;
                sc_ep_report_read_activity(sc);
        }
 }
@@ -441,10 +442,14 @@ static inline void sc_have_room(struct stconn *sc)
  * by lack of room. Since it indicates a willingness to deliver data to the
  * buffer that will have to be retried. Usually the caller will also clear
  * SE_FL_HAVE_NO_DATA to be called again as soon as SC_FL_NEED_ROOM is cleared.
+ *
+ * The caller is responsible to specified the amount of free space required to
+ * progress.
  */
-static inline void sc_need_room(struct stconn *sc)
+static inline void sc_need_room(struct stconn *sc, ssize_t room_needed)
 {
        sc->flags |= SC_FL_NEED_ROOM;
+       sc->room_needed = room_needed;
 }
 
 /* The stream endpoint indicates that it's ready to consume data from the
index 4deb34ea88e17361fbb9e90c2efe2fbd99cc57d3..cebd17e3de25bfa62eab11acbe17c33aac5add03 100644 (file)
@@ -1471,7 +1471,7 @@ static void http_cache_io_handler(struct appctx *appctx)
 
        /* Check if the input buffer is available. */
        if (!b_size(&res->buf)) {
-               sc_need_room(sc);
+               sc_need_room(sc, 0);
                goto out;
        }
 
@@ -1513,7 +1513,7 @@ static void http_cache_io_handler(struct appctx *appctx)
                if (len) {
                        ret = htx_cache_dump_msg(appctx, res_htx, len, HTX_BLK_UNUSED);
                        if (ret < len) {
-                               sc_need_room(sc);
+                               sc_need_room(sc, len - ret);
                                goto out;
                        }
                }
index c26840a46996534630dd6319d5fbcef5f16eb167..977e228695de5ee422a7422ecfbe0a3bafaf6ec3 100644 (file)
--- a/src/cli.c
+++ b/src/cli.c
@@ -900,7 +900,7 @@ static void cli_io_handler(struct appctx *appctx)
 
        /* Check if the input buffer is available. */
        if (!b_size(&res->buf)) {
-               sc_need_room(sc);
+               sc_need_room(sc, 0);
                goto out;
        }
 
@@ -937,7 +937,7 @@ static void cli_io_handler(struct appctx *appctx)
                         * would want to return some info right after parsing.
                         */
                        if (buffer_almost_full(sc_ib(sc))) {
-                               sc_need_room(sc);
+                               sc_need_room(sc, b_size(&res->buf) / 2);
                                break;
                        }
 
index e5ddee71f6e910e4e45a3b2729aa697ef1f7a821..23e9d9de538b00b816e06349ab46d2472f2ca1dd 100644 (file)
--- a/src/dns.c
+++ b/src/dns.c
@@ -525,7 +525,7 @@ static void dns_session_io_handler(struct appctx *appctx)
 
                        /* check if there is enough room to put message len and query id */
                        if (available_room < sizeof(slen) + sizeof(new_qid)) {
-                               sc_need_room(sc);
+                               sc_need_room(sc, sizeof(slen) + sizeof(new_qid));
                                ret = 0;
                                break;
                        }
@@ -583,7 +583,7 @@ static void dns_session_io_handler(struct appctx *appctx)
 
                /* check if it remains available room on output chan */
                if (unlikely(!available_room)) {
-                       sc_need_room(sc);
+                       sc_need_room(sc, 1);
                        ret = 0;
                        break;
                }
@@ -617,8 +617,7 @@ static void dns_session_io_handler(struct appctx *appctx)
 
                if (ds->tx_msg_offset) {
                        /* msg was not fully processed, we must  be awake to drain pending data */
-
-                       sc_need_room(sc);
+                       sc_need_room(sc, 0);
                        ret = 0;
                        break;
                }
index ba35f01f9d2552dde63d7a66b829833a716e5570..6ab1cfb3ebbbac1fee2a1348b5e7faf293b7d46c 100644 (file)
@@ -1147,9 +1147,9 @@ spoe_send_frame(struct appctx *appctx, char *buf, size_t framesz)
        memcpy(buf, (char *)&netint, 4);
        ret = applet_putblk(appctx, buf, framesz+4);
        if (ret <= 0) {
-               if ((ret == -3 && b_is_null(&sc_ic(sc)->buf)) || ret == -1) {
+               if (ret == -3 && b_is_null(&sc_ic(sc)->buf)) {
                        /* WT: is this still needed for the case ret==-3 ? */
-                       sc_need_room(sc);
+                       sc_need_room(sc, 0);
                        return 1; /* retry */
                }
                SPOE_APPCTX(appctx)->status_code = SPOE_FRM_ERR_IO;
index 8eb8e32df4949c3dd04054109ec691597e17a9d0..973e277264885ebe09c209428a054b19a8218772 100644 (file)
@@ -4929,7 +4929,7 @@ __LJMP static int hlua_applet_tcp_send_yield(lua_State *L, int status, lua_KCont
         * applet, and returns a yield.
         */
        if (l < len) {
-               sc_need_room(sc);
+               sc_need_room(sc, channel_recv_max(chn) + 1);
                MAY_LJMP(hlua_yieldk(L, 0, 0, hlua_applet_tcp_send_yield, TICK_ETERNITY, 0));
        }
 
@@ -5472,7 +5472,7 @@ __LJMP static int hlua_applet_http_send_yield(lua_State *L, int status, lua_KCon
        if (l < len) {
          snd_yield:
                htx_to_buf(htx, &res->buf);
-               sc_need_room(sc);
+               sc_need_room(sc, channel_recv_max(res) + 1);
                MAY_LJMP(hlua_yieldk(L, 0, 0, hlua_applet_http_send_yield, TICK_ETERNITY, 0));
        }
 
@@ -5776,7 +5776,7 @@ __LJMP static int hlua_applet_http_start_response_yield(lua_State *L, int status
        struct channel *res = sc_ic(sc);
 
        if (co_data(res)) {
-               sc_need_room(sc);
+               sc_need_room(sc, -1);
                MAY_LJMP(hlua_yieldk(L, 0, 0, hlua_applet_http_start_response_yield, TICK_ETERNITY, 0));
        }
        return MAY_LJMP(hlua_applet_http_send_response(L));
@@ -10390,7 +10390,7 @@ void hlua_applet_http_fct(struct appctx *ctx)
 
        /* Check if the input buffer is available. */
        if (!b_size(&res->buf)) {
-               sc_need_room(sc);
+               sc_need_room(sc, 0);
                goto out;
        }
 
@@ -10463,7 +10463,7 @@ void hlua_applet_http_fct(struct appctx *ctx)
                 */
                if (htx_is_empty(res_htx) && (strm->txn->rsp.flags & (HTTP_MSGF_XFER_LEN|HTTP_MSGF_CNT_LEN)) == HTTP_MSGF_XFER_LEN) {
                        if (!htx_add_endof(res_htx, HTX_BLK_EOT)) {
-                               sc_need_room(sc);
+                               sc_need_room(sc, sizeof(struct htx_blk)+1);
                                goto out;
                        }
                        channel_add_input(res, 1);
@@ -11029,7 +11029,7 @@ static int hlua_cli_io_handler_fct(struct appctx *appctx)
        case HLUA_E_AGAIN:
                /* We want write. */
                if (HLUA_IS_WAKERESWR(hlua))
-                       sc_need_room(sc);
+                       sc_need_room(sc, -1);
                /* Set the timeout. */
                if (hlua->wake_time != TICK_ETERNITY)
                        task_schedule(hlua->task, hlua->wake_time);
index c2dec8bbe8045f32cad010d8cf7a100d57da5ed0..af30c8e58e80629d54929762ed78477c10561725 100644 (file)
@@ -726,15 +726,19 @@ static void httpclient_applet_io_handler(struct appctx *appctx)
                                 * it's the first call, we can freely copy the
                                 * request from the httpclient buffer */
                                ret = b_xfer(&req->buf, &hc->req.buf, b_data(&hc->req.buf));
-                               if (!ret)
-                                       goto full;
+                               if (!ret) {
+                                       sc_need_room(sc, 0);
+                                       goto out;
+                               }
 
                                if (!b_data(&hc->req.buf))
                                        b_free(&hc->req.buf);
 
                                htx = htx_from_buf(&req->buf);
-                               if (!htx)
-                                       goto full;
+                               if (!htx) {
+                                       sc_need_room(sc, 0);
+                                       goto out;
+                               }
 
                                channel_add_input(req, htx->data);
 
@@ -983,11 +987,6 @@ process_data:
        sc_will_read(sc);
        goto out;
 
-full:
-       /* There was not enough room in the response channel */
-       sc_need_room(sc);
-       goto out;
-
 error:
        se_fl_set(appctx->sedesc, SE_FL_ERROR);
        goto out;
index 503a71fcca57c6e3191ae9f01ed49f88624ff1f1..1bbc1ca056525306f982bb5dae6b3d4b14a71aea 100644 (file)
@@ -1623,7 +1623,7 @@ static inline int peer_send_teachmsgs(struct appctx *appctx, struct peer *p,
                        /* pretend we're full so that we get back ASAP */
                        struct stconn *sc = appctx_sc(appctx);
 
-                       sc_need_room(sc);
+                       sc_need_room(sc, 0);
                        ret = -1;
                        break;
                }
@@ -2652,7 +2652,7 @@ static inline int peer_send_msgs(struct appctx *appctx,
                                /* pretend we're full so that we get back ASAP */
                                struct stconn *sc = appctx_sc(appctx);
 
-                               sc_need_room(sc);
+                               sc_need_room(sc, 0);
                                return -1;
                        }
                }
@@ -2925,7 +2925,7 @@ static void peer_io_handler(struct appctx *appctx)
 
        /* Check if the input buffer is available. */
        if (sc_ib(sc)->size == 0) {
-               sc_need_room(sc);
+               sc_need_room(sc, 0);
                goto out;
        }
 
index 55e9f2037eeebf8b10fb325d7c5a920b967b0a82..2b79dea4753653bcdc9dbcaf03271740d1db06d7 100644 (file)
@@ -3386,8 +3386,10 @@ static int cli_io_handler_show_errors(struct appctx *appctx)
 
                        newline = ctx->bol;
                        newptr = dump_text_line(&trash, es->buf, global.tune.bufsize, es->buf_len, &newline, ctx->ptr);
-                       if (newptr == ctx->ptr)
+                       if (newptr == ctx->ptr) {
+                               sc_need_room(sc, 0);
                                goto cant_send_unlock;
+                       }
 
                        if (applet_putchk(appctx, &trash) == -1)
                                goto cant_send_unlock;
@@ -3410,7 +3412,6 @@ static int cli_io_handler_show_errors(struct appctx *appctx)
  cant_send_unlock:
        HA_RWLOCK_RDUNLOCK(PROXY_LOCK, &ctx->px->lock);
  cant_send:
-       sc_need_room(sc);
        return 0;
 }
 
index 4a9209ebbff82cd91bda9e007b1d9d380966ce94..add9a25ab631a518dbfbeeccb6d7317c152de2bd 100644 (file)
@@ -2722,8 +2722,10 @@ int stats_dump_resolvers(struct stconn *sc,
                list_for_each_entry_from(ns, &resolver->nameservers, list) {
                        ctx->obj2 = ns;
 
-                       if (buffer_almost_full(&rep->buf))
+                       if (buffer_almost_full(&rep->buf)) {
+                               sc_need_room(sc, b_size(&rep->buf) / 2);
                                goto full;
+                       }
 
                        if (!stats_dump_resolv_to_buffer(sc, ns,
                                                         stats, stats_count,
index 56f62d88412bd9972f8add11db98b1e3af963ec6..0f2e027c165556da5713d75e61b4d3e26c4da0b4 100644 (file)
@@ -3853,12 +3853,16 @@ static int stats_dump_proxies(struct stconn *sc,
        /* dump proxies */
        while (ctx->obj1) {
                if (htx) {
-                       if (htx_almost_full(htx))
+                       if (htx_almost_full(htx)) {
+                               sc_need_room(sc, htx->size / 2);
                                goto full;
+                       }
                }
                else {
-                       if (buffer_almost_full(&rep->buf))
+                       if (buffer_almost_full(&rep->buf)) {
+                               sc_need_room(sc, b_size(&rep->buf) / 2);
                                goto full;
+                       }
                }
 
                px = ctx->obj1;
@@ -3880,7 +3884,6 @@ static int stats_dump_proxies(struct stconn *sc,
        return 1;
 
   full:
-       sc_need_room(sc);
        return 0;
 }
 
@@ -4378,7 +4381,7 @@ static int stats_send_http_headers(struct stconn *sc, struct htx *htx)
 
   full:
        htx_reset(htx);
-       sc_need_room(sc);
+       sc_need_room(sc, 0);
        return 0;
 }
 
@@ -4438,7 +4441,7 @@ static int stats_send_http_redirect(struct stconn *sc, struct htx *htx)
 
 full:
        htx_reset(htx);
-       sc_need_room(sc);
+       sc_need_room(sc, 0);
        return 0;
 }
 
@@ -4469,7 +4472,7 @@ static void http_stats_io_handler(struct appctx *appctx)
 
        /* Check if the input buffer is available. */
        if (!b_size(&res->buf)) {
-               sc_need_room(sc);
+               sc_need_room(sc, 0);
                goto out;
        }
 
@@ -4513,7 +4516,7 @@ static void http_stats_io_handler(struct appctx *appctx)
                 */
                if (htx_is_empty(res_htx)) {
                        if (!htx_add_endof(res_htx, HTX_BLK_EOT)) {
-                               sc_need_room(sc);
+                               sc_need_room(sc, sizeof(struct htx_blk) + 1);
                                goto out;
                        }
                        channel_add_input(res, 1);
index cb3d750a8a79ffec02311a2509234234e91adef5..615a97cc6707cd4eb5943effb2caff48d20ab2ff 100644 (file)
@@ -609,7 +609,7 @@ static void sc_app_chk_rcv(struct stconn *sc)
 
        if (ic->pipe) {
                /* stop reading */
-               sc_need_room(sc);
+               sc_need_room(sc, -1);
        }
        else {
                /* (re)start reading */
@@ -1269,7 +1269,7 @@ static int sc_conn_recv(struct stconn *sc)
                        /* 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);
+                       sc_need_room(sc, 0);
                        goto done_recv;
                }
 
@@ -1339,7 +1339,7 @@ static int sc_conn_recv(struct stconn *sc)
                         */
                        BUG_ON(c_empty(ic));
 
-                       sc_need_room(sc);
+                       sc_need_room(sc, channel_recv_max(ic) + 1);
                        /* Add READ_PARTIAL because some data are pending but
                         * cannot be xferred to the channel
                         */
@@ -1353,7 +1353,7 @@ static int sc_conn_recv(struct stconn *sc)
                         * here to proceed.
                         */
                        if (flags & CO_RFL_BUF_FLUSH)
-                               sc_need_room(sc);
+                               sc_need_room(sc, -1);
                        break;
                }