1.
任何时刻只有一个CPU在运行tasklet的处理函数。
在哪个cpu上激活的,就在哪个cpu上运行tasklet的处理函数。
tasklet api:
1. 初始化(init)
515 void tasklet_init(struct tasklet_struct *t,
516 void (*func)(unsigned long), unsigned long data)
2. 激活(raise)
561 static inline void tasklet_schedule(struct tasklet_struct *t)
-
515 void tasklet_init(struct tasklet_struct *t,
-
516 void (*func)(unsigned long), unsigned long data)
-
517 {
-
518 t->next = NULL;
-
519 t->state = 0;
-
520 atomic_set(&t->count, 0);
-
521 t->func = func;
-
522 t->data = data;
-
523 }
-
561 static inline void tasklet_schedule(struct tasklet_struct *t)
-
562 {
-
563 if (!test_and_set_bit(TASKLET_STATE_SCHED, &t->state))
-
564 __tasklet_schedule(t);
-
565 }
-
566
-
514
-
515 struct tasklet_struct
-
516 {
-
517 struct tasklet_struct *next;
-
518 unsigned long state;
-
519 atomic_t count;
-
520 void (*func)(unsigned long);
-
521 unsigned long data;
-
522 };
-
523
-
402 static DEFINE_PER_CPU(struct tasklet_head, tasklet_vec);
-
403 static DEFINE_PER_CPU(struct tasklet_head, tasklet_hi_vec);
-
393 /*
-
394 * Tasklets
-
395 */
-
396 struct tasklet_head
-
397 {
-
398 struct tasklet_struct *head;
-
399 struct tasklet_struct **tail;
-
400 };
-
401
-
561 static inline void tasklet_schedule(struct tasklet_struct *t)
-
562 {
-
563 if (!test_and_set_bit(TASKLET_STATE_SCHED, &t->state))
-
564 __tasklet_schedule(t);
-
565 }
-
566
-
405 void __tasklet_schedule(struct tasklet_struct *t)
-
406 {
-
407 unsigned long flags;
-
408
-
409 local_irq_save(flags);
-
410 t->next = NULL;
-
411 *__this_cpu_read(tasklet_vec.tail) = t;
-
412 __this_cpu_write(tasklet_vec.tail, &(t->next));
-
413 raise_softirq_irqoff(TASKLET_SOFTIRQ);
-
414 local_irq_restore(flags);
-
415 }
-
444 static void tasklet_action(struct softirq_action *a)
-
445 {
-
446 struct tasklet_struct *list;
-
447
-
448 local_irq_disable();
-
449 list = __this_cpu_read(tasklet_vec.head);
-
450 __this_cpu_write(tasklet_vec.head, NULL);
-
451 __this_cpu_write(tasklet_vec.tail, &__get_cpu_var(tasklet_vec).head);
-
452 local_irq_enable();
-
453
-
454 while (list) {
-
455 struct tasklet_struct *t = list;
-
456
-
457 list = list->next;
-
458
-
459 if (tasklet_trylock(t)) {
-
460 if (!atomic_read(&t->count)) {
-
461 if (!test_and_clear_bit(TASKLET_STATE_SCHED, &t->state))
-
462 BUG();
-
463 t->func(t->data);
-
464 tasklet_unlock(t);
-
465 continue;
-
466 }
-
467 tasklet_unlock(t);
-
468 }
-
469
-
470 local_irq_disable();
-
471 t->next = NULL;
-
472 *__this_cpu_read(tasklet_vec.tail) = t;
-
473 __this_cpu_write(tasklet_vec.tail, &(t->next));
-
474 __raise_softirq_irqoff(TASKLET_SOFTIRQ);
-
475 local_irq_enable();
-
476 }
-
477 }
阅读(673) | 评论(0) | 转发(0) |