[PATCH] dm-bufio: fix warnings about duplicate slab caches

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

 



Hi

I submit this upstream patch for the stable branches 6.6 and 6.11.

Matthew Sakai from the DM-VDO team found out that there is a very narrow 
race condition in the slub sysfs code and it could cause crashes if caches 
with the same name are rapidly created and deleted. In order to work 
around these crashes, we need to have unique slab cache names.

Mikulas



commit 42964e4b5e3ac95090bdd23ed7da2a941ccd902c
Author: Mikulas Patocka <mpatocka@xxxxxxxxxx>
Date:   Mon Nov 11 16:48:18 2024 +0100

    dm-bufio: fix warnings about duplicate slab caches
    
    The commit 4c39529663b9 adds a warning about duplicate cache names if
    CONFIG_DEBUG_VM is selected. These warnings are triggered by the dm-bufio
    code. The dm-bufio code allocates a slab cache with each client. It is
    not possible to preallocate the caches in the module init function
    because the size of auxiliary per-buffer data is not known at this point.
    
    So, this commit changes dm-bufio so that it appends a unique atomic value
    to the cache name, to avoid the warnings.
    
    Signed-off-by: Mikulas Patocka <mpatocka@xxxxxxxxxx>
    Fixes: 4c39529663b9 ("slab: Warn on duplicate cache names when DEBUG_VM=y")

diff --git a/drivers/md/dm-bufio.c b/drivers/md/dm-bufio.c
index d478aafa02c9..23e0b71b991e 100644
--- a/drivers/md/dm-bufio.c
+++ b/drivers/md/dm-bufio.c
@@ -2471,7 +2471,8 @@ struct dm_bufio_client *dm_bufio_client_create(struct block_device *bdev, unsign
 	int r;
 	unsigned int num_locks;
 	struct dm_bufio_client *c;
-	char slab_name[27];
+	char slab_name[64];
+	static atomic_t seqno = ATOMIC_INIT(0);
 
 	if (!block_size || block_size & ((1 << SECTOR_SHIFT) - 1)) {
 		DMERR("%s: block size not specified or is not multiple of 512b", __func__);
@@ -2522,7 +2523,8 @@ struct dm_bufio_client *dm_bufio_client_create(struct block_device *bdev, unsign
 	    (block_size < PAGE_SIZE || !is_power_of_2(block_size))) {
 		unsigned int align = min(1U << __ffs(block_size), (unsigned int)PAGE_SIZE);
 
-		snprintf(slab_name, sizeof(slab_name), "dm_bufio_cache-%u", block_size);
+		snprintf(slab_name, sizeof(slab_name), "dm_bufio_cache-%u-%u",
+					block_size, atomic_inc_return(&seqno));
 		c->slab_cache = kmem_cache_create(slab_name, block_size, align,
 						  SLAB_RECLAIM_ACCOUNT, NULL);
 		if (!c->slab_cache) {
@@ -2531,9 +2533,11 @@ struct dm_bufio_client *dm_bufio_client_create(struct block_device *bdev, unsign
 		}
 	}
 	if (aux_size)
-		snprintf(slab_name, sizeof(slab_name), "dm_bufio_buffer-%u", aux_size);
+		snprintf(slab_name, sizeof(slab_name), "dm_bufio_buffer-%u-%u",
+					aux_size, atomic_inc_return(&seqno));
 	else
-		snprintf(slab_name, sizeof(slab_name), "dm_bufio_buffer");
+		snprintf(slab_name, sizeof(slab_name), "dm_bufio_buffer-%u",
+					atomic_inc_return(&seqno));
 	c->slab_buffer = kmem_cache_create(slab_name, sizeof(struct dm_buffer) + aux_size,
 					   0, SLAB_RECLAIM_ACCOUNT, NULL);
 	if (!c->slab_buffer) {





[Index of Archives]     [Linux Kernel]     [Kernel Development Newbies]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Hiking]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux