Discussion:
[uClinux-dev] v3.15-rc1 slab allocator broken on m68knommu (coldfire)
Steven King
2014-04-15 00:45:43 UTC
Permalink
git bisect suggests it starts somewhere around commit
f315e3fa1cf5b3317fc948708645fff889ce1e63 slab: restrict the number of objects
in a slab

but its kinda hard to tell as there is some compile breakage in there as well.

slub and slob seem to still work okay for m68knommu.
Steven King
2014-04-16 15:47:27 UTC
Permalink
Post by Steven King
git bisect suggests it starts somewhere around commit
f315e3fa1cf5b3317fc948708645fff889ce1e63 slab: restrict the number of
objects in a slab
but its kinda hard to tell as there is some compile breakage in there as well.
Hello, Steven.
Hmm... there is the fix on upstream v3.15-rc1 for build breakage.
See commit 24f870d('slab: fix wrongly used macro').
If slab allocator broken with this fix, please let me know.
Thanks.
Yes, 24f870d fixes the build breakage but the allocator is still broken (board
doesn't boot). However, I was able to track down the exact changes that seem
to break things; in 8dcc774 'slab: introduce byte sized index for the freelist of a slab'
there are the changes to get_free_obj and set_free_obj:

-static inline unsigned int get_free_obj(struct page *page, unsigned int idx)
+static inline freelist_idx_t get_free_obj(struct page *page, unsigned char idx)
{
- return ((unsigned int *)page->freelist)[idx];
+ return ((freelist_idx_t *)page->freelist)[idx];
}

static inline void set_free_obj(struct page *page,
- unsigned int idx, unsigned int val)
+ unsigned char idx, freelist_idx_t val)
{
- ((unsigned int *)(page->freelist))[idx] = val;
+ ((freelist_idx_t *)(page->freelist))[idx] = val;
}

if I change idx back to unsigned int, ie:

diff --git a/mm/slab.c b/mm/slab.c
index 388cb1a..d7f9f44 100644
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -2572,13 +2572,13 @@ static void *alloc_slabmgmt(struct kmem_cache *cachep,
return freelist;
}

-static inline freelist_idx_t get_free_obj(struct page *page, unsigned char idx)
+static inline freelist_idx_t get_free_obj(struct page *page, unsigned int idx)
{
return ((freelist_idx_t *)page->freelist)[idx];
}

static inline void set_free_obj(struct page *page,
- unsigned char idx, freelist_idx_t val)
+ unsigned int idx, freelist_idx_t val)
{
((freelist_idx_t *)(page->freelist))[idx] = val;
}


then v3.15-rc1 will boot using the slab allocator.
Geert Uytterhoeven
2014-04-16 16:06:57 UTC
Permalink
Hi Steven,
Post by Steven King
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -2572,13 +2572,13 @@ static void *alloc_slabmgmt(struct kmem_cache *cachep,
return freelist;
}
-static inline freelist_idx_t get_free_obj(struct page *page, unsigned char idx)
+static inline freelist_idx_t get_free_obj(struct page *page, unsigned int idx)
{
return ((freelist_idx_t *)page->freelist)[idx];
}
static inline void set_free_obj(struct page *page,
- unsigned char idx, freelist_idx_t val)
+ unsigned int idx, freelist_idx_t val)
{
((freelist_idx_t *)(page->freelist))[idx] = val;
}
then v3.15-rc1 will boot using the slab allocator.
Is "idx" ever larger than 255?

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
Steven King
2014-04-16 17:44:11 UTC
Permalink
Post by Geert Uytterhoeven
Hi Steven,
Post by Steven King
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -2572,13 +2572,13 @@ static void *alloc_slabmgmt(struct kmem_cache
*cachep, return freelist;
}
-static inline freelist_idx_t get_free_obj(struct page *page, unsigned
char idx) +static inline freelist_idx_t get_free_obj(struct page *page,
unsigned int idx) {
return ((freelist_idx_t *)page->freelist)[idx];
}
static inline void set_free_obj(struct page *page,
- unsigned char idx, freelist_idx_t
val) + unsigned int idx,
freelist_idx_t val) {
((freelist_idx_t *)(page->freelist))[idx] = val;
}
then v3.15-rc1 will boot using the slab allocator.
Is "idx" ever larger than 255?
Gr{oetje,eeting}s,
Yes. If I stick

if (idx > 255)
pr_info("%s %d\n", __func__, idx);

in get_free_obj and set_free_obj and see values for idx up into the 400s.
Loading...