http: fix http session deschedule 21/42821/4
authorMatus Fabian <[email protected]>
Tue, 15 Apr 2025 15:02:45 +0000 (11:02 -0400)
committerFlorin Coras <[email protected]>
Wed, 16 Apr 2025 19:29:35 +0000 (19:29 +0000)
Type: fix

Change-Id: Ieda622ff48422e8f4707c8b624f14d93324e615d
Signed-off-by: Matus Fabian <[email protected]>
src/plugins/http/http1.c
src/plugins/http/http2/http2.c
src/plugins/http/http_private.h

index d99e4bd..fbd0d32 100644 (file)
@@ -125,6 +125,19 @@ http1_conn_free_req (http_conn_t *hc)
   hc->flags &= ~HTTP_CONN_F_HAS_REQUEST;
 }
 
+/* Deschedule http session and wait for deq notification if underlying ts tx
+ * fifo almost full */
+static_always_inline void
+http1_check_and_deschedule (http_conn_t *hc, http_req_t *req,
+                           transport_send_params_t *sp)
+{
+  if (http_io_ts_check_write_thresh (hc))
+    {
+      http_req_deschedule (req, sp);
+      http_io_ts_add_want_deq_ntf (hc);
+    }
+}
+
 static void
 http1_send_error (http_conn_t *hc, http_status_code_t ec,
                  transport_send_params_t *sp)
@@ -139,7 +152,7 @@ http1_send_error (http_conn_t *hc, http_status_code_t ec,
   HTTP_DBG (3, "%v", data);
   http_io_ts_write (hc, data, vec_len (data), sp);
   vec_free (data);
-  http_io_ts_after_write (hc, sp, 0, 1);
+  http_io_ts_after_write (hc, 0);
 }
 
 static int
@@ -1039,7 +1052,7 @@ http1_req_state_transport_io_more_data (http_conn_t *hc, http_req_t *req,
   if (max_enq == 0)
     {
       HTTP_DBG (1, "app's rx fifo full");
-      http_io_as_want_deq_ntf (req);
+      http_io_as_add_want_deq_ntf (req);
       return HTTP_SM_STOP;
     }
 
@@ -1095,7 +1108,7 @@ http1_req_state_tunnel_rx (http_conn_t *hc, http_req_t *req,
   if (max_enq == 0)
     {
       HTTP_DBG (1, "app's rx fifo full");
-      http_io_as_want_deq_ntf (req);
+      http_io_as_add_want_deq_ntf (req);
       return HTTP_SM_STOP;
     }
   max_read = clib_min (max_enq, max_deq);
@@ -1187,7 +1200,7 @@ http1_req_state_udp_tunnel_rx (http_conn_t *hc, http_req_t *req,
       if (http_io_as_max_write (req) < dgram_size)
        {
          HTTP_DBG (1, "app's rx fifo full");
-         http_io_as_want_deq_ntf (req);
+         http_io_as_add_want_deq_ntf (req);
          goto done;
        }
 
@@ -1328,7 +1341,7 @@ http1_req_state_wait_app_reply (http_conn_t *hc, http_req_t *req,
 
   http_req_state_change (req, next_state);
 
-  http_io_ts_after_write (hc, sp, 0, 1);
+  http_io_ts_after_write (hc, 0);
   return sm_result;
 
 error:
@@ -1445,7 +1458,7 @@ http1_req_state_wait_app_method (http_conn_t *hc, http_req_t *req,
 
   http_req_state_change (req, next_state);
 
-  http_io_ts_after_write (hc, sp, 0, 1);
+  http_io_ts_after_write (hc, 0);
   goto done;
 
 error:
@@ -1497,9 +1510,10 @@ http1_req_state_app_io_more_data (http_conn_t *hc, http_req_t *req,
                                    HTTP_REQ_STATE_WAIT_TRANSPORT_REPLY);
       http_buffer_free (hb);
     }
+  http_io_ts_after_write (hc, finished);
 
 check_fifo:
-  http_io_ts_after_write (hc, sp, finished, !!n_written);
+  http1_check_and_deschedule (hc, req, sp);
   return HTTP_SM_STOP;
 }
 
@@ -1529,10 +1543,10 @@ http1_req_state_tunnel_tx (http_conn_t *hc, http_req_t *req,
   http_io_as_read_segs (req, segs, &n_segs, max_read);
   n_written = http_io_ts_write_segs (hc, segs, n_segs, sp);
   http_io_as_drain (req, n_written);
+  http_io_ts_after_write (hc, 0);
 
 check_fifo:
-  http_io_ts_after_write (hc, sp, 0, !!n_written);
-
+  http1_check_and_deschedule (hc, req, sp);
   return HTTP_SM_STOP;
 }
 
@@ -1580,8 +1594,9 @@ http1_req_state_udp_tunnel_tx (http_conn_t *hc, http_req_t *req,
     }
 
 done:
-  http_io_ts_after_write (hc, sp, 0, written);
-
+  if (written)
+    http_io_ts_after_write (hc, 0);
+  http1_check_and_deschedule (hc, req, sp);
   return HTTP_SM_STOP;
 }
 
index bbfa25a..a447dc4 100644 (file)
@@ -224,7 +224,7 @@ http2_connection_error (http_conn_t *hc, http2_error_t error,
   response = http_get_tx_buf (hc);
   http2_frame_write_goaway (error, h2c->last_processed_stream_id, &response);
   http_io_ts_write (hc, response, vec_len (response), sp);
-  http_io_ts_after_write (hc, sp, 1, 1);
+  http_io_ts_after_write (hc, 1);
 
   hash_foreach (stream_id, req_index, h2c->req_by_stream_id, ({
                  req = http2_req_get (req_index, hc->c_thread_index);
@@ -243,7 +243,7 @@ http2_send_stream_error (http_conn_t *hc, u32 stream_id, http2_error_t error,
   response = http_get_tx_buf (hc);
   http2_frame_write_rst_stream (error, stream_id, &response);
   http_io_ts_write (hc, response, vec_len (response), sp);
-  http_io_ts_after_write (hc, sp, 1, 1);
+  http_io_ts_after_write (hc, 1);
 }
 
 /* send RST_STREAM frame and notify app */
@@ -301,7 +301,7 @@ http2_send_server_preface (http_conn_t *hc)
     response = http_get_tx_buf (hc);
   http2_frame_write_settings (settings_list, &response);
   http_io_ts_write (hc, response, vec_len (response), 0);
-  http_io_ts_after_write (hc, 0, 0, 1);
+  http_io_ts_after_write (hc, 0);
 }
 
 /*************************************/
@@ -523,7 +523,7 @@ http2_req_state_wait_app_reply (http_conn_t *hc, http2_req_t *req,
                             { response, vec_len (response) } };
   n_written = http_io_ts_write_segs (hc, segs, 2, sp);
   ASSERT (n_written == (HTTP2_FRAME_HEADER_SIZE + vec_len (response)));
-  http_io_ts_after_write (hc, sp, 0, 1);
+  http_io_ts_after_write (hc, 0);
 
   return sm_result;
 }
@@ -577,9 +577,14 @@ http2_req_state_app_io_more_data (http_conn_t *hc, http2_req_t *req,
       else
        req->stream_state = HTTP2_STREAM_STATE_HALF_CLOSED;
     }
+  http_io_ts_after_write (hc, finished);
 
 check_fifo:
-  http_io_ts_after_write (hc, sp, finished, !!n_written);
+  if (http_io_ts_check_write_thresh (hc))
+    {
+      http_io_ts_add_want_deq_ntf (hc);
+      http_req_deschedule (&req->base, sp);
+    }
   return HTTP_SM_STOP;
 }
 
@@ -842,7 +847,7 @@ http2_handle_settings_frame (http_conn_t *hc, http2_frame_header_t *fh)
       http2_frame_write_settings_ack (&resp);
       http_io_ts_write (hc, resp, vec_len (resp), 0);
       vec_free (resp);
-      http_io_ts_after_write (hc, 0, 0, 1);
+      http_io_ts_after_write (hc, 0);
     }
 
   return HTTP2_ERROR_NO_ERROR;
@@ -946,7 +951,7 @@ http2_handle_ping_frame (http_conn_t *hc, http2_frame_header_t *fh)
   http2_frame_write_ping (1, rx_buf, &resp);
   http_io_ts_write (hc, resp, vec_len (resp), 0);
   vec_free (resp);
-  http_io_ts_after_write (hc, 0, 1, 1);
+  http_io_ts_after_write (hc, 1);
 
   return HTTP2_ERROR_NO_ERROR;
 }
index c20694c..cee60a4 100644 (file)
@@ -540,10 +540,17 @@ http_parse_content_length (http_req_t *req, u8 *rx_buf)
   return 0;
 }
 
