Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'core-fixes-for-linus-2' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip

* 'core-fixes-for-linus-2' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
softirq: introduce tasklet_hrtimer infrastructure

+89 -1
+26
include/linux/interrupt.h
··· 14 14 #include <linux/irqflags.h> 15 15 #include <linux/smp.h> 16 16 #include <linux/percpu.h> 17 + #include <linux/hrtimer.h> 17 18 18 19 #include <asm/atomic.h> 19 20 #include <asm/ptrace.h> ··· 519 518 extern void tasklet_kill_immediate(struct tasklet_struct *t, unsigned int cpu); 520 519 extern void tasklet_init(struct tasklet_struct *t, 521 520 void (*func)(unsigned long), unsigned long data); 521 + 522 + struct tasklet_hrtimer { 523 + struct hrtimer timer; 524 + struct tasklet_struct tasklet; 525 + enum hrtimer_restart (*function)(struct hrtimer *); 526 + }; 527 + 528 + extern void 529 + tasklet_hrtimer_init(struct tasklet_hrtimer *ttimer, 530 + enum hrtimer_restart (*function)(struct hrtimer *), 531 + clockid_t which_clock, enum hrtimer_mode mode); 532 + 533 + static inline 534 + int tasklet_hrtimer_start(struct tasklet_hrtimer *ttimer, ktime_t time, 535 + const enum hrtimer_mode mode) 536 + { 537 + return hrtimer_start(&ttimer->timer, time, mode); 538 + } 539 + 540 + static inline 541 + void tasklet_hrtimer_cancel(struct tasklet_hrtimer *ttimer) 542 + { 543 + hrtimer_cancel(&ttimer->timer); 544 + tasklet_kill(&ttimer->tasklet); 545 + } 522 546 523 547 /* 524 548 * Autoprobing for irqs:
+63 -1
kernel/softirq.c
··· 345 345 softirq_vec[nr].action = action; 346 346 } 347 347 348 - /* Tasklets */ 348 + /* 349 + * Tasklets 350 + */ 349 351 struct tasklet_head 350 352 { 351 353 struct tasklet_struct *head; ··· 494 492 } 495 493 496 494 EXPORT_SYMBOL(tasklet_kill); 495 + 496 + /* 497 + * tasklet_hrtimer 498 + */ 499 + 500 + /* 501 + * The trampoline is called when the hrtimer expires. If this is 502 + * called from the hrtimer interrupt then we schedule the tasklet as 503 + * the timer callback function expects to run in softirq context. If 504 + * it's called in softirq context anyway (i.e. high resolution timers 505 + * disabled) then the hrtimer callback is called right away. 506 + */ 507 + static enum hrtimer_restart __hrtimer_tasklet_trampoline(struct hrtimer *timer) 508 + { 509 + struct tasklet_hrtimer *ttimer = 510 + container_of(timer, struct tasklet_hrtimer, timer); 511 + 512 + if (hrtimer_is_hres_active(timer)) { 513 + tasklet_hi_schedule(&ttimer->tasklet); 514 + return HRTIMER_NORESTART; 515 + } 516 + return ttimer->function(timer); 517 + } 518 + 519 + /* 520 + * Helper function which calls the hrtimer callback from 521 + * tasklet/softirq context 522 + */ 523 + static void __tasklet_hrtimer_trampoline(unsigned long data) 524 + { 525 + struct tasklet_hrtimer *ttimer = (void *)data; 526 + enum hrtimer_restart restart; 527 + 528 + restart = ttimer->function(&ttimer->timer); 529 + if (restart != HRTIMER_NORESTART) 530 + hrtimer_restart(&ttimer->timer); 531 + } 532 + 533 + /** 534 + * tasklet_hrtimer_init - Init a tasklet/hrtimer combo for softirq callbacks 535 + * @ttimer: tasklet_hrtimer which is initialized 536 + * @function: hrtimer callback funtion which gets called from softirq context 537 + * @which_clock: clock id (CLOCK_MONOTONIC/CLOCK_REALTIME) 538 + * @mode: hrtimer mode (HRTIMER_MODE_ABS/HRTIMER_MODE_REL) 539 + */ 540 + void tasklet_hrtimer_init(struct tasklet_hrtimer *ttimer, 541 + enum hrtimer_restart (*function)(struct hrtimer *), 542 + clockid_t which_clock, enum hrtimer_mode mode) 543 + { 544 + hrtimer_init(&ttimer->timer, which_clock, mode); 545 + ttimer->timer.function = __hrtimer_tasklet_trampoline; 546 + tasklet_init(&ttimer->tasklet, __tasklet_hrtimer_trampoline, 547 + (unsigned long)ttimer); 548 + ttimer->function = function; 549 + } 550 + EXPORT_SYMBOL_GPL(tasklet_hrtimer_init); 551 + 552 + /* 553 + * Remote softirq bits 554 + */ 497 555 498 556 DEFINE_PER_CPU(struct list_head [NR_SOFTIRQS], softirq_work_list); 499 557 EXPORT_PER_CPU_SYMBOL(softirq_work_list);