Question regarding dynamic allocated tasklet

Abhinav Misra abhitheextremeeng at gmail.com
Sat Jun 16 14:22:58 EDT 2018


Hi Guys,

I am Abhinav, new to this mailing list.

Have some query on tasklet.
Going Jerry Cooperstein's LDD book chapter-20 (Interrupt handling and
deferrable functions) lab exercises.

Attached is the snapshot of problem-2,3. I am referring here to only
tasklet.


Solution to problem for tasklet provided is below.

------------------------------------------------------------
--------------------------------
static void t_fun(unsigned long t_arg)
{
        struct my_dat *data = (struct my_dat *)t_arg;
        atomic_inc(&counter_bh);
        pr_info(
               "In BH: counter_th = %d, counter_bh = %d, jiffies=%ld,
%ld\n",
               atomic_read(&counter_th), atomic_read(&counter_bh),
               data->jiffies, jiffies);
}

static DECLARE_TASKLET(t_name, t_fun, (unsigned long)&my_data);

/* initialize tasklet */
static irqreturn_t my_interrupt(int irq, void *dev_id)
{
        struct my_dat *data = (struct my_dat *)dev_id;
        atomic_inc(&counter_th);
        data->jiffies = jiffies;
        tasklet_schedule(&t_name);
        mdelay(delay);          /* hoke up a delay to try to cause pileup */
        return IRQ_NONE;        /* we return IRQ_NONE because we are just
observing */
}

module_init(my_generic_init);
module_exit(my_generic_exit);

------------------------------------------------------------
-------------------------------------

Above solution will miss some bottom halves.
To solve this problem, a solution is provided using dynamically allocated
tasklet as below

-------------------------------------------------------------------------
static void t_fun(unsigned long t_arg)
{
        struct my_dat *data = (struct my_dat *)t_arg;
        atomic_inc(&counter_bh);
        pr_info("In BH: counter_th = %d, counter_bh = %d, jiffies=%ld,
%ld\n",
                atomic_read(&counter_th), atomic_read(&counter_bh),
                data->jiffies, jiffies);
        kfree(data);
}

static irqreturn_t my_interrupt(int irq, void *dev_id)
{
        struct tasklet_struct *t;
        struct my_dat *data;

        data = (struct my_dat *)kmalloc(sizeof(struct my_dat), GFP_ATOMIC);
        t = &data->tsk;
        data->jiffies = jiffies;

        tasklet_init(t, t_fun, (unsigned long)data);

        atomic_inc(&counter_th);
        tasklet_schedule(t);
        mdelay(delay);          /* hoke up a delay to try to cause pileup */
        return IRQ_NONE;        /* we return IRQ_NONE because we are just
observing */
}

module_init(my_generic_init);
module_exit(my_generic_exit);

-------------------------------------------------------------------------

Above solution will not miss any bottom halves.
Can somebody explains me why above solution is working ?
What is so special about dynamic tasklets ?

BR,Abhinav
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.kernelnewbies.org/pipermail/kernelnewbies/attachments/20180616/cf49a587/attachment-0001.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: problem-2,3.png
Type: image/png
Size: 179706 bytes
Desc: not available
URL: <http://lists.kernelnewbies.org/pipermail/kernelnewbies/attachments/20180616/cf49a587/attachment-0001.png>


More information about the Kernelnewbies mailing list