全部博文(2005)
分类: LINUX
2012-12-19 10:57:47
解决方法:
static inline struct slab *page_get_slab(struct page *page)
{
BUG_ON(!PageSlab(page));
return (struct slab *)page->lru.prev;
}
PageSlab()函数的宏定义位于
__PAGEFLAG(Slab, slab)
#define TESTPAGEFLAG(uname, lname) \
static inline int Page##uname(struct page *page) \
{ return test_bit(PG_##lname, &page->flags); }
#define __PAGEFLAG(uname, lname) TESTPAGEFLAG(uname, lname) \
__SETPAGEFLAG(uname, lname) __CLEARPAGEFLAG(uname, lname)
这样可知定义了PageSlab函数原型为:
static inline int PageSlab(struct page *page)
{
return test_bit(PG_slab, &page->flags);
}
因为slab分配器中使用的页面都会加上PG_slab标志,以跟一般页面的区别。在释放内存的时候,经常需要用到从页面到slab的对应转换关系。而
page_get_slab()函数在释放内存的时候经常会被引用到,这样可以定位应该是skb内存块释放出了问题,没敢怀疑标准内核代码,仔细阅读驱动
发现了如下代码:
status = gmac_set_tx_qptr(gmacdev, dma_addr, skb->len, (u64)skb,0,0,0,offload_needed);
if(status < 0){
TR0("%s No More Free Tx Descriptors\n",__FUNCTION__);
// dev_kfree_skb (skb); //出错的根源。
dev_kfree_skb (skb); // 修改后的代码
netif_stop_queue(netdev);
local_irq_restore(flags);
return -EBUSY;
}
http://blog.csdn.net/swq1982/article/details/8064716