aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMichal Kalderon <mkalderon@marvell.com>2021-11-24 01:33:15 -0800
committerFlorin Coras <florin.coras@gmail.com>2021-12-29 22:48:40 +0000
commitfe2231f01fb56af21d6b4d6f63d7e1a2c4d14848 (patch)
tree0d3fc1359f471b0ec6e455787ee9808790529f1d /src
parentfb079585cf6367eea279613bd7b9b810ab418edd (diff)
http_static: Fix timeout on large files
When trying to read files that are larger than the fifo a timeout was reached on client side leading to an abort of the request and a retry (sending another GET command). The svm fifo notification request was set to notify when the fifo is no longer full, this lead to an inefficient loop of sending small amounts of data each time with a large overhead of context switch and waiting for the next notification, eventually leading to a timeout. Modifying the trigger on the svm-fifo to be notified on a preset threshold value enabled sending larger amounts of data between context switches and sending large files more efficiently. This solved the timeout issue. In addition, cap the max write from application to 4MB to avoid running into a case of trying to allocate chunks that are too large. Reproduce: Server: http static server www-root /var/www/data uri tcp://0.0.0.0/80 cache-size 5m fifo-size 300 Client: wget http://11.0.0.2/file_of_size_32M Type: fix Change-Id: Idfceedffd935da9486cde820e9dca5dad69d9ca5 Signed-off-by: Yuval Caduri <cyuval@marvell.com> Signed-off-by: Michal Kalderon <mkalderon@marvell.com>
Diffstat (limited to 'src')
-rw-r--r--src/plugins/http_static/static_server.c22
1 files changed, 19 insertions, 3 deletions
diff --git a/src/plugins/http_static/static_server.c b/src/plugins/http_static/static_server.c
index c715dfa6fb8..ba81882fca0 100644
--- a/src/plugins/http_static/static_server.c
+++ b/src/plugins/http_static/static_server.c
@@ -299,8 +299,8 @@ static_send_data (http_session_t * hs, u8 * data, u32 length, u32 offset)
{
int actual_transfer;
- actual_transfer = svm_fifo_enqueue
- (hs->tx_fifo, bytes_to_send, data + offset);
+ actual_transfer = svm_fifo_enqueue (
+ hs->tx_fifo, clib_min (bytes_to_send, 4 << 20), data + offset);
/* Made any progress? */
if (actual_transfer <= 0)
@@ -893,7 +893,7 @@ state_send_more_data (session_t * s, http_session_t * hs,
{
/* No: ask for a shoulder-tap when the tx fifo has space */
svm_fifo_add_want_deq_ntf (hs->tx_fifo,
- SVM_FIFO_WANT_DEQ_NOTIF_IF_FULL);
+ SVM_FIFO_WANT_DEQ_NOTIF_IF_LEQ_THRESH);
hs->session_state = HTTP_STATE_SEND_MORE_DATA;
return 0;
}
@@ -1033,6 +1033,7 @@ http_static_server_session_accept_callback (session_t * s)
{
http_static_server_main_t *hsm = &http_static_server_main;
http_session_t *hs;
+ u32 thresh;
hsm->vpp_queue[s->thread_index] =
session_main_get_vpp_event_queue (s->thread_index);
@@ -1051,6 +1052,21 @@ http_static_server_session_accept_callback (session_t * s)
http_static_server_sessions_writer_unlock ();
+ /* The application sets a threshold for it's fifo to get notified when
+ * additional data can be enqueued. We want to keep the TX fifo reasonably
+ * full, however avoid entering a state where the
+ * fifo is full all the time and small chunks of data are being enqueued
+ * each time. If the fifo is small (under 16K) we set
+ * the threshold to 0, meaning a notification will be given when the
+ * fifo empties.
+ */
+#define HTTP_FIFO_THRESH (16 << 10)
+ thresh = (svm_fifo_size (hs->tx_fifo) < HTTP_FIFO_THRESH) ?
+ 0 :
+ svm_fifo_size (hs->tx_fifo) - HTTP_FIFO_THRESH;
+
+ svm_fifo_set_deq_thresh (hs->tx_fifo, thresh);
+
s->session_state = SESSION_STATE_READY;
return 0;
}