patch-2.2.18 linux/mm/slab.c

Next file: linux/mm/swapfile.c
Previous file: linux/mm/mmap.c
Back to the patch index
Back to the overall index

diff -u --new-file --recursive --exclude-from /usr/src/exclude v2.2.17/mm/slab.c linux/mm/slab.c
@@ -987,8 +987,8 @@
  * is available.  To help debugging, a zero exit status indicates all slabs
  * were released.
  */
-int
-kmem_cache_shrink(kmem_cache_t *cachep)
+
+static int __kmem_cache_shrink(kmem_cache_t *cachep, int validated)
 {
 	kmem_cache_t	*searchp;
 	kmem_slab_t	*slabp;
@@ -1003,26 +1003,29 @@
 		return 2;
 	}
 
-	/* Find the cache in the chain of caches. */
-	down(&cache_chain_sem);		/* Semaphore is needed. */
-	searchp = &cache_cache;
-	for (;searchp->c_nextp != &cache_cache; searchp = searchp->c_nextp) {
-		if (searchp->c_nextp != cachep)
-			continue;
+	if(validated==0)
+	{
+		/* Find the cache in the chain of caches. */
+		down(&cache_chain_sem);		/* Semaphore is needed. */
+		searchp = &cache_cache;
+		for (;searchp->c_nextp != &cache_cache; searchp = searchp->c_nextp) {
+			if (searchp->c_nextp != cachep)
+				continue;
 
-		/* Accessing clock_searchp is safe - we hold the mutex. */
-		if (cachep == clock_searchp)
-			clock_searchp = cachep->c_nextp;
-		goto found;
-	}
-	up(&cache_chain_sem);
-	printk(KERN_ERR "kmem_shrink: Invalid cache addr %p\n", cachep);
-	return 2;
+			/* Accessing clock_searchp is safe - we hold the mutex. */
+			if (cachep == clock_searchp)
+				clock_searchp = cachep->c_nextp;
+			goto found;
+		}
+		up(&cache_chain_sem);
+		printk(KERN_ERR "kmem_shrink: Invalid cache addr %p\n", cachep);
+		return 2;
 found:
-	/* Release the semaphore before getting the cache-lock.  This could
-	 * mean multiple engines are shrinking the cache, but so what.
-	 */
-	up(&cache_chain_sem);
+		/* Release the semaphore before getting the cache-lock.  This could
+		 * mean multiple engines are shrinking the cache, but so what.
+		 */
+		up(&cache_chain_sem);
+	}
 	spin_lock_irq(&cachep->c_spinlock);
 
 	/* If the cache is growing, stop shrinking. */
@@ -1040,6 +1043,71 @@
 		ret--;		/* Cache is empty. */
 	spin_unlock_irq(&cachep->c_spinlock);
 	return ret;
+}
+
+int kmem_cache_shrink(kmem_cache_t *cachep)
+{
+	return __kmem_cache_shrink(cachep,0);
+}
+
+/*
+ * Remove a kmem_cache_t object from the slab cache. When returns 0 it
+ * completed succesfully. -arca
+ */
+int kmem_cache_destroy(kmem_cache_t * cachep)
+{
+	kmem_cache_t * prev;
+	int ret;
+
+	if (!cachep) {
+		printk(KERN_ERR "kmem_destroy: NULL ptr\n");
+		return 1;
+	}
+	if (in_interrupt()) {
+		printk(KERN_ERR "kmem_destroy: Called during int - %s\n",
+		       cachep->c_name);
+		return 1;
+	}
+
+	ret = 0;
+	/* Find the cache in the chain of caches. */
+	down(&cache_chain_sem);
+	for (prev = &cache_cache; prev->c_nextp != &cache_cache;
+	     prev = prev->c_nextp) {
+		if (prev->c_nextp != cachep)
+			continue;
+
+		/* Accessing clock_searchp is safe - we hold the mutex. */
+		if (cachep == clock_searchp)
+			clock_searchp = cachep->c_nextp;
+
+		/* remove the cachep from the cache_cache list. -arca */
+		prev->c_nextp = cachep->c_nextp;
+
+		ret = 1;
+		break;
+	}
+	up(&cache_chain_sem);
+
+	if (!ret) {
+		printk(KERN_ERR "kmem_destroy: Invalid cache addr %p\n",
+		       cachep);
+		return 1;
+	}
+
+	if (__kmem_cache_shrink(cachep, 1)) {
+		printk(KERN_ERR "kmem_destroy: Can't free all objects %p\n",
+		       cachep);
+		down(&cache_chain_sem);
+		cachep->c_nextp = cache_cache.c_nextp;
+		cache_cache.c_nextp = cachep;
+		up(&cache_chain_sem);
+		return 1;
+	}
+
+	kmem_cache_free(&cache_cache, cachep);
+
+	return 0;
 }
 
 /* Get the memory for a slab management obj. */

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)