debug时,经常会需要打印slub的前一项(内存被前一个slub向后被踩),这里提供一个简单的例子,可以打印当前slub信息,并且返回前一个slub信息,重复调用可以不停的打印slub信息。
static void *_find_prev_slab_and_print_slub(phys_addr_t pa_addr) { void * va = _va(pa_addr); struct kmem_cache *slab_kmem_cache = NULL; struct page *page = phys_to_page(pa_addr); struct page *compound_page = compound_head(page); void *slub_info = NULL; void *s; if (pa_addr == NULL && va == NULL && compound_page == NULL) { return NULL; } //TODO: EXPORT_SYMBOL(print_page_info) print_page_info(compound_page); if (PageSlab(compound_page) && (slab_kmem_cache = compound_page->slab_cache)) { slub_info = nearest_obj(slab_kmem_cache, compound_page, va); pr_info("slub_info=%px, from slab %s(%x)\n", slub_info, cache_name(slab_kmem_cache), slab_kmem_cache->size); if (bit_spin_trylock(PG_locked, &compound_page->flags)) { for (s = compound_page->freelist; s != NULL; s = get_freepointer(slab_kmem_cache, s)); if (s == slub_info) pr_info("slub_info %px be free.\n", slub_info); else pr_info("slub_info %px don't free.\n", slub_info); bit_spin_unlock(PG_locked, &compound_page->flags); } else pr_info("slub_info %px don't free.\n", slub_info); //TODO: EXPORT_SYMBOL(print_tracking) if (slab_kmem_cache->flag & SLAB_STORE_USER) print_tracking(slab_kmem_cache, slub_info); } //prev slab info return _pa(slub_info - slab_kmem_cache->size); }