* Tim Chen <[EMAIL PROTECTED]> wrote: > Ingo, > > While trying out the 2.6.19.1-rt14 kernel with a x86_64 system with > Clovertown processor, it hung when it was shutting down e1000 ethernet > interface running the command: > > /sbin/ip link set dev eth0 down
does the patch below solve it for you? Ingo Index: linux/fs/file_table.c =================================================================== --- linux.orig/fs/file_table.c +++ linux/fs/file_table.c @@ -333,6 +333,22 @@ static void __filevec_add(struct filevec filevec_reinit(fvec); } +/* + * Flush files per-CPU workqueue: + */ +static struct workqueue_struct *flush_files_workqueue; + +int __init flush_files_init(void) +{ + flush_files_workqueue = create_workqueue("flush_filesd"); + if (!flush_files_workqueue) + panic("Failed to create flush_filesd\n"); + + return 0; +} + +__initcall(flush_files_init); + static void filevec_add_drain(void) { int cpu; @@ -349,7 +365,8 @@ static void filevec_add_drain_per_cpu(st int filevec_add_drain_all(void) { - return schedule_on_each_cpu(filevec_add_drain_per_cpu); + return schedule_on_each_cpu_wq(flush_files_workqueue, + filevec_add_drain_per_cpu); } EXPORT_SYMBOL_GPL(filevec_add_drain_all); Index: linux/include/linux/workqueue.h =================================================================== --- linux.orig/include/linux/workqueue.h +++ linux/include/linux/workqueue.h @@ -181,6 +181,7 @@ extern int FASTCALL(schedule_delayed_wor extern int schedule_delayed_work_on(int cpu, struct delayed_work *work, unsigned long delay); extern int schedule_on_each_cpu(work_func_t func); +extern int schedule_on_each_cpu_wq(struct workqueue_struct *wq, work_func_t func); extern void flush_scheduled_work(void); extern int current_is_keventd(void); extern int keventd_up(void); Index: linux/kernel/workqueue.c =================================================================== --- linux.orig/kernel/workqueue.c +++ linux/kernel/workqueue.c @@ -700,6 +700,44 @@ int schedule_on_each_cpu(work_func_t fun return 0; } +/** + * schedule_on_each_cpu_wq - call a function on each online CPU on a per-CPU wq + * @func: the function to call + * + * Returns zero on success. + * Returns -ve errno on failure. + * + * Appears to be racy against CPU hotplug. + * + * schedule_on_each_cpu() is very slow. + */ +int schedule_on_each_cpu_wq(struct workqueue_struct *wq, work_func_t func) +{ + int cpu; + struct work_struct *works; + + if (is_single_threaded(wq)) { + WARN_ON(1); + return -EINVAL; + } + works = alloc_percpu(struct work_struct); + if (!works) + return -ENOMEM; + + for_each_online_cpu(cpu) { + struct work_struct *work = per_cpu_ptr(works, cpu); + + INIT_WORK(work, func); + set_bit(WORK_STRUCT_PENDING, work_data_bits(work)); + __queue_work(per_cpu_ptr(wq->cpu_wq, cpu), work); + } + flush_workqueue(wq); + free_percpu(works); + + return 0; +} + + void flush_scheduled_work(void) { flush_workqueue(keventd_wq); - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/