An asynchronous function call infrastructure Feb 1, 2009

http://lwn.net/Articles/314808/

2.6.29-rc3가 몇일전 release되었지만 이제서야 2.6.29-rc1에 들어간 기능을 review한다.
그 동안 some bug를 digging 하느라 정신이 없었다. 사실 아직도 debugging 중이다.

kernel compile을 하는 동안 LWN 기사를 하나 review한다.

Intel의 Arjan이 시도하는 fastboot project의 일부이다.
Fastboot은 많은 사람들이 관심을 가지고 있는 주제중의 하나이며, 그 동안 많은 시도들이 있었다.
특히 embedded guy들이 많은 관심을 가지고 있던 주제중의 하나이다.
하지만 Arjan은 embedded가 아닌 desktop을 위해 Fastboot을 진행중이다. 물론 몇몇 기술들은
embedded에도 유용할 것이다. 하지만 오늘 소개하는 이 patch는 embedded와는 별로 관계가 없다.

사실, device probing을 parallel하게 하자는 시도는 예전부터 있어왔었다. 하지만 device ordering,
concurrent access등과 같은 문제들로 인하여 system stability의 문제가 있어 general하게
적용되지 못해왔다.

이 문제를 Arjan은 모든 device들을 한번에 해결하려는 시도보다는 libata subsystem과 SCSI로 국한하여
parallel probing을 시도하였으며(그래서 barrios는 embedded와는 현재로선 거리가 멀다고 얘기한 것이다. 하지만 이 비동기 framework 자체는 fastboot뿐만이 아니라 여러면에서 도움이 될 것으로 생각된다.), API를 잘 추상화하여 나머지 subsystem들은 아무 영향을 받지 않도록 설계하였다.

실제 동작 원리는 복잡하지 않다. 비동기 함수를 관리하는 async_pending list와 async_running list를 두어,
비동기 함수의 실행을 요청하는 async_schedule을 호춢하게 되면 callback function을 async_pending list에 넣고, 그 함수를 실행시키기 위해 async_manager_thread를 깨우게 된다. async_manager_thread는 새로운 async_thread를 생성하여 pending list에 있는 비동기 함수를 실행하게 된다. async_thread는 1초 async_pending list에 pending된 비동기 함수들이 없을 경우 스스로 소멸되게 된다.
또한, 한꺼번에 많은 비동기 함수들의 요청이 들어올 경우, kernel thread는 갑자기 많아 질 수 있다.
현재는 kernel thread를 MAX_THREAD(256)개로 제한하고 있다.


static async_cookie_t __async_schedule(async_func_ptr *ptr, void *data, struct list_head *running)
{
struct async_entry *entry;
unsigned long flags;
async_cookie_t newcookie;


/* allow irq-off callers */
entry = kzalloc(sizeof(struct async_entry), GFP_ATOMIC);

/*
* If we're out of memory or if there's too much work
* pending already, we execute synchronously.
*/
if (!async_enabled || !entry || atomic_read(&entry_count) > MAX_WORK) {
kfree(entry);
spin_lock_irqsave(&async_lock, flags);
newcookie = next_cookie++;
spin_unlock_irqrestore(&async_lock, flags);

/* low on memory.. run synchronously */
ptr(data, newcookie);
return newcookie;
}
entry->func = ptr;
entry->data = data;
entry->running = running;

spin_lock_irqsave(&async_lock, flags);
newcookie = entry->cookie = next_cookie++;
list_add_tail(&entry->list, &async_pending);
atomic_inc(&entry_count);
spin_unlock_irqrestore(&async_lock, flags);
wake_up(&async_new);
return newcookie;
}



하지만 아직까지 이 patch는 많은 문제를 가지고 있는 것 같다. 2.6.29-rc1에 들어가자마자 많은 문제들이 보고되기 시작했으며, 현재 Arjan은 Linus에게 이 기능을 disable 시켜달라고 요청한 상태이다.

이번주 LWN의 기사가 다시한번 이 주제를 다루고 있기 때문에, 몇일 뒤 무료로 기사를 볼 수 있게 될 경우, 이 문제가 어떻게 풀려나가고 있는지 다시한번 review를 하도록 하자.

0 개의 덧글: