[folded-merged] mm-fix-race-between-kmem_cache-destroy-create-and-deactivate-v2.patch removed from -mm tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The patch titled
     Subject: mm-fix-race-between-kmem_cache-destroy-create-and-deactivate-v2
has been removed from the -mm tree.  Its filename was
     mm-fix-race-between-kmem_cache-destroy-create-and-deactivate-v2.patch

This patch was dropped because it was folded into mm-fix-race-between-kmem_cache-destroy-create-and-deactivate.patch

------------------------------------------------------
From: Shakeel Butt <shakeelb@xxxxxxxxxx>
Subject: mm-fix-race-between-kmem_cache-destroy-create-and-deactivate-v2

add more documentation, rename fields to be more readable

Link: http://lkml.kernel.org/r/20180522201336.196994-1-shakeelb@xxxxxxxxxx
Signed-off-by: Shakeel Butt <shakeelb@xxxxxxxxxx>
Cc: Michal Hocko <mhocko@xxxxxxxxxx>
Cc: Greg Thelen <gthelen@xxxxxxxxxx>
Cc: Christoph Lameter <cl@xxxxxxxxx>
Cc: Pekka Enberg <penberg@xxxxxxxxxx>
Cc: David Rientjes <rientjes@xxxxxxxxxx>
Cc: Joonsoo Kim <iamjoonsoo.kim@xxxxxxx>
Cc: Johannes Weiner <hannes@xxxxxxxxxxx>
Cc: Vladimir Davydov <vdavydov.dev@xxxxxxxxx>
Cc: Tejun Heo <tj@xxxxxxxxxx>
Signed-off-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx>
---

 include/linux/slab_def.h |    4 ++
 include/linux/slub_def.h |    4 +-
 mm/slab.c                |    2 -
 mm/slab.h                |    4 +-
 mm/slab_common.c         |   52 ++++++++++++++++++++++++++++++++-----
 mm/slub.c                |   10 +++----
 6 files changed, 58 insertions(+), 18 deletions(-)

