commit 2b861fd01d64a3ae4432fe59211cc4691e359fc0 Author: Brad Spengler Date: Tue Jun 25 17:31:07 2013 -0400 on 64bit systems, the 'slab' elements of the vx_cacct struct can overflow under multiple large slab allocations change atomic_t to atomic_long_t to correct this and don't trucate their values when displaying them to userland via the cacct /proc entry diff --git a/include/linux/vserver/cacct_def.h b/include/linux/vserver/cacct_def.h index 5945f4f..6ba394b 100644 --- a/include/linux/vserver/cacct_def.h +++ b/include/linux/vserver/cacct_def.h @@ -14,7 +14,7 @@ struct _vx_sock_acc { struct _vx_cacct { struct _vx_sock_acc sock[VXA_SOCK_SIZE][3]; - atomic_t slab[8]; + atomic_long_t slab[8]; atomic_t page[6][8]; }; diff --git a/kernel/vserver/cacct_init.h b/kernel/vserver/cacct_init.h index 94d82e9..623f25e 100644 --- a/kernel/vserver/cacct_init.h +++ b/kernel/vserver/cacct_init.h @@ -12,7 +12,7 @@ static inline void vx_info_init_cacct(struct _vx_cacct *cacct) } } for (i = 0; i < 8; i++) - atomic_set(&cacct->slab[i], 0); + atomic_long_set(&cacct->slab[i], 0); for (i = 0; i < 5; i++) for (j = 0; j < 4; j++) atomic_set(&cacct->page[i][j], 0); diff --git a/kernel/vserver/cacct_proc.h b/kernel/vserver/cacct_proc.h index 0de9a38..3c2e1bd 100644 --- a/kernel/vserver/cacct_proc.h +++ b/kernel/vserver/cacct_proc.h @@ -28,11 +28,11 @@ static inline int vx_info_proc_cacct(struct _vx_cacct *cacct, char *buffer) length += sprintf(buffer + length, "\n"); length += sprintf(buffer + length, - "slab:\t %8u %8u %8u %8u\n", - atomic_read(&cacct->slab[1]), - atomic_read(&cacct->slab[4]), - atomic_read(&cacct->slab[0]), - atomic_read(&cacct->slab[2])); + "slab:\t %12lu %12lu %12lu %12lu\n", + atomic_long_read(&cacct->slab[1]), + atomic_long_read(&cacct->slab[4]), + atomic_long_read(&cacct->slab[0]), + atomic_long_read(&cacct->slab[2])); length += sprintf(buffer + length, "\n"); for (i = 0; i < 5; i++) { diff --git a/mm/slab_vs.h b/mm/slab_vs.h index 00c065e..5ee745c 100644 --- a/mm/slab_vs.h +++ b/mm/slab_vs.h @@ -12,7 +12,7 @@ void vx_slab_alloc(struct kmem_cache *cachep, gfp_t flags) if (!vxi) return; - atomic_add(cachep->buffer_size, &vxi->cacct.slab[what]); + atomic_long_add(cachep->buffer_size, &vxi->cacct.slab[what]); } static inline @@ -24,6 +24,6 @@ void vx_slab_free(struct kmem_cache *cachep) if (!vxi) return; - atomic_sub(cachep->buffer_size, &vxi->cacct.slab[what]); + atomic_long_sub(cachep->buffer_size, &vxi->cacct.slab[what]); }