Ben
Ben

Reputation: 2937

Linux Kernel Threads

So I'm working on a linux Kernel module which requires an infinite waiting loop in a separate thread initiated by kthread. The following is the function run by kthread, and train.queue_mutex is a mutex initialized before kthread (via mutex_init(&train.queue_mutex))

I cannot for the life of me figure out why it locks the kernel. My thinking is that between the mdelay and the schedule() every iteration, other processes should get CPU time.

 int train_thread(void *param)
    {
            while (!train.is_deactivating)
            {
                    mutex_lock_interruptible(&train.queue_mutex);
                    while (train.num_waiting > 0)
                    {
                        int five_foward = (train.stop + 5) % 10;
                        int five_back = (train.stop - 5) % 10;
                        int i = train.stop;
                        int max_count = 0;
                        int max_count_index = 0;

                        for (;i != five_foward; i = (i + 1) % 10)
                        {
                                int count = robots_count(train.waiting[i]);
                                if (count > max_count)
                                {
                                        max_count_index = i;
                                        max_count       = count;
                                }
                        }


                        for (i = train.stop ;i != five_back; i = (i - 1) % 10)
                        {
                                int count = robots_count(train.waiting[i]);
                                if (count > max_count)
                                {
                                        max_count_index = i;
                                        max_count       = count;
                                }
                        }

                        // Should have max_count_index set to index of stop with the most bots
                        printk("Most bots %d at stop %d\n", max_count, max_count_index);
                        mutex_unlock(&train.queue_mutex);
                        schedule();
                        mutex_lock_interruptible(&train.queue_mutex);
                }
                mutex_unlock(&train.queue_mutex);
                mdelay(10);
        }

        train.is_active = 0;
        return 0;
}

Upvotes: 1

Views: 1572

Answers (2)

Adrian Cox
Adrian Cox

Reputation: 6334

Once you've fixed the logic problem pointed out by bestsss you still have the problem that mdelay() is a busy-wait, which does not release the CPU. You should consider schedule_timeout() or msleep. Take a look in Linux Device Drivers for more details.

Upvotes: 0

bestsss
bestsss

Reputation: 12066

 for (i = train.stop ;i != five_back; i = (i - 1) % 10)
 {
    int count = robots_count(train.waiting[i]);

When i == 1, you have five_back negative and effectively robots_count(train.waiting[-1); after 2 iterations.

Upvotes: 1

Related Questions