+always_inline void
+http_req_deschedule (http_req_t *req, transport_send_params_t *sp)
+{
+  transport_connection_deschedule (&req->connection);
+  sp->flags |= TRANSPORT_SND_F_DESCHED;
+}
+
 /* Abstraction of app session fifo operations */
 
 always_inline void
-http_io_as_want_deq_ntf (http_req_t *req)
+http_io_as_add_want_deq_ntf (http_req_t *req)
 {
   session_t *as = session_get_from_handle (req->hr_pa_session_handle);
   svm_fifo_add_want_deq_ntf (as->rx_fifo, SVM_FIFO_WANT_DEQ_NOTIF);
@@ -656,6 +663,20 @@ http_io_ts_max_write (http_conn_t *hc, transport_send_params_t *sp)
                   sp->max_burst_size);
 }
 
+always_inline int
+http_io_ts_check_write_thresh (http_conn_t *hc)
+{
+  session_t *ts = session_get_from_handle (hc->hc_tc_session_handle);
+  return (svm_fifo_max_enqueue_prod (ts->tx_fifo) < HTTP_FIFO_THRESH);
+}
+
+always_inline void
+http_io_ts_add_want_deq_ntf (http_conn_t *hc)
+{
+  session_t *ts = session_get_from_handle (hc->hc_tc_session_handle);
+  svm_fifo_add_want_deq_ntf (ts->tx_fifo, SVM_FIFO_WANT_DEQ_NOTIF);
+}
+
 always_inline u32
 http_io_ts_read (http_conn_t *hc, u8 *buf, u32 len, u8 peek)
 {
@@ -745,28 +766,18 @@ http_io_ts_write_segs (http_conn_t *hc, const svm_fifo_seg_t segs[],
 }
 
 always_inline void
-http_io_ts_after_write (http_conn_t *hc, transport_send_params_t *sp, u8 flush,
-                       u8 written)
+http_io_ts_after_write (http_conn_t *hc, u8 flush)
 {
   session_t *ts = session_get_from_handle (hc->hc_tc_session_handle);
 
   if (!flush)
     {
-      if (written && svm_fifo_set_event (ts->tx_fifo))
+      if (svm_fifo_set_event (ts->tx_fifo))
        session_program_tx_io_evt (ts->handle, SESSION_IO_EVT_TX);
-
-      if (sp && (svm_fifo_max_enqueue (ts->tx_fifo) < HTTP_FIFO_THRESH))
-       {
-         /* Deschedule http session and wait for deq notification if
-          * underlying ts tx fifo almost full */
-         svm_fifo_add_want_deq_ntf (ts->tx_fifo, SVM_FIFO_WANT_DEQ_NOTIF);
-         transport_connection_deschedule (&hc->connection);
-         sp->flags |= TRANSPORT_SND_F_DESCHED;
-       }
     }
   else
     {
-      if (written && svm_fifo_set_event (ts->tx_fifo))
+      if (svm_fifo_set_event (ts->tx_fifo))
        session_program_tx_io_evt (ts->handle, SESSION_IO_EVT_TX_FLUSH);
     }
 }