diff --git a/NEWS b/NEWS index 6cf94c55..a6258354 100644 --- a/NEWS +++ b/NEWS @@ -6,6 +6,7 @@ ps: security labels can contain any printable ASCII top: help and version message on stdout, with exit(0) #283541 ps: SIGTSTP from ^Z shouldn't print bug email address slabtop: compile with glibc 2.2.17 (and older, likely) +slabtop: fix overflow on huge NUMA boxes procps-3.2.3 --> procps-3.2.4 diff --git a/proc/slab.c b/proc/slab.c index 29e6b589..f1a6bc21 100644 --- a/proc/slab.c +++ b/proc/slab.c @@ -136,8 +136,7 @@ static int parse_slabinfo20(struct slab_info **list, struct slab_stat *stats, if (curr->obj_size > stats->max_obj_size) stats->max_obj_size = curr->obj_size; - curr->cache_size = curr->nr_slabs * curr->pages_per_slab * - page_size; + curr->cache_size = (unsigned long)curr->nr_slabs * curr->pages_per_slab * page_size; if (curr->nr_objs) { curr->use = 100 * curr->nr_active_objs / curr->nr_objs; @@ -147,8 +146,8 @@ static int parse_slabinfo20(struct slab_info **list, struct slab_stat *stats, stats->nr_objs += curr->nr_objs; stats->nr_active_objs += curr->nr_active_objs; - stats->total_size += curr->nr_objs * curr->obj_size; - stats->active_size += curr->nr_active_objs * curr->obj_size; + stats->total_size += (unsigned long)curr->nr_objs * curr->obj_size; + stats->active_size += (unsigned long)curr->nr_active_objs * curr->obj_size; stats->nr_pages += curr->nr_slabs * curr->pages_per_slab; stats->nr_slabs += curr->nr_slabs; stats->nr_active_slabs += curr->nr_active_slabs; @@ -215,8 +214,7 @@ static int parse_slabinfo11(struct slab_info **list, struct slab_stat *stats, if (curr->obj_size > stats->max_obj_size) stats->max_obj_size = curr->obj_size; - curr->cache_size = curr->nr_slabs * curr->pages_per_slab * - page_size; + curr->cache_size = (unsigned long)curr->nr_slabs * curr->pages_per_slab * page_size; if (curr->nr_objs) { curr->use = 100 * curr->nr_active_objs / curr->nr_objs; @@ -230,8 +228,8 @@ static int parse_slabinfo11(struct slab_info **list, struct slab_stat *stats, stats->nr_objs += curr->nr_objs; stats->nr_active_objs += curr->nr_active_objs; - stats->total_size += curr->nr_objs * curr->obj_size; - stats->active_size += curr->nr_active_objs * curr->obj_size; + stats->total_size += (unsigned long)curr->nr_objs * curr->obj_size; + stats->active_size += (unsigned long)curr->nr_active_objs * curr->obj_size; stats->nr_pages += curr->nr_slabs * curr->pages_per_slab; stats->nr_slabs += curr->nr_slabs; stats->nr_active_slabs += curr->nr_active_slabs; diff --git a/proc/slab.h b/proc/slab.h index abe47688..ea17ddc9 100644 --- a/proc/slab.h +++ b/proc/slab.h @@ -1,35 +1,35 @@ #ifndef _PROC_SLAB_H #define _PROC_SLAB_H -#define SLAB_INFO_NAME_LEN 64 +#define SLAB_INFO_NAME_LEN 64 struct slab_info { - char name[SLAB_INFO_NAME_LEN]; /* name of this cache */ + char name[SLAB_INFO_NAME_LEN]; /* name of this cache */ struct slab_info *next; - int nr_objs; /* number of objects in this cache */ - int nr_active_objs; /* number of active objects */ - int obj_size; /* size of each object */ - int objs_per_slab; /* number of objects per slab */ - int pages_per_slab; /* number of pages per slab */ - int nr_slabs; /* number of slabs in this cache */ - int nr_active_slabs; /* number of active slabs */ - int use; /* percent full: total / active */ - int cache_size; /* size of entire cache */ + unsigned long cache_size; /* size of entire cache */ + unsigned nr_objs; /* number of objects in this cache */ + unsigned nr_active_objs; /* number of active objects */ + unsigned obj_size; /* size of each object */ + unsigned objs_per_slab; /* number of objects per slab */ + unsigned pages_per_slab; /* number of pages per slab */ + unsigned nr_slabs; /* number of slabs in this cache */ + unsigned nr_active_slabs; /* number of active slabs */ + unsigned use; /* percent full: total / active */ }; struct slab_stat { - int nr_objs; /* number of objects, among all caches */ - int nr_active_objs; /* number of active objects, among all caches */ - int total_size; /* size of all objects */ - int active_size; /* size of all active objects */ - int nr_pages; /* number of pages consumed by all objects */ - int nr_slabs; /* number of slabs, among all caches */ - int nr_active_slabs; /* number of active slabs, among all caches */ - int nr_caches; /* number of caches */ - int nr_active_caches; /* number of active caches */ - int avg_obj_size; /* average object size */ - int min_obj_size; /* size of smallest object */ - int max_obj_size; /* size of largest object */ + unsigned long total_size; /* size of all objects */ + unsigned long active_size; /* size of all active objects */ + unsigned nr_objs; /* number of objects, among all caches */ + unsigned nr_active_objs; /* number of active objects, among all caches */ + unsigned nr_pages; /* number of pages consumed by all objects */ + unsigned nr_slabs; /* number of slabs, among all caches */ + unsigned nr_active_slabs; /* number of active slabs, among all caches */ + unsigned nr_caches; /* number of caches */ + unsigned nr_active_caches; /* number of active caches */ + unsigned avg_obj_size; /* average object size */ + unsigned min_obj_size; /* size of smallest object */ + unsigned max_obj_size; /* size of largest object */ }; extern void put_slabinfo(struct slab_info *); diff --git a/slabtop.c b/slabtop.c index d33d4da7..36025e2f 100644 --- a/slabtop.c +++ b/slabtop.c @@ -346,27 +346,17 @@ int main(int argc, char *argv[]) } move(0,0); - printw( " Active / Total Objects (%% used) : " - "%d / %d (%.1f%%)\n" - " Active / Total Slabs (%% used) : " - "%d / %d (%.1f%%)\n" - " Active / Total Caches (%% used) : " - "%d / %d (%.1f%%)\n" - " Active / Total Size (%% used) : " - "%.2fK / %.2fK (%.1f%%)\n" - " Minimum / Average / Maximum Object : " - "%.2fK / %.2fK / %.2fK\n\n", - stats.nr_active_objs, stats.nr_objs, - 100.0 * stats.nr_active_objs / stats.nr_objs, - stats.nr_active_slabs, stats.nr_slabs, - 100.0 * stats.nr_active_slabs / stats.nr_slabs, - stats.nr_active_caches, stats.nr_caches, - 100.0 * stats.nr_active_caches / stats.nr_caches, - stats.active_size / 1024.0, stats.total_size / 1024.0, - 100.0 * stats.active_size / stats.total_size, - stats.min_obj_size / 1024.0, - stats.avg_obj_size / 1024.0, - stats.max_obj_size / 1024.0); + printw( " Active / Total Objects (%% used) : %d / %d (%.1f%%)\n" + " Active / Total Slabs (%% used) : %d / %d (%.1f%%)\n" + " Active / Total Caches (%% used) : %d / %d (%.1f%%)\n" + " Active / Total Size (%% used) : %.2fK / %.2fK (%.1f%%)\n" + " Minimum / Average / Maximum Object : %.2fK / %.2fK / %.2fK\n\n", + stats.nr_active_objs, stats.nr_objs, 100.0 * stats.nr_active_objs / stats.nr_objs, + stats.nr_active_slabs, stats.nr_slabs, 100.0 * stats.nr_active_slabs / stats.nr_slabs, + stats.nr_active_caches, stats.nr_caches, 100.0 * stats.nr_active_caches / stats.nr_caches, + stats.active_size / 1024.0, stats.total_size / 1024.0, 100.0 * stats.active_size / stats.total_size, + stats.min_obj_size / 1024.0, stats.avg_obj_size / 1024.0, stats.max_obj_size / 1024.0 + ); slab_list = slabsort(slab_list); @@ -378,10 +368,10 @@ int main(int argc, char *argv[]) curr = slab_list; for (i = 0; i < rows - 8 && curr->next; i++) { - printw("%6d %6d %3d%% %7.2fK %6d %8d %9dK %-23s\n", + printw("%6u %6u %3u%% %7.2fK %6u %8u %9uK %-23s\n", curr->nr_objs, curr->nr_active_objs, curr->use, curr->obj_size / 1024.0, curr->nr_slabs, - curr->objs_per_slab, curr->cache_size / 1024, + curr->objs_per_slab, (unsigned)(curr->cache_size / 1024), curr->name); curr = curr->next; }