[완료] 커널 타이머 이용시 커널 패닉 문제입니다.
글쓴이: nyxanox / 작성시간: 월, 2009/08/31 - 5:51오후
안녕하세요.
막힐때 마다 KLDP를 찾게 되네요.
커널 모듈을 개발하는 중에 타이머를 생성하여 일정 시간 간격으로 함수를 호출 하도록 하였는데
모듈을 올리고 동작하는데는 문제가 발생하지 않았는데,
모듈을 내리면(rmmod) 얼마 후에 커널이 패닉 상태에 빠져버리는 것을 확인 할 수 있었습니다.
어떻게 하면 해결이 될까요?
아래와 같이 모듈의 init 부분에서 타이머를 생성하고, 실행하였습니다.
int __init my_module_init(void) { dev_add_pack(&packet_type); init_timer(&timer); timer.function = kerneltimer_handler; timer.expires = jiffies + HZ; add_timer(&timer); printk( KERN_ALERT "module init\n" ); return 0; }
그리고 타이머에 등록된 함수는 다음과 같습니다.
#define TIME_STEP (5*HZ) void kerneltimer_handler(unsigned long arg) { schedule_work(&send_work); mod_timer(&timer, jiffies + TIME_STEP); }
워크 스케쥴에 등록한 동작은 다음과 같습니다.
static DECLARE_WORK(send_work, send);
send 함수는 다음과 같습니다.
static void send(struct work_struct *work) { int type; int ptype; struct net_device *dev; struct sk_buff *skb; type = MY_PACKET_SEND; ptype = ETH_P_XX; dev = dev_get_by_name(&init_net, "eth0"); skb = create(type, ptype, dev); if (skb == NULL) { printk( KERN_ALERT "skb is NULL\n"); return; } avb_as_xmit(skb); }
마지막으로 모듈이 종료될 때 타이머를 삭제합니다.
void __exit my_module_exit(void) { del_timer_sync(&timer); printk( KERN_ALERT "module exit\n" ); }
위와 같이 코딩하면, 처음 모듈이 init된 후 1초 후에 타이머가 동작하면서 send 함수를 호출 하며
다시 send 함수가 호출 되는 주기는 5초가 됩니다.
그런데 왜 insmod 할때와 모듈 동작 중에는 아무런 증상이 일어 나지 않다가, rmmod만 하면 몇초 뒤에
커널이 죽는지 모르겠습니다.
도와주세요 ㅠㅠ
Forums:
work 가 queue 에
work 가 queue 에 남아있는 상태라면 keventd([events/N]) 커널쓰레드가 패닉을 일으킵니다.
cancel_work_sync()
send_work 가 가벼워 보이지는 않는데... work queue 를 독립적으로 만드시는 게 좋을 듯 합니다.
keventd(events/N) 커널쓰레가 제공하는 work queue 는 이놈저놈 다 쓰기 때문에,
대기표 받아서 좀 기다려야 되는 경우가 많고, 중간에 시간 오래걸리는 work 가 있다면 그 뒤론 줄줄이 교통정체가 됩니다.
2.6 커널에선 간단히 work queue 를 만들 수 있습니다.
__create_workqueue() 라는 함수와 create_workqueue() 시리즈 매크로, destroy_workqueue() 함수가 있습니다.
OTL
앗 감사합니다!
앗 감사합니다!
그런 방법이 있었군요... 점점 심오해 집니다;;
근데 앞에 올렸던 질문에서 타이머는 패닉에 빠지는 원인이 아니었었습니다. ㅠㅠ
제가 다른 곳에서 release 해 주는 것을 잊어서 그렇게 되었네요 ㅎㅎ
타이머가 문제인 줄 알고 고민 했었는데... 다른 곳이었다니 ㅠㅠ OTL 입니다 ㅎ
그리고 알려주신 방법은 잘 활용해 보도록 하겠습니다. 감사합니다~
Good luck, dandy kang!
댓글 달기