In my kernel module, firstly I wrote:
int alloc_device(const char *name, int number)
{
char name[64];
snprintf(name, sizeof(name), "worker%d", number);
request_cache = kmem_cache_create(name, SECTOR_SIZE, 0, NULL, NULL);
......
}
In centos 7, this module works fine, but after port to centos 6, this kernel module reports:
kmem_cache_create: duplicate cache worker0 ......
The key to this problme is in the implementation of kmem_cache_create() in 2.6.32 linux kernel (for centos 6):
struct kmem_cache *
kmem_cache_create (const char *name, size_t size, size_t align,
unsigned long flags, void (*ctor)(void *))
{
......
cachep->ctor = ctor;
cachep->name = name;
......
After creating a new pool, it only point to ‘name’, not strdup() a new one. But the ‘name’ in my kernel module is a temporary variable (in stack), so it considers the name is “duplicated”.
The correct code should like:
static char *names[64];
/* before calling alloc_device() */
names = kcalloc(NR_OF_DEVICE, 64, GFP_KERNEL);
......
int alloc_device(const char *name, int number)
{
snprintf(names[number], 64, "worker%d", number);
request_cache = kmem_cache_create(names[number], SECTOR_SIZE, 0, NULL, NULL);
......
}
But why the old kernel module did not report error in centos 7? Because in centos 7 the default memory allocator is SLUB, and in centos 6 it is SLAB. They have totally different implementation.