Question regarding dynamic allocated tasklet

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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 = "" 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 = "" 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 = "" 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 = "" 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


Attachment: problem-2,3.png
Description: PNG image

_______________________________________________
Kernelnewbies mailing list
Kernelnewbies@xxxxxxxxxxxxxxxxx
https://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies

[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]

  Powered by Linux