----- Original Message ----- > Dave Anderson <anderson@xxxxxxxxxx> writes: > > >> I see what you say. However, my usual usage of kmem is to get the data > >> address of object (I was thinking the most users are same usage). > >> > >> crash> kmem <pointer in stack> > >> info for data address > >> > >> copy & paste <data address> > >> crash> p *(struct inode *)<data address> > > > > Why not copy-and-paste the address from <pointer in stack>? Or use "bt > > -FF" > > to get the kmem cache type, and skip using "kmem" entirely? ;-) > > Yes, bt -FF helps much. However, the pointer in stack is address in > middle of object data in many times. > > E.g. for ext4_inode_cache, "struct address_space *" is in stack. But > actual slab object is inode->i_mapping == ext4_inode_info.vfs_inode.i_data. > Or functions takes member of object, e.g., &object->list. for (p = vaddr; p < vaddr + objects * si->size; p += si->size) { hq_open(); is_free = FALSE; /* Search an object on both of freelist and cpu_freelist */ ulong lists[] = { freelist, cpu_freelist, }; for (i = 0; i < sizeof(lists) / sizeof(lists[0]); i++) { for (is_free = 0, q = lists[i]; q; q = get_freepointer(si, (void *)q)) { if (q == BADADDR) { hq_close(); return FALSE; } if (q & PAGE_MAPPING_ANON) break; if (p == q) { is_free = TRUE; goto found_object; } if (!hq_enter(q)) { hq_close(); error(INFO, "%s: slab: %lx duplicate freelist object: %lx\n", si->curname, si->slab, q); return FALSE; } } } found_object: > > If there is easy way to get the object address from the field of object > address, it would be what I want. OK, I understand. Let me work on a new "set redzone on/off" environment variable that can be toggled on-and-off during runtime. But I believe I see a problem in do_slab_slub(). When it is checking for free objects to display as FREE / [ALLOCATED], it will never find it in 4.6+ kernels with a red_left_pad. Note below, when it checks whether (p == q), the "q" address is the "shifted" address seen by the kmalloc() caller, and will never match the base object address "p", so "is_free" never gets set: for (p = vaddr; p < vaddr + objects * si->size; p += si->size) { hq_open(); is_free = FALSE; /* Search an object on both of freelist and cpu_freelist */ ulong lists[] = { freelist, cpu_freelist, }; for (i = 0; i < sizeof(lists) / sizeof(lists[0]); i++) { for (is_free = 0, q = lists[i]; q; q = get_freepointer(si, (void *)q)) { if (q == BADADDR) { hq_close(); return FALSE; } if (q & PAGE_MAPPING_ANON) break; === never can match ===> if (p == q) { is_free = TRUE; goto found_object; } if (!hq_enter(q)) { hq_close(); error(INFO, "%s: slab: %lx duplicate freelist object: %lx\n", si->curname, si->slab, q); return FALSE; } } } found_object: ... Do you agree? Dave -- Crash-utility mailing list Crash-utility@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/crash-utility