Support for 3rd party zlib libraries
Maxim Dounin
mdounin at mdounin.ru
Wed Jul 30 02:17:11 UTC 2014
Hello!
On Tue, Jul 29, 2014 at 10:46:03PM +0200, Richard Stanway wrote:
> Hello,
> I recently came across a modified version of zlib with code contributed by
> Intel [1] that makes use of modern CPU instructions to increase
> performance. In testing, the performance gains seemed substantial, however
> when I tried to use this version with nginx, the following alert types
> appeared in the error_log on gzip requests:
>
> 2014/07/30 05:20:29 [alert] 22285#0: *739837 gzip filter failed to use
> preallocated memory: 65536 of 65520 while sending to client
> 2014/07/30 05:40:42 [alert] 29462#0: *230460 gzip filter failed to use
> preallocated memory: 1040 of 4112
>
> It appears nginx is pre-allocating a buffer based on the original zlib
> memory usage patterns, however the Intel optimized version has slightly
> higher memory requirements due to padding for SSE functions etc.
>
> Is there a chance this version could be supported by nginx, or a
> configuration option made available to control the allocation size?
>
> Thanks.
>
> [1] https://github.com/jtkukunas/zlib
This version indeed uses larger allocations (much larger in some
cases), and also uses different sizes which confuses nginx code
when it tries to allocate 8k for deflate state.
Quick hack to do correct preallocations for this zlib version:
--- a/src/http/modules/ngx_http_gzip_filter_module.c Wed Jul 09 12:27:15 2014 -0700
+++ b/src/http/modules/ngx_http_gzip_filter_module.c Wed Jul 30 05:57:50 2014 +0400
@@ -521,7 +521,16 @@ ngx_http_gzip_filter_memory(ngx_http_req
* *) 5920 bytes on amd64 and sparc64
*/
+#if 0
ctx->allocated = 8192 + (1 << (wbits + 2)) + (1 << (memlevel + 9));
+#endif
+
+ if (conf->level == 1) {
+ wbits = 13;
+ }
+
+ ctx->allocated = 8192 + 16 + (1 << (wbits + 2))
+ + (1 << (ngx_max(memlevel, 8) + 8)) + (1 << (memlevel + 8));
}
@@ -987,7 +996,7 @@ ngx_http_gzip_filter_alloc(void *opaque,
alloc = items * size;
- if (alloc % 512 != 0 && alloc < 8192) {
+ if (alloc % 512 != 0 && alloc < 8192 && items == 1) {
/*
* The zlib deflate_state allocation, it takes about 6K,
This is expected to work with normal zlib as well, but will be
suboptimal from memory usage point of view.
Note well that alerts logged aren't really serious - nginx is able
to handle such cases properly, and will fallback to normal pool
allocations instead of using preallocated block. It's just not
something it expects to ever happen, so it logs alerts to make
sure it's noticed. With different zlib libraries out there, we
probably want to just silence the alert, keeping preallocation
tuned for normal zlib.
--
Maxim Dounin
http://nginx.org/
More information about the nginx
mailing list