ch7-deferred work tasklets

#include <linux/configfs.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/time.h>
#include <linux/timer.h>
#include <linux/kernel.h>
#include <linux/proc_fs.h>
#include <linux/types.h>
#include <linux/spinlock.h>
#include <linux/interrupt.h>

#include <asm/hardirq.h>


/*
 * The timer example follows
 */



/* This data structure used as "data" for the timer and tasklet functions */
struct jit_data {
	struct timer_list timer;
	struct tasklet_struct tlet;
	int hi; /* tasklet or tasklet_hi */
	wait_queue_head_t wait;
	unsigned long prevjiffies;
	unsigned char *buf;
	int loops;
};
#define JIT_ASYNC_LOOPS 10000

void jit_tasklet_fn(unsigned long arg)
{
	struct jit_data *data = (struct jit_data *)arg;
	unsigned long j = jiffies;
	data->buf += sprintf(data->buf, "%9li  %3li     %i    %6i   %i   %s\n",
			     j, j - data->prevjiffies, in_interrupt() ? 1 : 0,
			     current->pid, smp_processor_id(), current->comm);

 	printk("%9li  %3li     %i    %6i   %i   %s\n",
			     j, j - data->prevjiffies, in_interrupt() ? 1 : 0,
			     current->pid, smp_processor_id(), current->comm);


	if (--data->loops) {
		data->prevjiffies = j;
		if (data->hi)
			tasklet_hi_schedule(&data->tlet);
		else
			tasklet_schedule(&data->tlet);
	} else {
		kfree(data);
		//wake_up_interruptible(&data->wait);
	}
}

/* the /proc function: allocate everything to allow concurrency */
int jit_tasklet(char *buf, char **start, off_t offset,
	      int len, int *eof, void *arg)
{
	struct jit_data *data;
	char *buf2 = buf;
	unsigned long j = jiffies;
	long hi = (long)arg;

	data = kmalloc(sizeof(*data), GFP_KERNEL);
	if (!data)
		return -ENOMEM;

	init_waitqueue_head (&data->wait);

	/* write the first lines in the buffer */
	buf2 += sprintf(buf2, "   time   delta  inirq    pid   cpu command\n");
	buf2 += sprintf(buf2, "%9li  %3li     %i    %6i   %i   %s\n",
			j, 0L, in_interrupt() ? 1 : 0,
			current->pid, smp_processor_id(), current->comm);

	/* fill the data for our tasklet function */
	data->prevjiffies = j;
	data->buf = buf2;
	data->loops = JIT_ASYNC_LOOPS;
	
	/* register the tasklet */
	tasklet_init(&data->tlet, jit_tasklet_fn, (unsigned long)data);
	data->hi = hi;
	if (hi)
		tasklet_hi_schedule(&data->tlet);
	else
		tasklet_schedule(&data->tlet);

	/* wait for the buffer to fill */
	//wait_event_interruptible(data->wait, !data->loops);

	if (signal_pending(current))
		return -ERESTARTSYS;
	buf2 = data->buf;
	//kfree(data);
	*eof = 1;
	return buf2 - buf;
}

int __init jit_init(void)
{
	create_proc_read_entry("jitasklet", 0, NULL, jit_tasklet, NULL);
	create_proc_read_entry("jitasklethi", 0, NULL, jit_tasklet, (void *)1);

	return 0; /* success */
}



void __exit jit_cleanup(void)
{
	remove_proc_entry("jitasklet", NULL);
	remove_proc_entry("jitasklethi", NULL);
}

module_init(jit_init);
module_exit(jit_cleanup);
insmod test.ko
[root@localhost test]# cat /proc/jitasklet
   time   delta  inirq    pid   cpu command
   271843    0     0      3276   1   cat
[root@localhost test]# 
[root@localhost test]# cat /proc/kmsg 
<4>[  571.844503]    271844    1     1         7   1   ksoftirqd/1
<4>[  571.844560]    271844    0     1         7   1   ksoftirqd/1
<4>[  571.844570]    271844    0     1         7   1   ksoftirqd/1
<4>[  571.844651]    271844    0     1         7   1   ksoftirqd/1
<4>[  571.844685]    271844    0     1         7   1   ksoftirqd/1
<4>[  571.844694]    271844    0     1         7   1   ksoftirqd/1
<4>[  571.844702]    271844    0     1         7   1   ksoftirqd/1
<4>[  571.844710]    271844    0     1         7   1   ksoftirqd/1
<4>[  571.844718]    271844    0     1         7   1   ksoftirqd/1
<4>[  571.844726]    271844    0     1         7   1   ksoftirqd/1
<4>[  571.844740]    271844    0     1         7   1   ksoftirqd/1
<4>[  571.844748]    271844    0     1         7   1   ksoftirqd/1
<4>[  571.844756]    271844    0     1         7   1   ksoftirqd/1
<4>[  571.844763]    271844    0     1         7   1   ksoftirqd/1
<4>[  571.844771]    271844    0     1         7   1   ksoftirqd/1
<4>[  571.844779]    271844    0     1         7   1   ksoftirqd/1
<4>[  571.844786]    271844    0     1         7   1   ksoftirqd/1
<4>[  571.844794]    271844    0     1         7   1   ksoftirqd/1
<4>[  571.844802]    271844    0     1         7   1   ksoftirqd/1
<4>[  571.844810]    271844    0     1         7   1   ksoftirqd/1
<4>[  571.844818]    271844    0     1         7   1   ksoftirqd/1
<4>[  571.844826]    271844    0     1         7   1   ksoftirqd/1
<4>[  571.844834]    271844    0     1         7   1   ksoftirqd/1
<4>[  571.844842]    271844    0     1         7   1   ksoftirqd/1
<4>[  571.844849]    271844    0     1         7   1   ksoftirqd/1
<4>[  571.844857]    271844    0     1         7   1   ksoftirqd/1
<4>[  571.844865]    271844    0     1         7   1   ksoftirqd/1
<4>[  571.844872]    271844    0     1         7   1   ksoftirqd/1
<4>[  571.844880]    271844    0     1         7   1   ksoftirqd/1
<4>[  571.844888]    271844    0     1         7   1   ksoftirqd/1
<4>[  571.844895]    271844    0     1         7   1   ksoftirqd/1
<4>[  571.844903]    271844    0     1         7   1   ksoftirqd/1
<4>[  571.844911]    271844    0     1         7   1   ksoftirqd/1
<4>[  571.844918]    271844    0     1         7   1   ksoftirqd/1
<4>[  571.844926]    271844    0     1         7   1   ksoftirqd/1
<4>[  571.844934]    271844    0     1         7   1   ksoftirqd/1
<4>[  571.844942]    271844    0     1         7   1   ksoftirqd/1
<4>[  571.844949]    271844    0     1         7   1   ksoftirqd/1
<4>[  571.844957]    271844    0     1         7   1   ksoftirqd/1
<4>[  571.844965]    271844    0     1         7   1   ksoftirqd/1
<4>[  571.844973]    271844    0     1         7   1   ksoftirqd/1
<4>[  571.844980]    271844    0     1         7   1   ksoftirqd/1
<4>[  571.844988]    271844    0     1         7   1   ksoftirqd/1
<4>[  571.844996]    271844    0     1         7   1   ksoftirqd/1
<4>[  571.845003]    271844    0     1         7   1   ksoftirqd/1
<4>[  571.845011]    271844    0     1         7   1   ksoftirqd/1
<4>[  571.845018]    271844    0     1         7   1   ksoftirqd/1
<4>[  571.845026]    271844    0     1         7   1   ksoftirqd/1
<4>[  571.845034]    271844    0     1         7   1   ksoftirqd/1
<4>[  571.845042]    271844    0     1         7   1   ksoftirqd/1
<4>[  571.845049]    271844    0     1         7   1   ksoftirqd/1
<4>[  571.845057]    271844    0     1         7   1   ksoftirqd/1
<4>[  571.845065]    271844    0     1         7   1   ksoftirqd/1
<4>[  571.845072]    271844    0     1         7   1   ksoftirqd/1
<4>[  571.845080]    271844    0     1         7   1   ksoftirqd/1
<4>[  571.845087]    271844    0     1         7   1   ksoftirqd/1
<4>[  571.845095]    271844    0     1         7   1   ksoftirqd/1
<4>[  571.845103]    271844    0     1         7   1   ksoftirqd/1
<4>[  571.845111]    271844    0     1         7   1   ksoftirqd/1
<4>[  571.845118]    271844    0     1         7   1   ksoftirqd/1
<4>[  571.845126]    271844    0     1         7   1   ksoftirqd/1
<4>[  571.845134]    271844    0     1         7   1   ksoftirqd/1
<4>[  571.845141]    271844    0     1         7   1   ksoftirqd/1
<4>[  571.845149]    271844    0     1         7   1   ksoftirqd/1
<4>[  571.845214]    271844    0     1         7   1   ksoftirqd/1
<4>[  571.845223]    271844    0     1         7   1   ksoftirqd/1
<4>[  571.845231]    271844    0     1         7   1   ksoftirqd/1
<4>[  571.845239]    271844    0     1         7   1   ksoftirqd/1
<4>[  571.845246]    271844    0     1         7   1   ksoftirqd/1
<4>[  571.845254]    271844    0     1         7   1   ksoftirqd/1
<4>[  571.845263]    271844    0     1         7   1   ksoftirqd/1
<4>[  571.845270]    271844    0     1         7   1   ksoftirqd/1
<4>[  571.845276]    271844    0     1         7   1   ksoftirqd/1
<4>[  571.845276]    271844    0     1         7   1   ksoftirqd/1
<4>[  571.845276]    271844    0     1         7   1   ksoftirqd/1
<4>[  571.845276]    271844    0     1         7   1   ksoftirqd/1
<4>[  571.845276]    271844    0     1         7   1   ksoftirqd/1
<4>[  571.845276]    271844    0     1         7   1   ksoftirqd/1
<4>[  571.845276]    271844    0     1         7   1   ksoftirqd/1
<4>[  571.845276]    271844    0     1         7   1   ksoftirqd/1
<4>[  571.845276]    271844    0     1         7   1   ksoftirqd/1
<4>[  571.845435]    271844    0     1         7   1   ksoftirqd/1
<4>[  571.845463]    271845    1     1         7   1   ksoftirqd/1
<4>[  571.845480]    271845    0     1         7   1   ksoftirqd/1
<4>[  571.845488]    271845    0     1         7   1   ksoftirqd/1
<4>[  571.845496]    271845    0     1         7   1   ksoftirqd/1
<4>[  571.845504]    271845    0     1         7   1   ksoftirqd/1
<4>[  571.845511]    271845    0     1         7   1   ksoftirqd/1
<4>[  571.845519]    271845    0     1         7   1   ksoftirqd/1
<4>[  571.845527]    271845    0     1         7   1   ksoftirqd/1
<4>[  571.845535]    271845    0     1         7   1   ksoftirqd/1
<4>[  571.845543]    271845    0     1         7   1   ksoftirqd/1
<4>[  571.845550]    271845    0     1         7   1   ksoftirqd/1
<4>[  571.845558]    271845    0     1         7   1   ksoftirqd/1
<4>[  571.845566]    271845    0     1         7   1   ksoftirqd/1
<4>[  571.845573]    271845    0     1         7   1   ksoftirqd/1
<4>[  571.845581]    271845    0     1         7   1   ksoftirqd/1
<4>[  571.845589]    271845    0     1         7   1   ksoftirqd/1
<4>[  571.845596]    271845    0     1         7   1   ksoftirqd/1
<4>[  571.845604]    271845    0     1         7   1   ksoftirqd/1


1.和读进程无关
2.延后执行,延后到什么时间,要看kernel什么时候有空,但最迟也会在下一个时钟滴答里执行(2.6即1ms内)
3.除了执行时间稍微不确定外,和用定时器实现延后执行没多大区

7.5. Tasklets
Tasklets may be run immediately if the system is not under heavy load but never later than the next timer tick.
...
the tasklet is run at the next timer tick as long as the CPU is busy running a process, but it is run immediately when the CPU is otherwise idle.

4.理论上tasklet机制执行下半部的程序,但当大量软中断出现的时候,内核会唤醒一组内核线程来处理这些负载,这些线程是ksoftirqd(lkd2 p85)

内核的一个基本原则就是:在中断或者说原子上下文中,内核不能访问用户空间,而且内核是不能睡眠的。 也就是说在这种情况下,内核是不能调用有可能引起睡眠的任何函数。 一般来讲原子上下文指的是在中断或软中断中,以及在持有自旋锁的时候。
refer to
http://hi.baidu.com/juventus/blog/item/ac0e7bec26fc32d42f2e2144.html


于是有个问题,tasklet函数执行在原子上下文,但可以被硬件中断打断,而硬件的中断处理也处于原子上下文,这说明了原子上下文有优先级还是怎么回事呢?
答:tasklet处于原子上下文,但是可以响应中断,但不能被阻塞,即除了因响应中断之外不会有任何理由放弃cpu
但是,
tasklet响应了另外一个中断后,内核怎么调度其返回到原处继续执行呢?

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值