diff -puN include/linux/slab_def.h~mm-fix-race-between-kmem_cache-destroy-create-and-deactivate-v2 include/linux/slab_def.h
--- a/include/linux/slab_def.h~mm-fix-race-between-kmem_cache-destroy-create-and-deactivate-v2
+++ a/include/linux/slab_def.h
@@ -41,8 +41,10 @@ struct kmem_cache {
 /* 4) cache creation/removal */
 	const char *name;
 	struct list_head list;
+	/* Refcount for root kmem caches */
 	refcount_t refcount;
-	int alias_count;
+	/* Number of root kmem caches sharing this cache */
+	int shared_count;
 	int object_size;
 	int align;
 
diff -puN include/linux/slub_def.h~mm-fix-race-between-kmem_cache-destroy-create-and-deactivate-v2 include/linux/slub_def.h
--- a/include/linux/slub_def.h~mm-fix-race-between-kmem_cache-destroy-create-and-deactivate-v2
+++ a/include/linux/slub_def.h
@@ -97,8 +97,8 @@ struct kmem_cache {
 	struct kmem_cache_order_objects max;
 	struct kmem_cache_order_objects min;
 	gfp_t allocflags;	/* gfp flags to use on each alloc */
-	refcount_t refcount;	/* Refcount for slab cache destroy */
-	int alias_count;	/* Number of root kmem caches merged */
+	refcount_t refcount;	/* Refcount for root kmem cache */
+	int shared_count;	/* Number of kmem caches sharing this cache */
 	void (*ctor)(void *);
 	unsigned int inuse;		/* Offset to metadata */
 	unsigned int align;		/* Alignment */
diff -puN mm/slab.c~mm-fix-race-between-kmem_cache-destroy-create-and-deactivate-v2 mm/slab.c
--- a/mm/slab.c~mm-fix-race-between-kmem_cache-destroy-create-and-deactivate-v2
+++ a/mm/slab.c
@@ -1882,7 +1882,7 @@ __kmem_cache_alias(const char *name, uns
 
 	cachep = find_mergeable(size, align, flags, name, ctor);
 	if (cachep && kmem_cache_tryget(cachep)) {
-		cachep->alias_count++;
+		cachep->shared_count++;
 
 		/*
 		 * Adjust the object sizes so that we clear
diff -puN mm/slab_common.c~mm-fix-race-between-kmem_cache-destroy-create-and-deactivate-v2 mm/slab_common.c
--- a/mm/slab_common.c~mm-fix-race-between-kmem_cache-destroy-create-and-deactivate-v2
+++ a/mm/slab_common.c
@@ -306,7 +306,7 @@ int slab_unmergeable(struct kmem_cache *
 	/*
 	 * We may have set a slab to be unmergeable during bootstrap.
 	 */
-	if (s->alias_count < 0)
+	if (s->shared_count < 0)
 		return 1;
 
 	return 0;
@@ -391,7 +391,7 @@ static struct kmem_cache *create_cache(c
 	if (err)
 		goto out_free_cache;
 
-	s->alias_count = 1;
+	s->shared_count = 1;
 	refcount_set(&s->refcount, 1);
 	list_add(&s->list, &slab_caches);
 	memcg_link_cache(s);
@@ -615,8 +615,13 @@ void memcg_create_kmem_cache(struct mem_
 	/*
 	 * The root cache has been requested to be destroyed while its memcg
 	 * cache was in creation queue.
+	 *
+	 * The shared_count can be out-dated or can be incremented after return.
+	 * No big worries, at worst the creation of memcg kmem_cache is delayed.
+	 * The next allocation will again trigger the memcg kmem_cache creation
+	 * request.
 	 */
-	if (!root_cache->alias_count)
+	if (!root_cache->shared_count)
 		goto out_unlock;
 
 	idx = memcg_cache_id(memcg);
@@ -863,7 +868,7 @@ static void __kmem_cache_destroy(struct
 		mutex_lock(&slab_mutex);
 	}
 
-	VM_BUG_ON(s->alias_count);
+	VM_BUG_ON(s->shared_count);
 
 	err = shutdown_memcg_caches(s);
 	if (!err)
@@ -882,6 +887,14 @@ static void __kmem_cache_destroy(struct
 	}
 }
 
+/*
+ * kmem_cache_tryget - Try to get a reference on a kmem_cache
+ * @s: target kmem_cache
+ *
+ * Obtain a reference on a kmem_cache unless it already has reached zero and is
+ * being released. The caller needs to ensure that kmem_cache is accessible.
+ * Currently only root kmem_cache supports reference counting.
+ */
 bool kmem_cache_tryget(struct kmem_cache *s)
 {
 	if (is_root_cache(s))
@@ -889,6 +902,14 @@ bool kmem_cache_tryget(struct kmem_cache
 	return false;
 }
 
+/*
+ * kmem_cache_put - Put a reference on a kmem_cache
+ * @s: target kmem_cache
+ *
+ * Put a reference obtained via kmem_cache_tryget(). This function can not be
+ * called within slab_mutex as it can trigger a destruction of a kmem_cache
+ * which requires slab_mutex.
+ */
 void kmem_cache_put(struct kmem_cache *s)
 {
 	if (is_root_cache(s) &&
@@ -896,6 +917,16 @@ void kmem_cache_put(struct kmem_cache *s
 		__kmem_cache_destroy(s, true);
 }
 
+/*
+ * kmem_cache_put_locked - Put a reference on a kmem_cache while holding
+ * slab_mutex
+ * @s: target kmem_cache
+ *
+ * Put a reference obtained via kmem_cache_tryget(). Use this function instead
+ * of kmem_cache_put if the caller has already acquired slab_mutex.
+ *
+ * At the moment this function is not exposed externally and is used by SLUB.
+ */
 void kmem_cache_put_locked(struct kmem_cache *s)
 {
 	if (is_root_cache(s) &&
@@ -908,7 +939,14 @@ void kmem_cache_destroy(struct kmem_cach
 	if (unlikely(!s))
 		return;
 
-	s->alias_count--;
+	/*
+	 * It is safe to decrement shared_count without any lock. In
+	 * __kmem_cache_alias the kmem_cache's refcount is elevated before
+	 * incrementing shared_count and below the reference is dropped after
+	 * decrementing shared_count. At worst shared_count can be outdated for
+	 * a small window but that is tolerable.
+	 */
+	s->shared_count--;
 	kmem_cache_put(s);
 }
 EXPORT_SYMBOL(kmem_cache_destroy);
@@ -961,7 +999,7 @@ void __init create_boot_cache(struct kme
 		panic("Creation of kmalloc slab %s size=%u failed. Reason %d\n",
 					name, size, err);
 
-	s->alias_count = -1;	/* Exempt from merging for now */
+	s->shared_count = -1;	/* Exempt from merging for now */
 	refcount_set(&s->refcount, 1);
 }
 
@@ -977,7 +1015,7 @@ struct kmem_cache *__init create_kmalloc
 	create_boot_cache(s, name, size, flags, useroffset, usersize);
 	list_add(&s->list, &slab_caches);
 	memcg_link_cache(s);
-	s->alias_count = 1;
+	s->shared_count = 1;
 	refcount_set(&s->refcount, 1);
 	return s;
 }
diff -puN mm/slab.h~mm-fix-race-between-kmem_cache-destroy-create-and-deactivate-v2 mm/slab.h
--- a/mm/slab.h~mm-fix-race-between-kmem_cache-destroy-create-and-deactivate-v2
+++ a/mm/slab.h
@@ -25,8 +25,8 @@ struct kmem_cache {
 	unsigned int useroffset;/* Usercopy region offset */
 	unsigned int usersize;	/* Usercopy region size */
 	const char *name;	/* Slab name for sysfs */
-	refcount_t refcount;	/* Use counter */
-	int alias_count;
+	refcount_t refcount;	/* Refcount for root kmem cache */
+	int shared_count;	/* Number of kmem caches sharing this cache */
 	void (*ctor)(void *);	/* Called on object slot creation */
 	struct list_head list;	/* List of all slab caches on the system */
 };
diff -puN mm/slub.c~mm-fix-race-between-kmem_cache-destroy-create-and-deactivate-v2 mm/slub.c
--- a/mm/slub.c~mm-fix-race-between-kmem_cache-destroy-create-and-deactivate-v2
+++ a/mm/slub.c
@@ -4232,7 +4232,7 @@ __kmem_cache_alias(const char *name, uns
 
 	s = find_mergeable(size, align, flags, name, ctor);
 	if (s && kmem_cache_tryget(s)) {
-		s->alias_count++;
+		s->shared_count++;
 
 		/*
 		 * Adjust the object sizes so that we clear
@@ -4247,7 +4247,7 @@ __kmem_cache_alias(const char *name, uns
 		}
 
 		if (sysfs_slab_alias(s, name)) {
-			s->alias_count--;
+			s->shared_count--;
 			kmem_cache_put_locked(s);
 			s = NULL;
 		}
@@ -4972,7 +4972,7 @@ SLAB_ATTR_RO(ctor);
 static ssize_t aliases_show(struct kmem_cache *s, char *buf)
 {
 	return sprintf(buf, "%d\n",
-		       s->alias_count < 0 ? 0 : s->alias_count - 1);
+		       s->shared_count < 0 ? 0 : s->shared_count - 1);
 }
 SLAB_ATTR_RO(aliases);
 
@@ -5119,7 +5119,7 @@ static ssize_t trace_store(struct kmem_c
 	 * as well as cause other issues like converting a mergeable
 	 * cache into an umergeable one.
 	 */
-	if (s->alias_count > 1)
+	if (s->shared_count > 1)
 		return -EINVAL;
 
 	s->flags &= ~SLAB_TRACE;
@@ -5237,7 +5237,7 @@ static ssize_t failslab_show(struct kmem
 static ssize_t failslab_store(struct kmem_cache *s, const char *buf,
 							size_t length)
 {
-	if (s->alias_count > 1)
+	if (s->shared_count > 1)
 		return -EINVAL;
 
 	s->flags &= ~SLAB_FAILSLAB;
_

Patches currently in -mm which might be from shakeelb@xxxxxxxxxx are

mm-fix-race-between-kmem_cache-destroy-create-and-deactivate.patch
mm-fix-race-between-kmem_cache-destroy-create-and-deactivate-v3.patch

--
To unsubscribe from this list: send the line "unsubscribe mm-commits" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Kernel Archive]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]

  Powered by Linux