Christian Brauner (Amutable)exec_state: relocate dumpable information6b1c66c5 months agoHistory
1738 lines · 47.6 KB · C
RawDownload
	WARN_ON_ONCE(work->worker != worker); 	if (is_dwork)		kthread_cancel_delayed_work_timer(work, &flags); 	ret = __kthread_cancel_work(work); 	if (worker->current_work != work)		goto out_fast; 	/*	 * The work is in progress and we need to wait with the lock released.	 * In the meantime, block any queuing by setting the canceling counter.	 */	work->canceling++;	raw_spin_unlock_irqrestore(&worker->lock, flags);	kthread_flush_work(work);	raw_spin_lock_irqsave(&worker->lock, flags);	work->canceling--; out_fast:	raw_spin_unlock_irqrestore(&worker->lock, flags);out:	return ret;} /** * kthread_cancel_work_sync - cancel a kthread work and wait for it to finish * @work: the kthread work to cancel * * Cancel @work and wait for its execution to finish.  This function * can be used even if the work re-queues itself. On return from this * function, @work is guaranteed to be not pending or executing on any CPU. * * kthread_cancel_work_sync(&delayed_work->work) must not be used for * delayed_work's. Use kthread_cancel_delayed_work_sync() instead. * * The caller must ensure that the worker on which @work was last * queued can't be destroyed before this function returns. * * Return: %true if @work was pending, %false otherwise. */bool kthread_cancel_work_sync(struct kthread_work *work){	return __kthread_cancel_work_sync(work, false);}EXPORT_SYMBOL_GPL(kthread_cancel_work_sync); /** * kthread_cancel_delayed_work_sync - cancel a kthread delayed work and *	wait for it to finish. * @dwork: the kthread delayed work to cancel * * This is kthread_cancel_work_sync() for delayed works. * * Return: %true if @dwork was pending, %false otherwise. */bool kthread_cancel_delayed_work_sync(struct kthread_delayed_work *dwork){	return __kthread_cancel_work_sync(&dwork->work, true);}EXPORT_SYMBOL_GPL(kthread_cancel_delayed_work_sync); /** * kthread_flush_worker - flush all current works on a kthread_worker * @worker: worker to flush * * Wait until all currently executing or pending works on @worker are * finished. */void kthread_flush_worker(struct kthread_worker *worker){	struct kthread_flush_work fwork = {		KTHREAD_WORK_INIT(fwork.work, kthread_flush_work_fn),		COMPLETION_INITIALIZER_ONSTACK(fwork.done),	}; 	kthread_queue_work(worker, &fwork.work);	wait_for_completion(&fwork.done);}EXPORT_SYMBOL_GPL(kthread_flush_worker); /** * kthread_destroy_worker - destroy a kthread worker * @worker: worker to be destroyed * * Flush and destroy @worker.  The simple flush is enough because the kthread * worker API is used only in trivial scenarios.  There are no multi-step state * machines needed. * * Note that this function is not responsible for handling delayed work, so * caller should be responsible for queuing or canceling all delayed work items * before invoke this function. */void kthread_destroy_worker(struct kthread_worker *worker){	struct task_struct *task; 	task = worker->task;	if (WARN_ON(!task))		return; 	kthread_flush_worker(worker);	kthread_stop(task);	WARN_ON(!list_empty(&worker->delayed_work_list));	WARN_ON(!list_empty(&worker->work_list));	kfree(worker);}EXPORT_SYMBOL(kthread_destroy_worker); /** * kthread_use_mm - make the calling kthread operate on an address space * @mm: address space to operate on */void kthread_use_mm(struct mm_struct *mm){	struct mm_struct *active_mm;	struct task_struct *tsk = current; 	WARN_ON_ONCE(!(tsk->flags & PF_KTHREAD));	WARN_ON_ONCE(tsk->mm); 	/*	 * It is possible for mm to be the same as tsk->active_mm, but	 * we must still mmgrab(mm) and mmdrop_lazy_tlb(active_mm),	 * because these references are not equivalent.	 */	mmgrab(mm); 	task_lock(tsk);	/* Hold off tlb flush IPIs while switching mm's */	local_irq_disable();	active_mm = tsk->active_mm;	tsk->active_mm = mm;	tsk->mm = mm;	membarrier_update_current_mm(mm);	switch_mm_irqs_off(active_mm, mm, tsk);	local_irq_enable();	task_unlock(tsk);#ifdef finish_arch_post_lock_switch	finish_arch_post_lock_switch();#endif 	/*	 * When a kthread starts operating on an address space, the loop	 * in membarrier_{private,global}_expedited() may not observe	 * that tsk->mm, and not issue an IPI. Membarrier requires a	 * memory barrier after storing to tsk->mm, before accessing	 * user-space memory. A full memory barrier for membarrier	 * {PRIVATE,GLOBAL}_EXPEDITED is implicitly provided by	 * mmdrop_lazy_tlb().	 */	mmdrop_lazy_tlb(active_mm);}EXPORT_SYMBOL_GPL(kthread_use_mm); /** * kthread_unuse_mm - reverse the effect of kthread_use_mm() * @mm: address space to operate on */void kthread_unuse_mm(struct mm_struct *mm){	struct task_struct *tsk = current; 	WARN_ON_ONCE(!(tsk->flags & PF_KTHREAD));	WARN_ON_ONCE(!tsk->mm); 	task_lock(tsk);	/*	 * When a kthread stops operating on an address space, the loop	 * in membarrier_{private,global}_expedited() may not observe	 * that tsk->mm, and not issue an IPI. Membarrier requires a	 * memory barrier after accessing user-space memory, before	 * clearing tsk->mm.	 */	smp_mb__after_spinlock();	local_irq_disable();	tsk->mm = NULL;	membarrier_update_current_mm(NULL);	mmgrab_lazy_tlb(mm);	/* active_mm is still 'mm' */	enter_lazy_tlb(mm, tsk);	local_irq_enable();	task_unlock(tsk); 	mmdrop(mm);}EXPORT_SYMBOL_GPL(kthread_unuse_mm); #ifdef CONFIG_BLK_CGROUP/** * kthread_associate_blkcg - associate blkcg to current kthread * @css: the cgroup info * * Current thread must be a kthread. The thread is running jobs on behalf of * other threads. In some cases, we expect the jobs attach cgroup info of * original threads instead of that of current thread. This function stores * original thread's cgroup info in current kthread context for later * retrieval. */void kthread_associate_blkcg(struct cgroup_subsys_state *css){	struct kthread *kthread; 	if (!(current->flags & PF_KTHREAD))		return;	kthread = to_kthread(current);	if (!kthread)		return; 	if (kthread->blkcg_css) {		css_put(kthread->blkcg_css);		kthread->blkcg_css = NULL;	}	if (css) {		css_get(css);		kthread->blkcg_css = css;	}}EXPORT_SYMBOL(kthread_associate_blkcg); /** * kthread_blkcg - get associated blkcg css of current kthread * * Current thread must be a kthread. */struct cgroup_subsys_state *kthread_blkcg(void){	struct kthread *kthread; 	if (current->flags & PF_KTHREAD) {		kthread = to_kthread(current);		if (kthread)			return kthread->blkcg_css;	}	return NULL;}#endif

Lines 1501–1738 of 1738. Previous lines

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t