Re: mm: slub: invalid memory access in setup_object

From: Wei Yang
Date: Mon Jun 30 2014 - 21:40:17 EST


On Mon, Jun 30, 2014 at 03:03:21PM -0700, David Rientjes wrote:
>On Wed, 25 Jun 2014, Christoph Lameter wrote:
>
>> On Wed, 25 Jun 2014, Sasha Levin wrote:
>>
>> > [ 791.669480] ? init_object (mm/slub.c:665)
>> > [ 791.669480] setup_object.isra.34 (mm/slub.c:1008 mm/slub.c:1373)
>> > [ 791.669480] new_slab (mm/slub.c:278 mm/slub.c:1412)
>>
>> So we just got a new page from the page allocator but somehow cannot
>> write to it. This is the first write access to the page.
>>
>
>I'd be inclined to think that this was a result of "slub: reduce duplicate
>creation on the first object" from -mm[*] that was added the day before
>Sasha reported the problem.
>
>It's not at all clear to me that that patch is correct. Wei?
>
>Sasha, with a revert of that patch, does this reproduce?
>
> [*] http://ozlabs.org/~akpm/mmotm/broken-out/slub-reduce-duplicate-creation-on-the-first-object.patch

David,

So sad to see the error after applying my patch. In which case this is
triggered? The kernel with this patch runs fine on my laptop. Maybe there is
some corner case I missed? If you could tell me the way you reproduce it, I
would have a try on my side.

I did a simple test for this patch, my test code and result is attached.

1. kmem_cache.c
The test module.
2. kmem_log.txt
In this log, you can see 26 objects are initialized once exactly, while
without this patch, the first object will be initialized twice.

Fetch a cache from kmem_cache
new_slab: page->objects is 26
new_slab: setup on ffff880097038000, ffff8800970384e0
init_once: [00]ffff880097038000 is created
new_slab: setup on ffff8800970384e0, ffff8800970389c0
init_once: [01]ffff8800970384e0 is created
new_slab: setup on ffff8800970389c0, ffff880097038ea0
init_once: [02]ffff8800970389c0 is created
new_slab: setup on ffff880097038ea0, ffff880097039380
init_once: [03]ffff880097038ea0 is created
new_slab: setup on ffff880097039380, ffff880097039860
init_once: [04]ffff880097039380 is created
new_slab: setup on ffff880097039860, ffff880097039d40
init_once: [05]ffff880097039860 is created
new_slab: setup on ffff880097039d40, ffff88009703a220
init_once: [06]ffff880097039d40 is created
new_slab: setup on ffff88009703a220, ffff88009703a700
init_once: [07]ffff88009703a220 is created
new_slab: setup on ffff88009703a700, ffff88009703abe0
init_once: [08]ffff88009703a700 is created
new_slab: setup on ffff88009703abe0, ffff88009703b0c0
init_once: [09]ffff88009703abe0 is created
new_slab: setup on ffff88009703b0c0, ffff88009703b5a0
init_once: [10]ffff88009703b0c0 is created
new_slab: setup on ffff88009703b5a0, ffff88009703ba80
init_once: [11]ffff88009703b5a0 is created
new_slab: setup on ffff88009703ba80, ffff88009703bf60
init_once: [12]ffff88009703ba80 is created
new_slab: setup on ffff88009703bf60, ffff88009703c440
init_once: [13]ffff88009703bf60 is created
new_slab: setup on ffff88009703c440, ffff88009703c920
init_once: [14]ffff88009703c440 is created
new_slab: setup on ffff88009703c920, ffff88009703ce00
init_once: [15]ffff88009703c920 is created
new_slab: setup on ffff88009703ce00, ffff88009703d2e0
init_once: [16]ffff88009703ce00 is created
new_slab: setup on ffff88009703d2e0, ffff88009703d7c0
init_once: [17]ffff88009703d2e0 is created
new_slab: setup on ffff88009703d7c0, ffff88009703dca0
init_once: [18]ffff88009703d7c0 is created
new_slab: setup on ffff88009703dca0, ffff88009703e180
init_once: [19]ffff88009703dca0 is created
new_slab: setup on ffff88009703e180, ffff88009703e660
init_once: [20]ffff88009703e180 is created
new_slab: setup on ffff88009703e660, ffff88009703eb40
init_once: [21]ffff88009703e660 is created
new_slab: setup on ffff88009703eb40, ffff88009703f020
init_once: [22]ffff88009703eb40 is created
new_slab: setup on ffff88009703f020, ffff88009703f500
init_once: [23]ffff88009703f020 is created
new_slab: setup on ffff88009703f500, ffff88009703f9e0
init_once: [24]ffff88009703f500 is created
new_slab: do it again? ffff88009703f9e0
init_once: [25]ffff88009703f9e0 is created

--
Richard Yang
Help you, Help me
/*
* =====================================================================================
*
* Filename: kmem_cache.c
*
* Description: /proc/slabinfo
*
* Version: 1.0
* Created: 04/26/2014 09:12:04 PM
* Revision: none
* Compiler: gcc
*
* Author: Wei Yang (weiyang), weiyang.kernel@xxxxxxxxx
* Company:
*
* =====================================================================================
*/

#include <linux/init.h>
#include <linux/module.h>
#include <linux/slab.h>
MODULE_LICENSE("Dual BSD/GPL");

static struct kmem_cache *test_cache;
void *tmp;

static void init_once(void *foo)
{
static int num;
printk(KERN_ERR "%s: [%02d]%p is created\n", __func__, num++, foo);
}

static int kmem_cache_test_init(void)
{
test_cache = kmem_cache_create("test_cache", 1234, 4,
0, init_once);
if (test_cache == NULL)
return -ENOMEM;

printk(KERN_ERR "Fetch a cache from kmem_cache\n", __func__);
tmp = kmem_cache_zalloc(test_cache, GFP_KERNEL);

return 0;
}
static void kmem_cache_test_exit(void)
{
kmem_cache_free(test_cache, tmp);
kmem_cache_destroy(test_cache);
}
module_init(kmem_cache_test_init);
module_exit(kmem_cache_test_exit);