summaryrefslogtreecommitdiffstats
path: root/meta/recipes-extended/lighttpd/lighttpd/0001-core-reuse-large-mem-chunks-fix-mem-usage-fixes-3033.patch
diff options
context:
space:
mode:
authorPurushottam Choudhary <purushottamchoudhary29@gmail.com>2021-09-03 17:01:35 +0530
committerRichard Purdie <richard.purdie@linuxfoundation.org>2021-09-10 16:21:36 +0100
commit468ac59e9cc85581bc836df24dd6f9723ac315b8 (patch)
treeb6c1553c0d07f5828f4aa359266f6c370e5e39b7 /meta/recipes-extended/lighttpd/lighttpd/0001-core-reuse-large-mem-chunks-fix-mem-usage-fixes-3033.patch
parent2c00edba7fc55aaaec051d16736338e78abe9058 (diff)
downloadpoky-468ac59e9cc85581bc836df24dd6f9723ac315b8.tar.gz
lighttpd: Add patch for reuse large memory chunks
Added 0001-core-reuse-large-mem-chunks-fix-mem-usage-fixes-3033.patch to fix large memory usage for large file downloads from dynamic backends reuse or release large memory chunks. Also, added patch to set default chunk size 8k earlier it was 4k. This issue is caused by a bug in the lighttpd 1.4.55 version and has been fixed in lighttpd 1.4.58. Hence, it is not needed for master and hardknott branch because lighttpd has 1.4.59 version. Link: https://redmine.lighttpd.net/projects/lighttpd/repository/14/revisions/7ba521ffb4959f6f74a609d5d4acafc29a038337 Link: https://git.lighttpd.net/lighttpd/lighttpd1.4/commit/304e46d4f808c46cbb025edfacf2913a30ce8855 (From OE-Core rev: d3ac63230b98251d67a75a67456b769b6a002df0) Signed-off-by: Purushottam Choudhary <purushottamchoudhary29@gmail.com> Signed-off-by: Steve Sakoman <steve@sakoman.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'meta/recipes-extended/lighttpd/lighttpd/0001-core-reuse-large-mem-chunks-fix-mem-usage-fixes-3033.patch')
-rw-r--r--meta/recipes-extended/lighttpd/lighttpd/0001-core-reuse-large-mem-chunks-fix-mem-usage-fixes-3033.patch224
1 files changed, 224 insertions, 0 deletions
diff --git a/meta/recipes-extended/lighttpd/lighttpd/0001-core-reuse-large-mem-chunks-fix-mem-usage-fixes-3033.patch b/meta/recipes-extended/lighttpd/lighttpd/0001-core-reuse-large-mem-chunks-fix-mem-usage-fixes-3033.patch
new file mode 100644
index 0000000000..e226366112
--- /dev/null
+++ b/meta/recipes-extended/lighttpd/lighttpd/0001-core-reuse-large-mem-chunks-fix-mem-usage-fixes-3033.patch
@@ -0,0 +1,224 @@
1From a566fe4cc9f9d0ef9cfdcbc13159ef0644e91c9c Mon Sep 17 00:00:00 2001
2From: Glenn Strauss <gstrauss@gluelogic.com>
3Date: Wed, 23 Dec 2020 23:14:47 -0500
4Subject: [PATCH] reuse large mem chunks (fix mem usage) (fixes #3033)
5
6(cherry picked from commit 7ba521ffb4959f6f74a609d5d4acafc29a038337)
7
8(thx flynn)
9
10fix large memory usage for large file downloads from dynamic backends
11
12reuse or release large memory chunks
13
14x-ref:
15 "Memory Growth with PUT and full buffered streams"
16 https://redmine.lighttpd.net/issues/3033
17
18Upstream-Status: Backport
19Comment: Hunk refreshed to make it backword compatible.
20https://redmine.lighttpd.net/projects/lighttpd/repository/14/revisions/7ba521ffb4959f6f74a609d5d4acafc29a038337
21Signed-off-by: Purushottam Choudhary <Purushottam.Choudhary@kpit.com>
22
23---
24 src/chunk.c | 99 +++++++++++++++++++++++++++++++++---------
25 src/chunk.h | 2 +
26 src/http-header-glue.c | 2 +-
27 3 files changed, 82 insertions(+), 21 deletions(-)
28
29diff --git a/src/chunk.c b/src/chunk.c
30index 133308f..d7259b9 100644
31--- a/src/chunk.c
32+++ b/src/chunk.c
33@@ -28,16 +28,20 @@
34 static size_t chunk_buf_sz = 8192;
35 static chunk *chunks, *chunks_oversized;
36 static chunk *chunk_buffers;
37+static int chunks_oversized_n;
38 static array *chunkqueue_default_tempdirs = NULL;
39 static off_t chunkqueue_default_tempfile_size = DEFAULT_TEMPFILE_SIZE;
40
41 void chunkqueue_set_chunk_size (size_t sz)
42 {
43- chunk_buf_sz = sz > 0 ? ((sz + 1023) & ~1023uL) : 8192;
44+ size_t x = 1024;
45+ while (x < sz && x < (1u << 30)) x <<= 1;
46+ chunk_buf_sz = sz > 0 ? x : 8192;
47 }
48
49 void chunkqueue_set_tempdirs_default_reset (void)
50 {
51+ chunk_buf_sz = 8192;
52 chunkqueue_default_tempdirs = NULL;
53 chunkqueue_default_tempfile_size = DEFAULT_TEMPFILE_SIZE;
54 }
55@@ -120,15 +124,49 @@ static void chunk_free(chunk *c) {
56 free(c);
57 }
58
59-buffer * chunk_buffer_acquire(void) {
60+static chunk * chunk_pop_oversized(size_t sz) {
61+ /* future: might have buckets of certain sizes, up to socket buf sizes */
62+ if (chunks_oversized && chunks_oversized->mem->size >= sz) {
63+ --chunks_oversized_n;
64+ chunk *c = chunks_oversized;
65+ chunks_oversized = c->next;
66+ return c;
67+ }
68+ return NULL;
69+}
70+
71+static void chunk_push_oversized(chunk * const c, const size_t sz) {
72+ if (chunks_oversized_n < 64 && chunk_buf_sz >= 4096) {
73+ ++chunks_oversized_n;
74+ chunk **co = &chunks_oversized;
75+ while (*co && sz < (*co)->mem->size) co = &(*co)->next;
76+ c->next = *co;
77+ *co = c;
78+ }
79+ else
80+ chunk_free(c);
81+}
82+
83+static buffer * chunk_buffer_acquire_sz(size_t sz) {
84 chunk *c;
85 buffer *b;
86- if (chunks) {
87- c = chunks;
88- chunks = c->next;
89+ if (sz <= chunk_buf_sz) {
90+ if (chunks) {
91+ c = chunks;
92+ chunks = c->next;
93+ }
94+ else
95+ c = chunk_init(chunk_buf_sz);
96+ /* future: might choose to pop from chunks_oversized, if available
97+ * (even if larger than sz) rather than allocating new chunk
98+ * (and if doing so, might replace chunks_oversized_n) */
99 }
100 else {
101- c = chunk_init(chunk_buf_sz);
102+ /*(round up to nearest chunk_buf_sz)*/
103+ sz = (sz + (chunk_buf_sz-1)) & ~(chunk_buf_sz-1);
104+ c = chunk_pop_oversized(sz);
105+ if (NULL == c)
106+ c = chunk_init(sz);
107 }
108 c->next = chunk_buffers;
109 chunk_buffers = c;
110@@ -137,21 +175,47 @@ buffer * chunk_buffer_acquire(void) {
111 return b;
112 }
113
114+buffer * chunk_buffer_acquire(void) {
115+ return chunk_buffer_acquire_sz(chunk_buf_sz);
116+}
117+
118 void chunk_buffer_release(buffer *b) {
119 if (NULL == b) return;
120- if (b->size >= chunk_buf_sz && chunk_buffers) {
121+ if (chunk_buffers) {
122 chunk *c = chunk_buffers;
123 chunk_buffers = c->next;
124 c->mem = b;
125- c->next = chunks;
126- chunks = c;
127 buffer_clear(b);
128+ if (b->size == chunk_buf_sz) {
129+ c->next = chunks;
130+ chunks = c;
131+ }
132+ else if (b->size > chunk_buf_sz)
133+ chunk_push_oversized(c, b->size);
134+ else
135+ chunk_free(c);
136 }
137 else {
138 buffer_free(b);
139 }
140 }
141
142+size_t chunk_buffer_prepare_append(buffer * const b, size_t sz) {
143+ if (sz > chunk_buffer_string_space(b)) {
144+ sz += b->used ? b->used : 1;
145+ buffer * const cb = chunk_buffer_acquire_sz(sz);
146+ /* swap buffer contents and copy original b->ptr into larger b->ptr */
147+ /*(this does more than buffer_move())*/
148+ buffer tb = *b;
149+ *b = *cb;
150+ *cb = tb;
151+ if ((b->used = tb.used))
152+ memcpy(b->ptr, tb.ptr, tb.used);
153+ chunk_buffer_release(cb);
154+ }
155+ return chunk_buffer_string_space(b);
156+}
157+
158 static chunk * chunk_acquire(size_t sz) {
159 if (sz <= chunk_buf_sz) {
160 if (chunks) {
161@@ -162,13 +226,10 @@ static chunk * chunk_acquire(size_t sz) {
162 sz = chunk_buf_sz;
163 }
164 else {
165- sz = (sz + 8191) & ~8191uL;
166- /* future: might have buckets of certain sizes, up to socket buf sizes*/
167- if (chunks_oversized && chunks_oversized->mem->size >= sz) {
168- chunk *c = chunks_oversized;
169- chunks_oversized = c->next;
170- return c;
171- }
172+ /*(round up to nearest chunk_buf_sz)*/
173+ sz = (sz + (chunk_buf_sz-1)) & ~(chunk_buf_sz-1);
174+ chunk *c = chunk_pop_oversized(sz);
175+ if (c) return c;
176 }
177
178 return chunk_init(sz);
179@@ -183,10 +244,7 @@ static void chunk_release(chunk *c) {
180 }
181 else if (sz > chunk_buf_sz) {
182 chunk_reset(c);
183- chunk **co = &chunks_oversized;
184- while (*co && sz < (*co)->mem->size) co = &(*co)->next;
185- c->next = *co;
186- *co = c;
187+ chunk_push_oversized(c, sz);
188 }
189 else {
190 chunk_free(c);
191@@ -205,6 +263,7 @@ void chunkqueue_chunk_pool_clear(void)
192 chunk_free(c);
193 }
194 chunks_oversized = NULL;
195+ chunks_oversized_n = 0;
196 }
197
198 void chunkqueue_chunk_pool_free(void)
199diff --git a/src/chunk.h b/src/chunk.h
200index 4c6b7e4..93f343c 100644
201--- a/src/chunk.h
202+++ b/src/chunk.h
203@@ -50,6 +50,8 @@ typedef struct {
204 buffer * chunk_buffer_acquire(void);
205 void chunk_buffer_release(buffer *b);
206
207+size_t chunk_buffer_prepare_append (buffer *b, size_t sz);
208+
209 void chunkqueue_chunk_pool_clear(void);
210 void chunkqueue_chunk_pool_free(void);
211
212diff --git a/src/http-header-glue.c b/src/http-header-glue.c
213index d54f00c..2231fba 100644
214--- a/src/http-header-glue.c
215+++ b/src/http-header-glue.c
216@@ -1267,7 +1267,7 @@ handler_t http_response_read(server *srv, connection *con, http_response_opts *o
217 if (avail < toread) {
218 /*(add avail+toread to reduce allocations when ioctl EOPNOTSUPP)*/
219 avail = avail ? avail - 1 + toread : toread;
220- buffer_string_prepare_append(b, avail);
221+ avail = chunk_buffer_prepare_append(b, avail);
222 }
223
224 n = read(fd, b->ptr+buffer_string_length(b), avail);