我已经完成任务,但我已尽力而为,但无论我尝试什么,我都无法获得最合适的方案。以下是代码。为了实现最佳匹配,我对slob_page_alloc
函数进行了更改。代码如下:
static void *slob_page_alloc(struct page *sp, size_t size, int align)
{
slob_t *prev, *cur, *aligned = NULL, *best_fit=NULL;
/* See SLOB_UNITS defination for meaning of macro. units is required
* number OF units.*/
int delta = 0, units = SLOB_UNITS(size);
unsigned long frag_size = -1UL;
/*Iterate throught the whole page to find best fit*/
//printk("Before the for loop\n");
printk("Starting slob_page_alloc execution\t");
for(prev=NULL, cur=sp->freelist; ; prev=cur, cur=slob_next(cur)) {
slobidx_t avail = slob_units(cur);
if(align) {
aligned = (slob_t *)ALIGN((unsigned long)cur, align);
delta = aligned - cur;
}
if(avail >= delta+units) {
if( frag_size > avail-units ) {
frag_size = avail-units;
best_fit = cur;
}
}
if(slob_last(cur))
break;
}
//printk("after the for loop.\n");
if(best_fit) {
slobidx_t avail = slob_units(best_fit);
//printk("best fit found\n");
if (align) {
aligned = (slob_t *)ALIGN((unsigned long)best_fit, align);
delta = aligned - best_fit;
}
if (avail >= units + delta) { /* room enough? */
slob_t *next;
if (delta) { /* need to fragment head to align? */
next = slob_next(best_fit);
/*Update the newly fragmented slob*/
set_slob(aligned, avail - delta, next);
/* Update the lod slob about reduced size
* and new next slob*/
set_slob(best_fit, delta, aligned);
prev = best_fit;
best_fit = aligned;
avail = slob_units(best_fit);
}
next = slob_next(best_fit);
if (avail == units) { /* exact fit? unlink. */
if (prev)
set_slob(prev, slob_units(prev), next);
else
sp->freelist = next;
} else { /* fragment */
if (prev)
set_slob(prev, slob_units(prev), best_fit + units);
else
sp->freelist = best_fit + units;
set_slob(best_fit + units, avail - units, next);
}
sp->units -= units;
if (!sp->units)
clear_slob_page_free(sp);
printk("Returned from slob_page_alloc\t");
return best_fit;
}
}
printk("Returned from slob_page_alloc\t");
return NULL;
}
当我使用这种方案配置内核时,它只是挂在某个地方。
的调试: 的
我已在此功能的某个地方以及slob_alloc
功能中进行了打印。虽然它对我没有任何意义,但我的函数被多次调用并成功返回,然后再次被调用并返回等等。但是有一次它被调用打印出这个函数中的语句,但是不会打印来自被调用者的语句而只是无限期地挂起它。
任何帮助表示赞赏!! 感谢。
答案 0 :(得分:4)
我认为这里没有足够的代码来弄清楚什么是错的(也许在lxr.oss.org.cn/source/mm/slob.c,但我没有检查)。但这就是我猜你的问题:
不知何故,你在链表中得到一个循环(或'循环'),所以你对slob_last(cur)的调用永远不会返回true。 (你的代码确实到达了那一行;没有任何事情,没有一个段错误,这将阻止它。)我添加了一个调试函数,它将扫描列表以查看它是否终止或有一个循环,并打印出来如果有循环的消息。然后我在你的函数中添加了对该函数的调用。如果你还没有听说过鲍勃弗洛伊德的宠物乌龟和野兔之前,谷歌为鲍勃弗洛伊德和链表循环检测(或链表循环检测)。我没有在下面测试我的代码,但我认为我编码正确。如果它检测到循环,那么查看将slob_t添加到列表中的逻辑,并查看将它们从列表中删除的代码。必须有一些条件,它要么不正确地添加一些东西,要么不正确地从列表中取出一些东西。如果你在这里找到一个循环,请在其他位置之前添加其他呼叫...在您修改列表的代码中的每个点之后立即...这样您可以缩小代码的哪个部分导致循环。
static void slob_debug_detect_loop(slob_t *list_head, const char* debug_location)
{
// Bob Floyd's pet tortoise & hare, both born in 1967...
slot_t *hare = list_head;
slob_t *tortoise = list_head;
int tortoise_pacer=0;
while (!slob_last(hare))
{
hare = slob_next(hare);
if (++tortoise_pacer&1)
tortoise = slob_next(tortoise);
if (tortoise_pacer>2 && hare==tortoise)
{
printk("LINKED LIST LOOP DETECTED at %s!\n", debug_location);
return;
}
}
}
static void *slob_page_alloc(struct page *sp, size_t size, int align)
{
slob_t *prev, *cur, *aligned = NULL, *best_fit=NULL;
/* See SLOB_UNITS defination for meaning of macro. units is required
* number OF units.*/
int delta = 0, units = SLOB_UNITS(size);
unsigned long frag_size = -1UL;
/*Iterate throught the whole page to find best fit*/
//printk("Before the for loop\n");
printk("Starting slob_page_alloc execution\t");
slob_debug_detect_loop(sp->freelist, "before best-fit detection loop"); // ++++++++++
for(prev=NULL, cur=sp->freelist; ; prev=cur, cur=slob_next(cur)) {
slobidx_t avail = slob_units(cur);
if(align) {
aligned = (slob_t *)ALIGN((unsigned long)cur, align);
delta = aligned - cur;
}
if(avail >= delta+units) {
if( frag_size > avail-units ) {
frag_size = avail-units;
best_fit = cur;
}
}
if(slob_last(cur))
break;
}
.
.
.
答案 1 :(得分:2)
问题是prev指针是错误的,因为你没有 当你找到best_fit但打破了slob_last(cur)时休息。 best_fit指针是最后一个best_fit,但prev是最后一个。
稍后在代码列表中修改了假设prev 是best_fit的热门词条。当列表搞乱时,你会得到一个无限循环。