[nginx] Slab: slots statistics.

Ruslan Ermilov ru at nginx.com
Wed Dec 7 19:28:11 UTC 2016


details:   http://hg.nginx.org/nginx/rev/99770a5ea14f
branches:  
changeset: 6828:99770a5ea14f
user:      Ruslan Ermilov <ru at nginx.com>
date:      Wed Dec 07 22:25:37 2016 +0300
description:
Slab: slots statistics.

For each slot, the number of total and used entries, as well as
the number of allocation requests and failures, are tracked.

diffstat:

 src/core/ngx_slab.c |  57 ++++++++++++++++++++++++++++++++++++++++++----------
 src/core/ngx_slab.h |  11 ++++++++++
 2 files changed, 57 insertions(+), 11 deletions(-)

diffs (236 lines):

diff -r 0e61510c56c4 -r 99770a5ea14f src/core/ngx_slab.c
--- a/src/core/ngx_slab.c	Wed Dec 07 22:25:37 2016 +0300
+++ b/src/core/ngx_slab.c	Wed Dec 07 22:25:37 2016 +0300
@@ -120,7 +120,13 @@ ngx_slab_init(ngx_slab_pool_t *pool)
     }
 
     p += n * sizeof(ngx_slab_page_t);
-    size -= n * sizeof(ngx_slab_page_t);
+
+    pool->stats = (ngx_slab_stat_t *) p;
+    ngx_memzero(pool->stats, n * sizeof(ngx_slab_stat_t));
+
+    p += n * sizeof(ngx_slab_stat_t);
+
+    size -= n * (sizeof(ngx_slab_page_t) + sizeof(ngx_slab_stat_t));
 
     pages = (ngx_uint_t) (size / (ngx_pagesize + sizeof(ngx_slab_page_t)));
 
@@ -205,6 +211,8 @@ ngx_slab_alloc_locked(ngx_slab_pool_t *p
         slot = 0;
     }
 
+    pool->stats[slot].reqs++;
+
     ngx_log_debug2(NGX_LOG_DEBUG_ALLOC, ngx_cycle->log, 0,
                    "slab alloc: %uz slot: %ui", size, slot);
 
@@ -232,11 +240,13 @@ ngx_slab_alloc_locked(ngx_slab_pool_t *p
 
                         i = (n * sizeof(uintptr_t) * 8 + i) << shift;
 
+                        p = (uintptr_t) bitmap + i;
+
+                        pool->stats[slot].used++;
+
                         if (bitmap[n] == NGX_SLAB_BUSY) {
                             for (n = n + 1; n < map; n++) {
                                 if (bitmap[n] != NGX_SLAB_BUSY) {
-                                    p = (uintptr_t) bitmap + i;
-
                                     goto done;
                                 }
                             }
@@ -249,8 +259,6 @@ ngx_slab_alloc_locked(ngx_slab_pool_t *p
                             page->prev = NGX_SLAB_SMALL;
                         }
 
-                        p = (uintptr_t) bitmap + i;
-
                         goto done;
                     }
                 }
@@ -276,6 +284,8 @@ ngx_slab_alloc_locked(ngx_slab_pool_t *p
 
                 p = ngx_slab_page_addr(pool, page) + (i << shift);
 
+                pool->stats[slot].used++;
+
                 goto done;
             }
 
@@ -305,6 +315,8 @@ ngx_slab_alloc_locked(ngx_slab_pool_t *p
 
                 p = ngx_slab_page_addr(pool, page) + (i << shift);
 
+                pool->stats[slot].used++;
+
                 goto done;
             }
         }
@@ -339,8 +351,12 @@ ngx_slab_alloc_locked(ngx_slab_pool_t *p
 
             slots[slot].next = page;
 
+            pool->stats[slot].total += (ngx_pagesize >> shift) - n;
+
             p = ngx_slab_page_addr(pool, page) + (n << shift);
 
+            pool->stats[slot].used++;
+
             goto done;
 
         } else if (shift == ngx_slab_exact_shift) {
@@ -351,8 +367,12 @@ ngx_slab_alloc_locked(ngx_slab_pool_t *p
 
             slots[slot].next = page;
 
+            pool->stats[slot].total += sizeof(uintptr_t) * 8;
+
             p = ngx_slab_page_addr(pool, page);
 
+            pool->stats[slot].used++;
+
             goto done;
 
         } else { /* shift > ngx_slab_exact_shift */
@@ -363,14 +383,20 @@ ngx_slab_alloc_locked(ngx_slab_pool_t *p
 
             slots[slot].next = page;
 
+            pool->stats[slot].total += ngx_pagesize >> shift;
+
             p = ngx_slab_page_addr(pool, page);
 
+            pool->stats[slot].used++;
+
             goto done;
         }
     }
 
     p = 0;
 
+    pool->stats[slot].fails++;
+
 done:
 
     ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, ngx_cycle->log, 0,
@@ -425,7 +451,7 @@ ngx_slab_free_locked(ngx_slab_pool_t *po
 {
     size_t            size;
     uintptr_t         slab, m, *bitmap;
-    ngx_uint_t        n, type, slot, shift, map;
+    ngx_uint_t        i, n, type, slot, shift, map;
     ngx_slab_page_t  *slots, *page;
 
     ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, ngx_cycle->log, 0, "slab free: %p", p);
@@ -458,10 +484,10 @@ ngx_slab_free_locked(ngx_slab_pool_t *po
                              ((uintptr_t) p & ~((uintptr_t) ngx_pagesize - 1));
 
         if (bitmap[n] & m) {
+            slot = shift - pool->min_shift;
 
             if (page->next == NULL) {
                 slots = ngx_slab_slots(pool);
-                slot = shift - pool->min_shift;
 
                 page->next = slots[slot].next;
                 slots[slot].next = page;
@@ -484,14 +510,16 @@ ngx_slab_free_locked(ngx_slab_pool_t *po
 
             map = (ngx_pagesize >> shift) / (sizeof(uintptr_t) * 8);
 
-            for (n = 1; n < map; n++) {
-                if (bitmap[n]) {
+            for (i = 1; i < map; i++) {
+                if (bitmap[i]) {
                     goto done;
                 }
             }
 
             ngx_slab_free_pages(pool, page, 1);
 
+            pool->stats[slot].total -= (ngx_pagesize >> shift) - n;
+
             goto done;
         }
 
@@ -508,9 +536,10 @@ ngx_slab_free_locked(ngx_slab_pool_t *po
         }
 
         if (slab & m) {
+            slot = ngx_slab_exact_shift - pool->min_shift;
+
             if (slab == NGX_SLAB_BUSY) {
                 slots = ngx_slab_slots(pool);
-                slot = ngx_slab_exact_shift - pool->min_shift;
 
                 page->next = slots[slot].next;
                 slots[slot].next = page;
@@ -527,6 +556,8 @@ ngx_slab_free_locked(ngx_slab_pool_t *po
 
             ngx_slab_free_pages(pool, page, 1);
 
+            pool->stats[slot].total -= sizeof(uintptr_t) * 8;
+
             goto done;
         }
 
@@ -545,10 +576,10 @@ ngx_slab_free_locked(ngx_slab_pool_t *po
                               + NGX_SLAB_MAP_SHIFT);
 
         if (slab & m) {
+            slot = shift - pool->min_shift;
 
             if (page->next == NULL) {
                 slots = ngx_slab_slots(pool);
-                slot = shift - pool->min_shift;
 
                 page->next = slots[slot].next;
                 slots[slot].next = page;
@@ -565,6 +596,8 @@ ngx_slab_free_locked(ngx_slab_pool_t *po
 
             ngx_slab_free_pages(pool, page, 1);
 
+            pool->stats[slot].total -= ngx_pagesize >> shift;
+
             goto done;
         }
 
@@ -604,6 +637,8 @@ ngx_slab_free_locked(ngx_slab_pool_t *po
 
 done:
 
+    pool->stats[slot].used--;
+
     ngx_slab_junk(p, size);
 
     return;
diff -r 0e61510c56c4 -r 99770a5ea14f src/core/ngx_slab.h
--- a/src/core/ngx_slab.h	Wed Dec 07 22:25:37 2016 +0300
+++ b/src/core/ngx_slab.h	Wed Dec 07 22:25:37 2016 +0300
@@ -23,6 +23,15 @@ struct ngx_slab_page_s {
 
 
 typedef struct {
+    ngx_uint_t        total;
+    ngx_uint_t        used;
+
+    ngx_uint_t        reqs;
+    ngx_uint_t        fails;
+} ngx_slab_stat_t;
+
+
+typedef struct {
     ngx_shmtx_sh_t    lock;
 
     size_t            min_size;
@@ -32,6 +41,8 @@ typedef struct {
     ngx_slab_page_t  *last;
     ngx_slab_page_t   free;
 
+    ngx_slab_stat_t  *stats;
+
     u_char           *start;
     u_char           *end;
 


More information about the nginx-devel mailing list