617 lines · 15.1 KB · C
RawDownload
	INIT_WORK(&ew->work, fn, data);	schedule_work(&ew->work); 	return 1;}EXPORT_SYMBOL_GPL(execute_in_process_context); int keventd_up(void){	return keventd_wq != NULL;} int current_is_keventd(void){	struct cpu_workqueue_struct *cwq;	int cpu = smp_processor_id();	/* preempt-safe: keventd is per-cpu */	int ret = 0; 	BUG_ON(!keventd_wq); 	cwq = per_cpu_ptr(keventd_wq->cpu_wq, cpu);	if (current == cwq->thread)		ret = 1; 	return ret; } #ifdef CONFIG_HOTPLUG_CPU/* Take the work from this (downed) CPU. */static void take_over_work(struct workqueue_struct *wq, unsigned int cpu){	struct cpu_workqueue_struct *cwq = per_cpu_ptr(wq->cpu_wq, cpu);	LIST_HEAD(list);	struct work_struct *work; 	spin_lock_irq(&cwq->lock);	list_splice_init(&cwq->worklist, &list); 	while (!list_empty(&list)) {		printk("Taking work for %s\n", wq->name);		work = list_entry(list.next,struct work_struct,entry);		list_del(&work->entry);		__queue_work(per_cpu_ptr(wq->cpu_wq, smp_processor_id()), work);	}	spin_unlock_irq(&cwq->lock);} /* We're holding the cpucontrol mutex here */static int workqueue_cpu_callback(struct notifier_block *nfb,				  unsigned long action,				  void *hcpu){	unsigned int hotcpu = (unsigned long)hcpu;	struct workqueue_struct *wq; 	switch (action) {	case CPU_UP_PREPARE:		/* Create a new workqueue thread for it. */		list_for_each_entry(wq, &workqueues, list) {			if (!create_workqueue_thread(wq, hotcpu)) {				printk("workqueue for %i failed\n", hotcpu);				return NOTIFY_BAD;			}		}		break; 	case CPU_ONLINE:		/* Kick off worker threads. */		list_for_each_entry(wq, &workqueues, list) {			struct cpu_workqueue_struct *cwq; 			cwq = per_cpu_ptr(wq->cpu_wq, hotcpu);			kthread_bind(cwq->thread, hotcpu);			wake_up_process(cwq->thread);		}		break; 	case CPU_UP_CANCELED:		list_for_each_entry(wq, &workqueues, list) {			/* Unbind so it can run. */			kthread_bind(per_cpu_ptr(wq->cpu_wq, hotcpu)->thread,				     any_online_cpu(cpu_online_map));			cleanup_workqueue_thread(wq, hotcpu);		}		break; 	case CPU_DEAD:		list_for_each_entry(wq, &workqueues, list)			cleanup_workqueue_thread(wq, hotcpu);		list_for_each_entry(wq, &workqueues, list)			take_over_work(wq, hotcpu);		break;	} 	return NOTIFY_OK;}#endif void init_workqueues(void){	singlethread_cpu = first_cpu(cpu_possible_map);	hotcpu_notifier(workqueue_cpu_callback, 0);	keventd_wq = create_workqueue("events");	BUG_ON(!keventd_wq);} EXPORT_SYMBOL_GPL(__create_workqueue);EXPORT_SYMBOL_GPL(queue_work);EXPORT_SYMBOL_GPL(queue_delayed_work);EXPORT_SYMBOL_GPL(flush_workqueue);EXPORT_SYMBOL_GPL(destroy_workqueue); EXPORT_SYMBOL(schedule_work);EXPORT_SYMBOL(schedule_delayed_work);EXPORT_SYMBOL(schedule_delayed_work_on);EXPORT_SYMBOL(flush_scheduled_work);

Lines 501–617 of 617. Previous lines