From 271a17e550236d7cfc14385a1b20f692e23de0af Mon Sep 17 00:00:00 2001 From: Thadeu Lima de Souza Cascardo Date: Fri, 21 May 2010 07:00:32 -0400 Subject: [PATCH] Create a work that will busy wait. Create a workqueue and queue two works, the first one being a work that busy waits for a number of seconds, delaying the execution of the second one. --- Makefile | 1 + block_wq.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+) create mode 100644 block_wq.c diff --git a/Makefile b/Makefile index f2266eb..dbcf910 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,6 @@ ifneq ($(KERNELRELEASE),) obj-m := wq.o + obj-m += block_wq.o else KERNELDIR ?= /lib/modules/$(shell uname -r)/build PWD := $(shell pwd) diff --git a/block_wq.c b/block_wq.c new file mode 100644 index 0000000..ae6d8ab --- /dev/null +++ b/block_wq.c @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2010 Thadeu Lima de Souza Cascardo + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/* + * This code demonstrates why a work should not block for too long. + * This is worse in the case that the work is scheduled in keventd. + */ + +#include +#include + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Thadeu Lima de Souza Cascardo"); + +static void work_block(struct work_struct *work) +{ + unsigned long tmp = jiffies + 5 * HZ; + printk(KERN_INFO "Blocking other works in the queue\n"); + printk(KERN_INFO "Executing task in CPU %d\n", smp_processor_id()); + /* We also kick the CPU high */ + while (!time_after(jiffies, tmp)) + cpu_relax(); +} + +static void work_print(struct work_struct *work) +{ + printk(KERN_INFO "Phew! That was waiting!\n"); + printk(KERN_INFO "Task done in CPU %d\n", smp_processor_id()); +} + +static struct workqueue_struct *block_wq; +static DECLARE_WORK(block_work, work_block); +static DECLARE_WORK(print_work, work_print); + +static int block_wq_init(void) +{ + block_wq = create_workqueue("block_wq"); + if (!block_wq) + return -ENOMEM; + printk(KERN_INFO "Queueing task in CPU %d\n", get_cpu()); + put_cpu(); + queue_work(block_wq, &block_work); + queue_work(block_wq, &print_work); + return 0; +} + +static void block_wq_exit(void) +{ + destroy_workqueue(block_wq); +} + +module_init(block_wq_init); +module_exit(block_wq_exit); -- 2.20.1