From: clameter@sgi.com
To: akpm@linux-foundation.org
Cc: linux-kernel@vger.kernel.org, linux-mm@kvack.org,
Pekka Enberg <penberg@cs.helsinki.fi>,
suresh.b.siddha@intel.com
Subject: [patch 14/26] SLUB: Logic to trigger slab defragmentation from memory reclaim
Date: Mon, 18 Jun 2007 02:58:52 -0700 [thread overview]
Message-ID: <20070618095916.764877426@sgi.com> (raw)
In-Reply-To: <20070618095838.238615343@sgi.com>
[-- Attachment #1: slab_defrag_trigger --]
[-- Type: text/plain, Size: 9781 bytes --]
At some point slab defragmentation needs to be triggered. The logical
point for this is after slab shrinking was performed in vmscan.c. At
that point the fragmentation ratio of a slab was increased by objects
being freed. So we call kmem_cache_defrag from there.
kmem_cache_defrag takes the defrag ratio to make the decision to
defrag a slab or not. We define a new VM tunable
slab_defrag_ratio
that contains the limit to trigger slab defragmentation.
slab_shrink() from vmscan.c is called in some contexts to do
global shrinking of slabs and in others to do shrinking for
a particular zone. Pass the zone to slab_shrink, so that slab_shrink
can call kmem_cache_defrag() and restrict the defragmentation to
the node that is under memory pressure.
Signed-off-by: Christoph Lameter <clameter@sgi.com>
---
Documentation/sysctl/vm.txt | 25 +++++++++++++++++++++++++
fs/drop_caches.c | 2 +-
include/linux/mm.h | 2 +-
include/linux/slab.h | 1 +
kernel/sysctl.c | 10 ++++++++++
mm/vmscan.c | 34 +++++++++++++++++++++++++++-------
6 files changed, 65 insertions(+), 9 deletions(-)
Index: linux-2.6.22-rc4-mm2/Documentation/sysctl/vm.txt
===================================================================
--- linux-2.6.22-rc4-mm2.orig/Documentation/sysctl/vm.txt 2007-06-17 18:08:02.000000000 -0700
+++ linux-2.6.22-rc4-mm2/Documentation/sysctl/vm.txt 2007-06-17 18:12:29.000000000 -0700
@@ -35,6 +35,7 @@ Currently, these files are in /proc/sys/
- swap_prefetch
- swap_prefetch_delay
- swap_prefetch_sleep
+- slab_defrag_ratio
==============================================================
@@ -300,3 +301,27 @@ sleep for when the ram is found to be fu
further.
The default value is 5.
+
+==============================================================
+
+slab_defrag_ratio
+
+After shrinking the slabs the system checks if slabs have a lower usage
+ratio than the percentage given here. If so then slab defragmentation is
+activated to increase the usage ratio of the slab and in order to free
+memory.
+
+This is the percentage of objects allocated of the total possible number
+of objects in a slab. A lower percentage signifies more fragmentation.
+
+Note slab defragmentation only works on slabs that have the proper methods
+defined (see /sys/slab/<slabname>/ops). When this text was written slab
+defragmentation was only supported by the dentry cache and the inode cache.
+
+The main purpose of the slab defragmentation is to address pathological
+situations in which large amounts of inodes or dentries have been
+removed from the system. That may leave lots of slabs around with just
+a few objects. Slab defragmentation removes these slabs.
+
+The default value is 30% meaning for 3 items in use we have 7 free
+and unused items.
Index: linux-2.6.22-rc4-mm2/include/linux/slab.h
===================================================================
--- linux-2.6.22-rc4-mm2.orig/include/linux/slab.h 2007-06-17 18:12:22.000000000 -0700
+++ linux-2.6.22-rc4-mm2/include/linux/slab.h 2007-06-17 18:12:29.000000000 -0700
@@ -97,6 +97,7 @@ void kmem_cache_free(struct kmem_cache *
unsigned int kmem_cache_size(struct kmem_cache *);
const char *kmem_cache_name(struct kmem_cache *);
int kmem_ptr_validate(struct kmem_cache *cachep, const void *ptr);
+int kmem_cache_defrag(int percentage, int node);
/*
* Please use this macro to create slab caches. Simply specify the
Index: linux-2.6.22-rc4-mm2/kernel/sysctl.c
===================================================================
--- linux-2.6.22-rc4-mm2.orig/kernel/sysctl.c 2007-06-17 18:08:02.000000000 -0700
+++ linux-2.6.22-rc4-mm2/kernel/sysctl.c 2007-06-17 18:12:29.000000000 -0700
@@ -81,6 +81,7 @@ extern int percpu_pagelist_fraction;
extern int compat_log;
extern int maps_protect;
extern int sysctl_stat_interval;
+extern int sysctl_slab_defrag_ratio;
/* this is needed for the proc_dointvec_minmax for [fs_]overflow UID and GID */
static int maxolduid = 65535;
@@ -917,6 +918,15 @@ static ctl_table vm_table[] = {
.strategy = &sysctl_intvec,
.extra1 = &zero,
},
+ {
+ .ctl_name = CTL_UNNUMBERED,
+ .procname = "slab_defrag_ratio",
+ .data = &sysctl_slab_defrag_ratio,
+ .maxlen = sizeof(sysctl_slab_defrag_ratio),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec,
+ .strategy = &sysctl_intvec,
+ },
#ifdef HAVE_ARCH_PICK_MMAP_LAYOUT
{
.ctl_name = VM_LEGACY_VA_LAYOUT,
Index: linux-2.6.22-rc4-mm2/mm/vmscan.c
===================================================================
--- linux-2.6.22-rc4-mm2.orig/mm/vmscan.c 2007-06-17 18:08:02.000000000 -0700
+++ linux-2.6.22-rc4-mm2/mm/vmscan.c 2007-06-17 18:12:29.000000000 -0700
@@ -135,6 +135,12 @@ void unregister_shrinker(struct shrinker
EXPORT_SYMBOL(unregister_shrinker);
#define SHRINK_BATCH 128
+
+/*
+ * Slabs should be defragmented if less than 30% of objects are allocated.
+ */
+int sysctl_slab_defrag_ratio = 30;
+
/*
* Call the shrink functions to age shrinkable caches
*
@@ -152,10 +158,19 @@ EXPORT_SYMBOL(unregister_shrinker);
* are eligible for the caller's allocation attempt. It is used for balancing
* slab reclaim versus page reclaim.
*
+ * zone is the zone for which we are shrinking the slabs. If the intent
+ * is to do a global shrink then zone can be be NULL. This is currently
+ * only used to limit slab defragmentation to a NUMA node. The performace
+ * of shrink_slab would be better (in particular under NUMA) if it could
+ * be targeted as a whole to a zone that is under memory pressure but
+ * the VFS datastructures do not allow that at the present time. As a
+ * result zone_reclaim must perform global slab reclaim in order
+ * to free up memory in a zone.
+ *
* Returns the number of slab objects which we shrunk.
*/
unsigned long shrink_slab(unsigned long scanned, gfp_t gfp_mask,
- unsigned long lru_pages)
+ unsigned long lru_pages, struct zone *zone)
{
struct shrinker *shrinker;
unsigned long ret = 0;
@@ -218,6 +233,8 @@ unsigned long shrink_slab(unsigned long
shrinker->nr += total_scan;
}
up_read(&shrinker_rwsem);
+ kmem_cache_defrag(sysctl_slab_defrag_ratio,
+ zone ? zone_to_nid(zone) : -1);
return ret;
}
@@ -1163,7 +1180,8 @@ unsigned long try_to_free_pages(struct z
if (!priority)
disable_swap_token();
nr_reclaimed += shrink_zones(priority, zones, &sc);
- shrink_slab(sc.nr_scanned, gfp_mask, lru_pages);
+ shrink_slab(sc.nr_scanned, gfp_mask, lru_pages,
+ NULL);
if (reclaim_state) {
nr_reclaimed += reclaim_state->reclaimed_slab;
reclaim_state->reclaimed_slab = 0;
@@ -1333,7 +1351,7 @@ loop_again:
nr_reclaimed += shrink_zone(priority, zone, &sc);
reclaim_state->reclaimed_slab = 0;
nr_slab = shrink_slab(sc.nr_scanned, GFP_KERNEL,
- lru_pages);
+ lru_pages, zone);
nr_reclaimed += reclaim_state->reclaimed_slab;
total_scanned += sc.nr_scanned;
if (zone->all_unreclaimable)
@@ -1601,7 +1619,7 @@ unsigned long shrink_all_memory(unsigned
/* If slab caches are huge, it's better to hit them first */
while (nr_slab >= lru_pages) {
reclaim_state.reclaimed_slab = 0;
- shrink_slab(nr_pages, sc.gfp_mask, lru_pages);
+ shrink_slab(nr_pages, sc.gfp_mask, lru_pages, NULL);
if (!reclaim_state.reclaimed_slab)
break;
@@ -1639,7 +1657,7 @@ unsigned long shrink_all_memory(unsigned
reclaim_state.reclaimed_slab = 0;
shrink_slab(sc.nr_scanned, sc.gfp_mask,
- count_lru_pages());
+ count_lru_pages(), NULL);
ret += reclaim_state.reclaimed_slab;
if (ret >= nr_pages)
goto out;
@@ -1656,7 +1674,8 @@ unsigned long shrink_all_memory(unsigned
if (!ret) {
do {
reclaim_state.reclaimed_slab = 0;
- shrink_slab(nr_pages, sc.gfp_mask, count_lru_pages());
+ shrink_slab(nr_pages, sc.gfp_mask,
+ count_lru_pages(), NULL);
ret += reclaim_state.reclaimed_slab;
} while (ret < nr_pages && reclaim_state.reclaimed_slab > 0);
}
@@ -1816,7 +1835,8 @@ static int __zone_reclaim(struct zone *z
* Note that shrink_slab will free memory on all zones and may
* take a long time.
*/
- while (shrink_slab(sc.nr_scanned, gfp_mask, order) &&
+ while (shrink_slab(sc.nr_scanned, gfp_mask, order,
+ zone) &&
zone_page_state(zone, NR_SLAB_RECLAIMABLE) >
slab_reclaimable - nr_pages)
;
Index: linux-2.6.22-rc4-mm2/fs/drop_caches.c
===================================================================
--- linux-2.6.22-rc4-mm2.orig/fs/drop_caches.c 2007-06-17 18:08:02.000000000 -0700
+++ linux-2.6.22-rc4-mm2/fs/drop_caches.c 2007-06-17 18:12:29.000000000 -0700
@@ -52,7 +52,7 @@ void drop_slab(void)
int nr_objects;
do {
- nr_objects = shrink_slab(1000, GFP_KERNEL, 1000);
+ nr_objects = shrink_slab(1000, GFP_KERNEL, 1000, NULL);
} while (nr_objects > 10);
}
Index: linux-2.6.22-rc4-mm2/include/linux/mm.h
===================================================================
--- linux-2.6.22-rc4-mm2.orig/include/linux/mm.h 2007-06-17 18:08:02.000000000 -0700
+++ linux-2.6.22-rc4-mm2/include/linux/mm.h 2007-06-17 18:12:29.000000000 -0700
@@ -1229,7 +1229,7 @@ int in_gate_area_no_task(unsigned long a
int drop_caches_sysctl_handler(struct ctl_table *, int, struct file *,
void __user *, size_t *, loff_t *);
unsigned long shrink_slab(unsigned long scanned, gfp_t gfp_mask,
- unsigned long lru_pages);
+ unsigned long lru_pages, struct zone *zone);
extern void drop_pagecache_sb(struct super_block *);
void drop_pagecache(void);
void drop_slab(void);
--
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
next prev parent reply other threads:[~2007-06-18 9:58 UTC|newest]
Thread overview: 73+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-06-18 9:58 [patch 00/26] Current slab allocator / SLUB patch queue clameter
2007-06-18 9:58 ` [patch 01/26] SLUB Debug: Fix initial object debug state of NUMA bootstrap objects clameter
2007-06-18 9:58 ` [patch 02/26] Slab allocators: Consolidate code for krealloc in mm/util.c clameter
2007-06-18 20:03 ` Pekka Enberg
2007-06-18 9:58 ` [patch 03/26] Slab allocators: Consistent ZERO_SIZE_PTR support and NULL result semantics clameter
2007-06-18 20:08 ` Pekka Enberg
2007-06-18 9:58 ` [patch 04/26] Slab allocators: Support __GFP_ZERO in all allocators clameter
2007-06-18 10:09 ` Paul Mundt
2007-06-18 16:17 ` Christoph Lameter
2007-06-18 20:11 ` Pekka Enberg
2007-06-18 9:58 ` [patch 05/26] Slab allocators: Cleanup zeroing allocations clameter
2007-06-18 20:16 ` Pekka Enberg
2007-06-18 20:26 ` Pekka Enberg
2007-06-18 22:34 ` Christoph Lameter
2007-06-19 5:48 ` Pekka Enberg
2007-06-18 21:55 ` Christoph Lameter
2007-06-19 21:00 ` Matt Mackall
2007-06-19 22:33 ` Christoph Lameter
2007-06-20 6:14 ` Pekka J Enberg
2007-06-18 9:58 ` [patch 06/26] Slab allocators: Replace explicit zeroing with __GFP_ZERO clameter
2007-06-19 20:55 ` Pekka Enberg
2007-06-28 6:09 ` Andrew Morton
2007-06-18 9:58 ` [patch 07/26] SLUB: Add some more inlines and #ifdef CONFIG_SLUB_DEBUG clameter
2007-06-18 9:58 ` [patch 08/26] SLUB: Extract dma_kmalloc_cache from get_cache clameter
2007-06-18 9:58 ` [patch 09/26] SLUB: Do proper locking during dma slab creation clameter
2007-06-18 9:58 ` [patch 10/26] SLUB: Faster more efficient slab determination for __kmalloc clameter
2007-06-19 20:08 ` Andrew Morton
2007-06-19 22:22 ` Christoph Lameter
2007-06-19 22:29 ` Andrew Morton
2007-06-19 22:38 ` Christoph Lameter
2007-06-19 22:46 ` Andrew Morton
2007-06-25 6:41 ` Nick Piggin
2007-06-18 9:58 ` [patch 11/26] SLUB: Add support for kmem_cache_ops clameter
2007-06-19 20:58 ` Pekka Enberg
2007-06-19 22:32 ` Christoph Lameter
2007-06-18 9:58 ` [patch 12/26] SLUB: Slab defragmentation core clameter
2007-06-26 8:18 ` Andrew Morton
2007-06-26 18:19 ` Christoph Lameter
2007-06-26 18:38 ` Andrew Morton
2007-06-26 18:52 ` Christoph Lameter
2007-06-26 19:13 ` Nish Aravamudan
2007-06-26 19:19 ` Christoph Lameter
2007-06-18 9:58 ` [patch 13/26] SLUB: Extend slabinfo to support -D and -C options clameter
2007-06-18 9:58 ` clameter [this message]
2007-06-18 9:58 ` [patch 15/26] Slab defrag: Support generic defragmentation for inode slab caches clameter
2007-06-26 8:18 ` Andrew Morton
2007-06-26 18:21 ` Christoph Lameter
2007-06-26 19:28 ` Christoph Lameter
2007-06-26 19:37 ` Andrew Morton
2007-06-26 19:41 ` Christoph Lameter
2007-06-18 9:58 ` [patch 16/26] Slab defragmentation: Support defragmentation for extX filesystem inodes clameter
2007-06-18 9:58 ` [patch 17/26] Slab defragmentation: Support inode defragmentation for xfs clameter
2007-06-18 9:58 ` [patch 18/26] Slab defragmentation: Support procfs inode defragmentation clameter
2007-06-18 9:58 ` [patch 19/26] Slab defragmentation: Support reiserfs " clameter
2007-06-18 9:58 ` [patch 20/26] Slab defragmentation: Support inode defragmentation for sockets clameter
2007-06-18 9:58 ` [patch 21/26] Slab defragmentation: support dentry defragmentation clameter
2007-06-26 8:18 ` Andrew Morton
2007-06-26 18:23 ` Christoph Lameter
2007-06-18 9:59 ` [patch 22/26] SLUB: kmem_cache_vacate to support page allocator memory defragmentation clameter
2007-06-18 9:59 ` [patch 23/26] SLUB: Move sysfs operations outside of slub_lock clameter
2007-06-18 9:59 ` [patch 24/26] SLUB: Avoid page struct cacheline bouncing due to remote frees to cpu slab clameter
2007-06-18 9:59 ` [patch 25/26] SLUB: Add an object counter to the kmem_cache_cpu structure clameter
2007-06-18 9:59 ` [patch 26/26] SLUB: Place kmem_cache_cpu structures in a NUMA aware way clameter
2007-06-19 23:17 ` Christoph Lameter
2007-06-18 11:57 ` [patch 00/26] Current slab allocator / SLUB patch queue Michal Piotrowski
2007-06-18 16:46 ` Christoph Lameter
2007-06-18 17:38 ` Michal Piotrowski
2007-06-18 18:05 ` Christoph Lameter
2007-06-18 18:58 ` Michal Piotrowski
2007-06-18 19:00 ` Christoph Lameter
2007-06-18 19:09 ` Michal Piotrowski
2007-06-18 19:19 ` Christoph Lameter
2007-06-18 20:43 ` Michal Piotrowski
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20070618095916.764877426@sgi.com \
--to=clameter@sgi.com \
--cc=akpm@linux-foundation.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=penberg@cs.helsinki.fi \
--cc=suresh.b.siddha@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox