<div dir="ltr"><div><div><div><div><span style="font-family:verdana,sans-serif">Hi Guys,<br><br></span></div><div><span style="font-family:verdana,sans-serif">I am Abhinav, new to this mailing list.<br><br></span></div><div><span style="font-family:verdana,sans-serif">Have some query on tasklet.<br></span></div><span style="font-family:verdana,sans-serif">Going Jerry Cooperstein's LDD book chapter-20 (Interrupt handling and deferrable functions) lab exercises.<br><br></span></div><span style="font-family:verdana,sans-serif">Attached is the snapshot of problem-2,3. I am referring here to only tasklet.<br><br><br></span></div><span style="font-family:verdana,sans-serif">Solution to problem for tasklet provided is below.<br></span></div><span style="font-family:verdana,sans-serif"></span><div><span style="font-family:verdana,sans-serif"><br>------------------------------<wbr>------------------------------<wbr>------------------------------<wbr>--<br>static void t_fun(unsigned long t_arg)<br>{<br>        struct my_dat *data = (struct my_dat *)t_arg;<br>        atomic_inc(&counter_bh);<br>        pr_info(<br>               "In BH: counter_th = %d, counter_bh = %d, jiffies=%ld, %ld\n",<br>               atomic_read(&counter_th), atomic_read(&counter_bh),<br>               data->jiffies, jiffies);<br>}<br><br>static DECLARE_TASKLET(t_name, t_fun, (unsigned long)&my_data);<br><br>/* initialize tasklet */<br>static irqreturn_t my_interrupt(int irq, void *dev_id)<br>{<br>        struct my_dat *data = (struct my_dat *)dev_id;<br>        atomic_inc(&counter_th);<br>        data->jiffies = jiffies;<br>        tasklet_schedule(&t_name);<br>        mdelay(delay);          /* hoke up a delay to try to cause pileup */<br>        return IRQ_NONE;        /* we return IRQ_NONE because we are just observing */<br>}<br><br>module_init(my_generic_init);<br>module_exit(my_generic_exit);<br><br>------------------------------<wbr>------------------------------<wbr>------------------------------<wbr>-------<br><br><span>Above solution will miss some bottom halves.</span><br></span></div><div><span style="font-family:verdana,sans-serif">To solve this problem, a solution is provided using dynamically allocated tasklet as below<br><br>------------------------------<wbr>------------------------------<wbr>-------------<br>static void t_fun(unsigned long t_arg)<br>{<br>        struct my_dat *data = (struct my_dat *)t_arg;<br>        atomic_inc(&counter_bh);<br>        pr_info("In BH: counter_th = %d, counter_bh = %d, jiffies=%ld, %ld\n",<br>                atomic_read(&counter_th), atomic_read(&counter_bh),<br>                data->jiffies, jiffies);<br>        kfree(data);<br>}<br><br>static irqreturn_t my_interrupt(int irq, void *dev_id)<br>{<br>        struct tasklet_struct *t;<br>        struct my_dat *data;<br><br>        data = (struct my_dat *)kmalloc(sizeof(struct my_dat), GFP_ATOMIC);<br>        t = &data->tsk;<br>        data->jiffies = jiffies;<br><br>        tasklet_init(t, t_fun, (unsigned long)data);<br><br>        atomic_inc(&counter_th);<br>        tasklet_schedule(t);<br>        mdelay(delay);          /* hoke up a delay to try to cause pileup */<br>        return IRQ_NONE;        /* we return IRQ_NONE because we are just observing */<br>}<br><br>module_init(my_generic_init);<br>module_exit(my_generic_exit);<br><br>------------------------------<wbr>------------------------------<wbr>-------------<br></span></div><div><span style="font-family:verdana,sans-serif"><br></span></div><div><span style="font-family:verdana,sans-serif">Above solution will not miss any bottom halves.<br></span></div><div><span style="font-family:verdana,sans-serif">Can somebody explains me why above solution is working ?<br></span></div><div><span style="font-family:verdana,sans-serif">What is so special about dynamic tasklets ?<br><br></span></div><div><span style="font-family:verdana,sans-serif">BR,Abhinav<br></span></div><div><span style="font-family:verdana,sans-serif"><br><br></span></div></div>