/* Worker thread pool for slow items, such as filesystem lookups or mkdirs
 *
 * Copyright (C) 2008 Red Hat, Inc. All Rights Reserved.
 * Written by David Howells (dhowells@redhat.com)
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public Licence
 * as published by the Free Software Foundation; either version
 * 2 of the Licence, or (at your option) any later version.
 *
 * See Documentation/slow-work.txt
 */

#include <linux/module.h>
#include <linux/slow-work.h>
#include <linux/kthread.h>
#include <linux/freezer.h>
#include <linux/wait.h>
#include <linux/debugfs.h>
#include "slow-work.h"

static void slow_work_cull_timeout(unsigned long);
static void slow_work_oom_timeout(unsigned long);

#ifdef CONFIG_SYSCTL
static int slow_work_min_threads_sysctl(struct ctl_table *, int,
					void __user *, size_t *, loff_t *);

static int slow_work_max_threads_sysctl(struct ctl_table *, int ,
					void __user *, size_t *, loff_t *);
#endif

/*
 * The pool of threads has at least min threads in it as long as someone is
 * using the facility, and may have as many as max.
 *
 * A portion of the pool may be processing very slow operations.
 */
static unsigned slow_work_min_threads = 2;
static unsigned slow_work_max_threads = 4;
static unsigned vslow_work_proportion = 50; /* % of threads that may process
					     * very slow work */

#ifdef CONFIG_SYSCTL
static const int slow_work_min_min_threads = 2;
static int slow_work_max_max_threads = SLOW_WORK_THREAD_LIMIT;
static const int slow_work_min_vslow = 1;
static const int slow_work_max_vslow = 99;

ctl_table slow_work_sysctls[] = {
	{
		.procname	= "min-threads",
		.data		= &slow_work_min_threads,
		.maxlen		= sizeof(unsigned),
		.mode		= 0644,
		.proc_handler	= slow_work_min_threads_sysctl,
		.extra1		= (void *) &slow_work_min_min_threads,
		.extra2		= &slow_work_max_threads,
	},
	{
		.procname	= "max-threads",
		.data		= &slow_work_max_threads,
		.maxlen		= sizeof(unsigned),
		.mode		= 0644,
		.proc_handler	= slow_work_max_threads_sysctl,
		.extra1		= &slow_work_min_threads,
		.extra2		= (void *) &slow_work_max_max_threads,
	},
	{
		.procname	= "vslow-percentage",
		.data		= &vslow_work_proportion,
		.maxlen		= sizeof(unsigned),
		.mode		= 0644,
		.proc_handler	= proc_dointvec_minmax,
		.extra1		= (void *) &slow_work_min_vslow,
		.extra2		= (void *) &slow_work_max_vslow,
	},
	{}
};
#endif

/*
 * The active state of the thread pool
 */
static atomic_t slow_work_thread_count;
static atomic_t vslow_work_executing_count;

static bool slow_work_may_not_start_new_thread;
static bool slow_work_cull; /* cull a thread due to lack of activity */
static DEFINE_TIMER(slow_work_cull_timer, slow_work_cull_timeout, 0, 0);
static DEFINE_TIMER(slow_work_oom_timer, slow_work_oom_timeout, 0, 0);
static struct slow_work slow_work_new_thread; /* new thread starter */

/*
 * slow work ID allocation (use slow_work_queue_lock)
 */
static DECLARE_BITMAP(slow_work_ids, SLOW_WORK_THREAD_LIMIT);

/*
 * Unregistration tracking to prevent put_ref() from disappearing during module
 * unload
 */
#ifdef CONFIG_MODULES
static struct module *slow_work_thread_processing[SLOW_WORK_THREAD_LIMIT];
static struct module *slow_work_unreg_module;
static struct slow_work *slow_work_unreg_work_item;
static DECLARE_WAIT_QUEUE_HEAD(slow_work_unreg_wq);
static DEFINE_MUTEX(slow_work_unreg_sync_lock);

static void slow_work_set_thread_processing(int id, struct slow_work *work)
{
	if (work)
		slow_work_thread_processing[id] = work->owner;
}
static void slow_work_done_thread_processing(int id, struct slow_work *work)
{
	struct module *module = slow_work_thread_processing[id];

	slow_work_thread_processing[id] = NULL;
	smp_mb();
	if (slow_work_unreg_work_item == work ||
	    slow_work_unreg_module == module)
		wake_up_all(&slow_work_unreg_wq);
}
static void slow_work_clear_thread_processing(int id)
{
	slow_work_thread_processing[id] = NULL;
}
#else
static void slow_work_set_thread_processing(int id, struct slow_work *work) {}
static void slow_work_done_thread_processing(int id, struct slow_work *work) {}
static void slow_work_clear_thread_processing(int id) {}
#endif

/*
 * Data for tracking currently executing items for indication through /proc
 */
#ifdef CONFIG_SLOW_WORK_DEBUG
struct slow_work *slow_work_execs[SLOW_WORK_THREAD_LIMIT];
pid_t slow_work_pids[SLOW_WORK_THREAD_LIMIT];
DEFINE_RWLOCK(slow_work_execs_lock);
#endif

/*
 * The queues of work items and the lock governing access to them.  These are
 * shared between all the CPUs.  It doesn't make sense to have per-CPU queues
 * as the number of threads bears no relation to the number of CPUs.
 *
 * There are two queues of work items: one for slow work items, and one for
 * very slow work items.
 */
LIST_HEAD(slow_work_queue);
LIST_HEAD(vslow_work_queue);
DEFINE_SPINLOCK(slow_work_queue_lock);

/*
 * The following are two wait queues that get pinged when a work item is placed
 * on an empty queue.  These allow work items that are hogging a thread by
 * sleeping in a way that could be deferred to yield their thread and enqueue
 * themselves.
 */
static DECLARE_WAIT_QUEUE_HEAD(slow_work_queue_waits_for_occupation);
static DECLARE_WAIT_QUEUE_HEAD(vslow_work_queue_waits_for_occupation);

/*
 * The thread controls.  A variable used to signal to the threads that they
 * should exit when the queue is empty, a waitqueue used by the threads to wait
 * for signals, and a completion set by the last thread to exit.
 */
static bool slow_work_threads_should_exit;
static DECLARE_WAIT_QUEUE_HEAD(slow_work_thread_wq);
static DECLARE_COMPLETION(slow_work_last_thread_exited);

/*
 * The number of users of the thread pool and its lock.  Whilst this is zero we
 * have no threads hanging around, and when this reaches zero, we wait for all
 * active or queued work items to complete and kill all the threads we do have.
 */
static int slow_work_user_count;
static DEFINE_MUTEX(slow_work_user_lock);

static inline int slow_work_get_ref(struct slow_work *work)
{
	if (work->ops->get_ref)
		return work->ops->get_ref(work);

	return 0;
}

static inline void slow_work_put_ref(struct slow_work *work)
{
	if (work->ops->put_ref)
		work->ops->put_ref(work);
}

/*
 * Calculate the maximum number of active threads in the pool that are
 * permitted to process very slow work items.
 *
 * The answer is rounded up to at least 1, but may not equal or exceed the
 * maximum number of the threads in the pool.  This means we always have at
 * least one thread that can process slow work items, and we always have at
 * least one thread that won't get tied up doing so.
 */
static unsigned slow_work_calc_vsmax(void)
{
	unsigned vsmax;

	vsmax = atomic_read(&slow_work_thread_count) * vslow_work_proportion;
	vsmax /= 100;
	vsmax = max(vsmax, 1U);
	return min(vsmax, slow_work_max_threads - 1);
}

/*
 * Attempt to execute stuff queued on a slow thread.  Return true if we managed
 * it, false if there was nothing to do.
 */
static noinline bool slow_work_execute(int id)
{
	struct slow_work *work = NULL;
	unsigned vsmax;
	bool very_slow;

	vsmax = slow_work_calc_vsmax();

	/* see if we can schedule a new thread to be started if we're not
	 * keeping up with the work */
	if (!waitqueue_active(&slow_work_thread_wq) &&
	    (!list_empty(&slow_work_queue) || !list_empty(&vslow_work_queue)) &&
	    atomic_read(&slow_work_thread_count) < slow_work_max_threads &&
	    !slow_work_may_not_start_new_thread)
		slow_work_enqueue(&slow_work_new_thread);

	/* find something to execute */
	spin_lock_irq(&slow_work_queue_lock);
	if (!list_empty(&vslow_work_queue) &&
	    atomic_read(&vslow_work_executing_count) < vsmax) {
		work = list_entry(vslow_work_queue.next,
				  struct slow_work, link);
		if (test_and_set_bit_lock(SLOW_WORK_EXECUTING, &work->flags))
			BUG();
		list_del_init(&work->link);
		atomic_inc(&vslow_work_executing_count);
		very_slow = true;
	} else if (!list_empty(&slow_work_queue)) {
		work = list_entry(slow_work_queue.next,
				  struct slow_work, link);
		if (test_and_set_bit_lock(SLOW_WORK_EXECUTING, &work->flags))
			BUG();
		list_del_init(&work->link);
		very_slow = false;
	} else {
		very_slow = false; /* avoid the compiler warning */
	}

	slow_work_set_thread_processing(id, work);
	if (work) {
		slow_work_mark_time(work);
		slow_work_begin_exec(id, work);
	}

	spin_unlock_irq(&slow_work_queue_lock);

	if (!work)
		return false;

	if (!test_and_clear_bit(SLOW_WORK_PENDING, &work->flags))
		BUG();

	/* don't execute if the work is in the process of being cancelled */
	if (!test_bit(SLOW_WORK_CANCELLING, &work->flags))
		work->ops->execute(work);

	if (very_slow)
		atomic_dec(&vslow_work_executing_count);
	clear_bit_unlock(SLOW_WORK_EXECUTING, &work->flags);

	/* wake up anyone waiting for this work to be complete */
	wake_up_bit(&work->flags, SLOW_WORK_EXECUTING);

	slow_work_end_exec(id, work);

	/* if someone tried to enqueue the item whilst we were executing it,
	 * then it'll be left unenqueued to avoid multiple threads trying to
	 * execute it simultaneously
	 *
	 * there is, however, a race between us testing the pending flag and
	 * getting the spinlock, and between the enqueuer setting the pending
	 * flag and getting the spinlock, so we use a deferral bit to tell us
	 * if the enqueuer got there first
	 */
	if (test_bit(SLOW_WORK_PENDING, &work->flags)) {
		spin_lock_irq(&slow_work_queue_lock);

		if (!test_bit(SLOW_WORK_EXECUTING, &work->flags) &&
		    test_and_clear_bit(SLOW_WORK_ENQ_DEFERRED, &work->flags))
			goto auto_requeue;

		spin_unlock_irq(&slow_work_queue_lock);
	}

	/* sort out the race between module unloading and put_ref() */
	slow_work_put_ref(work);
	slow_work_done_thread_processing(id, work);

	return true;

auto_requeue:
	/* we must complete the enqueue operation
	 * - we transfer our ref on the item back to the appropriate queue
	 * - don't wake another thread up as we're awake already
	 */
	slow_work_mark_time(work);
	if (test_bit(SLOW_WORK_VERY_SLOW, &work->flags))
		list_add_tail(&work->link, &vslow_work_queue);
	else
		list_add_tail(&work->link, &slow_work_queue);
	spin_unlock_irq(&slow_work_queue_lock);
	slow_work_clear_thread_processing(id);
	return true;
}

/**
 * slow_work_sleep_till_thread_needed - Sleep till thread needed by other work
 * work: The work item under execution that wants to sleep
 * _timeout: Scheduler sleep timeout
 *
 * Allow a requeueable work item to sleep on a slow-work processor thread until
 * that thread is needed to do some other work or the sleep is interrupted by
 * some other event.
 *
 * The caller must set up a wake up event before calling this and must have set
 * the appropriate sleep mode (such as TASK_UNINTERRUPTIBLE) and tested its own
 * condition before calling this function as no test is made here.
 *
 * False is returned if there is nothing on the queue; true is returned if the
 * work item should be requeued
 */
bool slow_work_sleep_till_thread_needed(struct slow_work *work,
					signed long *_timeout)
{
	wait_queue_head_t *wfo_wq;
	struct list_head *queue;

	DEFINE_WAIT(wait);

	if (test_bit(SLOW_WORK_VERY_SLOW, &work->flags)) {
		wfo_wq = &vslow_work_queue_waits_for_occupation;
		queue = &vslow_work_queue;
	} else {
		wfo_wq = &slow_work_queue_waits_for_occupation;
		queue = &slow_work_queue;
	}

	if (!list_empty(queue))
		return true;

	add_wait_queue_exclusive(wfo_wq, &wait);
	if (list_empty(queue))
		*_timeout = schedule_timeout(*_timeout);
	finish_wait(wfo_wq, &wait);

	return !list_empty(queue);
}
EXPORT_SYMBOL(slow_work_sleep_till_thread_needed);

/**
 * slow_work_enqueue - Schedule a slow work item for processing
 * @work: The work item to queue
 *
 * Schedule a slow work item for processing.  If the item is already undergoing
 * execution, this guarantees not to re-enter the execution routine until the
 * first execution finishes.
 *
 * The item is pinned by this function as it retains a reference to it, managed
 * through the item operations.  The item is unpinned once it has been
 * executed.
 *
 * An item may hog the thread that is running it for a relatively large amount
 * of time, sufficient, for example, to perform several lookup, mkdir, create
 * and setxattr operations.  It may sleep on I/O and may sleep to obtain locks.
 *
 * Conversely, if a number of items are awaiting processing, it may take some
 * time before any given item is given attention.  The number of threads in the
 * pool may be increased to deal with demand, but only up to a limit.
 *
 * If SLOW_WORK_VERY_SLOW is set on the work item, then it will be placed in
 * the very slow queue, from which only a portion of the threads will be
 * allowed to pick items to execute.  This ensures that very slow items won't
 * overly block ones that are just ordinarily slow.
 *
 * Returns 0 if successful, -EAGAIN if not (or -ECANCELED if cancelled work is
 * attempted queued)
 */
int slow_work_enqueue(struct slow_work *work)
{
	wait_queue_head_t *wfo_wq;
	struct list_head *queue;
	unsigned long flags;
	int ret;

	if (test_bit(SLOW_WORK_CANCELLING, &work->flags))
		return -ECANCELED;

	BUG_ON(slow_work_user_count <= 0);
	BUG_ON(!work);
	BUG_ON(!work->ops);

	/* when honouring an enqueue request, we only promise that we will run
	 * the work function in the future; we do not promise to run it once
	 * per enqueue request
	 *
	 * we use the PENDING bit to merge together repeat requests without
	 * having to disable IRQs and take the spinlock, whilst still
	 * maintaining our promise
	 */
	if (!test_and_set_bit_lock(SLOW_WORK_PENDING, &work->flags)) {
		if (test_bit(SLOW_WORK_VERY_SLOW, &work->flags)) {
			wfo_wq = &vslow_work_queue_waits_for_occupation;
			queue = &vslow_work_queue;
		} else {
			wfo_wq = &slow_work_queue_waits_for_occupation;
			queue = &slow_work_queue;
		}

		spin_lock_irqsave(&slow_work_queue_lock, flags);

		if (unlikely(test_bit(SLOW_WORK_CANCELLING, &work->flags)))
			goto cancelled;

		/* we promise that we will not attempt to execute the work
		 * function in more than one thread simultaneously
		 *
		 * this, however, leaves us with a problem if we're asked to
		 * enqueue the work whilst someone is executing the work
		 * function as simply queueing the work immediately means that
		 * another thread may try executing it whilst it is already
		 * under execution
		 *
		 * to deal with this, we set the ENQ_DEFERRED bit instead of
		 * enqueueing, and the thread currently executing the work
		 * function will enqueue the work item when the work function
		 * returns and it has cleared the EXECUTING bit
		 */
		if (test_bit(SLOW_WORK_EXECUTING, &work->flags)) {
			set_bit(SLOW_WORK_ENQ_DEFERRED, &work->flags);
		} else {
			ret = slow_work_get_ref(work);
			if (ret < 0)
				goto failed;
			slow_work_mark_time(work);
			list_add_tail(&work->link, queue);
			wake_up(&slow_work_thread_wq);

			/* if someone who could be requeued is sleeping on a
			 * thread, then ask them to yield their thread */
			if (work->link.prev == queue)
				wake_up(wfo_wq);
		}

		spin_unlock_irqrestore(&slow_work_queue_lock, flags);
	}
	return 0;

cancelled:
	ret = -ECANCELED;
failed:
	spin_unlock_irqrestore(&slow_work_queue_lock, flags);
	return ret;
}
EXPORT_SYMBOL(slow_work_enqueue);

static int slow_work_wait(void *word)
{
	schedule();
	return 0;
}

/**
 * slow_work_cancel - Cancel a slow work item
 * @work: The work item to cancel
 *
 * This function will cancel a previously enqueued work item. If we cannot
 * cancel the work item, it is guarenteed to have run when this function
 * returns.
 */
void slow_work_cancel(struct slow_work *work)
{
	bool wait = true, put = false;

	set_bit(SLOW_WORK_CANCELLING, &work->flags);
	smp_mb();

	/* if the work item is a delayed work item with an active timer, we
	 * need to wait for the timer to finish _before_ getting the spinlock,
	 * lest we deadlock against the timer routine
	 *
	 * the timer routine will leave DELAYED set if it notices the
	 * CANCELLING flag in time
	 */
	if (test_bit(SLOW_WORK_DELAYED, &work->flags)) {
		struct delayed_slow_work *dwork =
			container_of(work, struct delayed_slow_work, work);
		del_timer_sync(&dwork->timer);
	}

	spin_lock_irq(&slow_work_queue_lock);

	if (test_bit(SLOW_WORK_DELAYED, &work->flags)) {
		/* the timer routine aborted or never happened, so we are left
		 * holding the timer's reference on the item and should just
		 * drop the pending flag and wait for any ongoing execution to
		 * finish */
		struct delayed_slow_work *dwork =
			container_of(work, struct delayed_slow_work, work);

		BUG_ON(timer_pending(&dwork->timer));
		BUG_ON(!list_empty(&work->link));

		clear_bit(SLOW_WORK_DELAYED, &work->flags);
		put = true;
		clear_bit(SLOW_WORK_PENDING, &work->flags);

	} else if (test_bit(SLOW_WORK_PENDING, &work->flags) &&
		   !list_empty(&work->link)) {
		/* the link in the pending queue holds a reference on the item
		 * that we will need to release */
		list_del_init(&work->link);
		wait = false;
		put = true;
		clear_bit(SLOW_WORK_PENDING, &work->flags);

	} else if (test_and_clear_bit(SLOW_WORK_ENQ_DEFERRED, &work->flags)) {
		/* the executor is holding our only reference on the item, so
		 * we merely need to wait for it to finish executing */
		clear_bit(SLOW_WORK_PENDING, &work->flags);
	}

	spin_unlock_irq(&slow_work_queue_lock);

	/* the EXECUTING flag is set by the executor whilst the spinlock is set
	 * and before the item is dequeued - so assuming the above doesn't
	 * actually dequeue it, simply waiting for the EXECUTING flag to be
	 * released here should be sufficient */
	if (wait)
		wait_on_bit(&work->flags, SLOW_WORK_EXECUTING, slow_work_wait,
			    TASK_UNINTERRUPTIBLE);

	clear_bit(SLOW_WORK_CANCELLING, &work->flags);
	if (put)
		slow_work_put_ref(work);
}
EXPORT_SYMBOL(slow_work_cancel);

/*
 * Handle expiry of the delay timer, indicating that a delayed slow work item
 * should now be queued if not cancelled
 */
static void delayed_slow_work_timer(unsigned long data)
{
	wait_queue_head_t *wfo_wq;
	struct list_head *queue;
	struct slow_work *work = (struct slow_work *) data;
	unsigned long flags;
	bool queued = false, put = false, first = false;

	if (test_bit(SLOW_WORK_VERY_SLOW, &work->flags)) {
		wfo_wq = &vslow_work_queue_waits_for_occupation;
		queue = &vslow_work_queue;
	} else {
		wfo_wq = &slow_work_queue_waits_for_occupation;
		queue = &slow_work_queue;
	}

	spin_lock_irqsave(&slow_work_queue_lock, flags);
	if (likely(!test_bit(SLOW_WORK_CANCELLING, &work->flags))) {
		clear_bit(SLOW_WORK_DELAYED, &work->flags);

		if (test_bit(SLOW_WORK_EXECUTING, &work->flags)) {
			/* we discard the reference the timer was holding in
			 * favour of the one the executor holds */
			set_bit(SLOW_WORK_ENQ_DEFERRED, &work->flags);
			put = true;
		} else {
			slow_work_mark_time(work);
			list_add_tail(&work->link, queue);
			queued = true;
			if (work->link.prev == queue)
				first = true;
		}
	}

	spin_unlock_irqrestore(&slow_work_queue_lock, flags);
	if (put)
		slow_work_put_ref(work);
	if (first)
		wake_up(wfo_wq);
	if (queued)
		wake_up(&slow_work_thread_wq);
}

/**
 * delayed_slow_work_enqueue - Schedule a delayed slow work item for processing
 * @dwork: The delayed work item to queue
 * @delay: When to start executing the work, in jiffies from now
 *
 * This is similar to slow_work_enqueue(), but it adds a delay before the work
 * is actually queued for processing.
 *
 * The item can have delayed processing requested on it whilst it is being
 * executed.  The delay will begin immediately, and if it expires before the
 * item finishes executing, the item will be placed back on the queue when it
 * has done executing.
 */
int delayed_slow_work_enqueue(struct delayed_slow_work *dwork,
			      unsigned long delay)
{
	struct slow_work *work = &dwork->work;
	unsigned long flags;
	int ret;

	if (delay == 0)
		return slow_work_enqueue(&dwork->work);

	BUG_ON(slow_work_user_count <= 0);
	BUG_ON(!work);
	BUG_ON(!work->ops);

	if (test_bit(SLOW_WORK_CANCELLING, &work->flags))
		return -ECANCELED;

	if (!test_and_set_bit_lock(SLOW_WORK_PENDING, &work->flags)) {
		spin_lock_irqsave(&slow_work_queue_lock, flags);

		if (test_bit(SLOW_WORK_CANCELLING, &work->flags))
			goto cancelled;

		/* the timer holds a reference whilst it is pending */
		ret = slow_work_get_ref(work);
		if (ret < 0)
			goto cant_get_ref;

		if (test_and_set_bit(SLOW_WORK_DELAYED, &work->flags))
			BUG();
		dwork->timer.expires = jiffies + delay;
		dwork->timer.data = (unsigned long) work;
		dwork->timer.function = delayed_slow_work_timer;
		add_timer(&dwork->timer);

		spin_unlock_irqrestore(&slow_work_queue_lock, flags);
	}

	return 0;

cancelled:
	ret = -ECANCELED;
cant_get_ref:
	spin_unlock_irqrestore(&slow_work_queue_lock, flags);
	return ret;
}
EXPORT_SYMBOL(delayed_slow_work_enqueue);

/*
 * Schedule a cull of the thread pool at some time in the near future
 */
static void slow_work_schedule_cull(void)
{
	mod_timer(&slow_work_cull_timer,
		  round_jiffies(jiffies + SLOW_WORK_CULL_TIMEOUT));
}

/*
 * Worker thread culling algorithm
 */
static bool slow_work_cull_thread(void)
{
	unsigned long flags;
	bool do_cull = false;

	spin_lock_irqsave(&slow_work_queue_lock, flags);

	if (slow_work_cull) {
		slow_work_cull = false;

		if (list_empty(&slow_work_queue) &&
		    list_empty(&vslow_work_queue) &&
		    atomic_read(&slow_work_thread_count) >
		    slow_work_min_threads) {
			slow_work_schedule_cull();
			do_cull = true;
		}
	}

	spin_unlock_irqrestore(&slow_work_queue_lock, flags);
	return do_cull;
}

/*
 * Determine if there is slow work available for dispatch
 */
static inline bool slow_work_available(int vsmax)
{
	return !list_empty(&slow_work_queue) ||
		(!list_empty(&vslow_work_queue) &&
		 atomic_read(&vslow_work_executing_count) < vsmax);
}

/*
 * Worker thread dispatcher
 */
static int slow_work_thread(void *_data)
{
	int vsmax, id;

	DEFINE_WAIT(wait);

	set_freezable();
	set_user_nice(current, -5);

	/* allocate ourselves an ID */
	spin_lock_irq(&slow_work_queue_lock);
	id = find_first_zero_bit(slow_work_ids, SLOW_WORK_THREAD_LIMIT);
	BUG_ON(id < 0 || id >= SLOW_WORK_THREAD_LIMIT);
	__set_bit(id, slow_work_ids);
	slow_work_set_thread_pid(id, current->pid);
	spin_unlock_irq(&slow_work_queue_lock);

	sprintf(current->comm, "kslowd%03u", id);

	for (;;) {
		vsmax = vslow_work_proportion;
		vsmax *= atomic_read(&slow_work_thread_count);
		vsmax /= 100;

		prepare_to_wait_exclusive(&slow_work_thread_wq, &wait,
					  TASK_INTERRUPTIBLE);
		if (!freezing(current) &&
		    !slow_work_threads_should_exit &&
		    !slow_work_available(vsmax) &&
		    !slow_work_cull)
			schedule();
		finish_wait(&slow_work_thread_wq, &wait);

		try_to_freeze();

		vsmax = vslow_work_proportion;
		vsmax *= atomic_read(&slow_work_thread_count);
		vsmax /= 100;

		if (slow_work_available(vsmax) && slow_work_execute(id)) {
			cond_resched();
			if (list_empty(&slow_work_queue) &&
			    list_empty(&vslow_work_queue) &&
			    atomic_read(&slow_work_thread_count) >
			    slow_work_min_threads)
				slow_work_schedule_cull();
			continue;
		}

		if (slow_work_threads_should_exit)
			break;

		if (slow_work_cull && slow_work_cull_thread())
			break;
	}

	spin_lock_irq(&slow_work_queue_lock);
	slow_work_set_thread_pid(id, 0);
	__clear_bit(id, slow_work_ids);
	spin_unlock_irq(&slow_work_queue_lock);

	if (atomic_dec_and_test(&slow_work_thread_count))
		complete_and_exit(&slow_work_last_thread_exited, 0);
	return 0;
}

/*
 * Handle thread cull timer expiration
 */
static void slow_work_cull_timeout(unsigned long data)
{
	slow_work_cull = true;
	wake_up(&slow_work_thread_wq);
}

/*
 * Start a new slow work thread
 */
static void slow_work_new_thread_execute(struct slow_work *work)
{
	struct task_struct *p;

	if (slow_work_threads_should_exit)
		return;

	if (atomic_read(&slow_work_thread_count) >= slow_work_max_threads)
		return;

	if (!mutex_trylock(&slow_work_user_lock))
		return;

	slow_work_may_not_start_new_thread = true;
	atomic_inc(&slow_work_thread_count);
	p = kthread_run(slow_work_thread, NULL, "kslowd");
	if (IS_ERR(p)) {
		printk(KERN_DEBUG "Slow work thread pool: OOM\n");
		if (atomic_dec_and_test(&slow_work_thread_count))
			BUG(); /* we're running on a slow work thread... */
		mod_timer(&slow_work_oom_timer,
			  round_jiffies(jiffies + SLOW_WORK_OOM_TIMEOUT));
	} else {
		/* ratelimit the starting of new threads */
		mod_timer(&slow_work_oom_timer, jiffies + 1);
	}

	mutex_unlock(&slow_work_user_lock);
}

static const struct slow_work_ops slow_work_new_thread_ops = {
	.owner		= THIS_MODULE,
	.execute	= slow_work_new_thread_execute,
#ifdef CONFIG_SLOW_WORK_DEBUG
	.desc		= slow_work_new_thread_desc,
#endif
};

/*
 * post-OOM new thread start suppression expiration
 */
static void slow_work_oom_timeout(unsigned long data)
{
	slow_work_may_not_start_new_thread = false;
}

#ifdef CONFIG_SYSCTL
/*
 * Handle adjustment of the minimum number of threads
 */
static int slow_work_min_threads_sysctl(struct ctl_table *table, int write,
					void __user *buffer,
					size_t *lenp, loff_t *ppos)
{
	int ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos);
	int n;

	if (ret == 0) {
		mutex_lock(&slow_work_user_lock);
		if (slow_work_user_count > 0) {
			/* see if we need to start or stop threads */
			n = atomic_read(&slow_work_thread_count) -
				slow_work_min_threads;

			if (n < 0 && !slow_work_may_not_start_new_thread)
				slow_work_enqueue(&slow_work_new_thread);
			else if (n > 0)
				slow_work_schedule_cull();
		}
		mutex_unlock(&slow_work_user_lock);
	}

	return ret;
}

/*
 * Handle adjustment of the maximum number of threads
 */
static int slow_work_max_threads_sysctl(struct ctl_table *table, int write,
					void __user *buffer,
					size_t *lenp, loff_t *ppos)
{
	int ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos);
	int n;

	if (ret == 0) {
		mutex_lock(&slow_work_user_lock);
		if (slow_work_user_count > 0) {
			/* see if we need to stop threads */
			n = slow_work_max_threads -
				atomic_read(&slow_work_thread_count);

			if (n < 0)
				slow_work_schedule_cull();
		}
		mutex_unlock(&slow_work_user_lock);
	}

	return ret;
}
#endif /* CONFIG_SYSCTL */

/**
 * slow_work_register_user - Register a user of the facility
 * @module: The module about to make use of the facility
 *
 * Register a user of the facility, starting up the initial threads if there
 * aren't any other users at this point.  This will return 0 if successful, or
 * an error if not.
 */
int slow_work_register_user(struct module *module)
{
	struct task_struct *p;
	int loop;

	mutex_lock(&slow_work_user_lock);

	if (slow_work_user_count == 0) {
		printk(KERN_NOTICE "Slow work thread pool: Starting up\n");
		init_completion(&slow_work_last_thread_exited);

		slow_work_threads_should_exit = false;
		slow_work_init(&slow_work_new_thread,
			       &slow_work_new_thread_ops);
		slow_work_may_not_start_new_thread = false;
		slow_work_cull = false;

		/* start the minimum number of threads */
		for (loop = 0; loop < slow_work_min_threads; loop++) {
			atomic_inc(&slow_work_thread_count);
			p = kthread_run(slow_work_thread, NULL, "kslowd");
			if (IS_ERR(p))
				goto error;
		}
		printk(KERN_NOTICE "Slow work thread pool: Ready\n");
	}

	slow_work_user_count++;
	mutex_unlock(&slow_work_user_lock);
	return 0;

error:
	if (atomic_dec_and_test(&slow_work_thread_count))
		complete(&slow_work_last_thread_exited);
	if (loop > 0) {
		printk(KERN_ERR "Slow work thread pool:"
		       " Aborting startup on ENOMEM\n");
		slow_work_threads_should_exit = true;
		wake_up_all(&slow_work_thread_wq);
		wait_for_completion(&slow_work_last_thread_exited);
		printk(KERN_ERR "Slow work thread pool: Aborted\n");
	}
	mutex_unlock(&slow_work_user_lock);
	return PTR_ERR(p);
}
EXPORT_SYMBOL(slow_work_register_user);

/*
 * wait for all outstanding items from the calling module to complete
 * - note that more items may be queued whilst we're waiting
 */
static void slow_work_wait_for_items(struct module *module)
{
#ifdef CONFIG_MODULES
	DECLARE_WAITQUEUE(myself, current);
	struct slow_work *work;
	int loop;

	mutex_lock(&slow_work_unreg_sync_lock);
	add_wait_queue(&slow_work_unreg_wq, &myself);

	for (;;) {
		spin_lock_irq(&slow_work_queue_lock);

		/* first of all, we wait for the last queued item in each list
		 * to be processed */
		list_for_each_entry_reverse(work, &vslow_work_queue, link) {
			if (work->owner == module) {
				set_current_state(TASK_UNINTERRUPTIBLE);
				slow_work_unreg_work_item = work;
				goto do_wait;
			}
		}
		list_for_each_entry_reverse(work, &slow_work_queue, link) {
			if (work->owner == module) {
				set_current_state(TASK_UNINTERRUPTIBLE);
				slow_work_unreg_work_item = work;
				goto do_wait;
			}
		}

		/* then we wait for the items being processed to finish */
		slow_work_unreg_module = module;
		smp_mb();
		for (loop = 0; loop < SLOW_WORK_THREAD_LIMIT; loop++) {
			if (slow_work_thread_processing[loop] == module)
				goto do_wait;
		}
		spin_unlock_irq(&slow_work_queue_lock);
		break; /* okay, we're done */

	do_wait:
		spin_unlock_irq(&slow_work_queue_lock);
		schedule();
		slow_work_unreg_work_item = NULL;
		slow_work_unreg_module = NULL;
	}

	remove_wait_queue(&slow_work_unreg_wq, &myself);
	mutex_unlock(&slow_work_unreg_sync_lock);
#endif /* CONFIG_MODULES */
}

/**
 * slow_work_unregister_user - Unregister a user of the facility
 * @module: The module whose items should be cleared
 *
 * Unregister a user of the facility, killing all the threads if this was the
 * last one.
 *
 * This waits for all the work items belonging to the nominated module to go
 * away before proceeding.
 */
void slow_work_unregister_user(struct module *module)
{
	/* first of all, wait for all outstanding items from the calling module
	 * to complete */
	if (module)
		slow_work_wait_for_items(module);

	/* then we can actually go about shutting down the facility if need
	 * be */
	mutex_lock(&slow_work_user_lock);

	BUG_ON(slow_work_user_count <= 0);

	slow_work_user_count--;
	if (slow_work_user_count == 0) {
		printk(KERN_NOTICE "Slow work thread pool: Shutting down\n");
		slow_work_threads_should_exit = true;
		del_timer_sync(&slow_work_cull_timer);
		del_timer_sync(&slow_work_oom_timer);
		wake_up_all(&slow_work_thread_wq);
		wait_for_completion(&slow_work_last_thread_exited);
		printk(KERN_NOTICE "Slow work thread pool:"
		       " Shut down complete\n");
	}

	mutex_unlock(&slow_work_user_lock);
}
EXPORT_SYMBOL(slow_work_unregister_user);

/*
 * Initialise the slow work facility
 */
static int __init init_slow_work(void)
{
	unsigned nr_cpus = num_possible_cpus();

	if (slow_work_max_threads < nr_cpus)
		slow_work_max_threads = nr_cpus;
#ifdef CONFIG_SYSCTL
	if (slow_work_max_max_threads < nr_cpus * 2)
		slow_work_max_max_threads = nr_cpus * 2;
#endif
#ifdef CONFIG_SLOW_WORK_DEBUG
	{
		struct dentry *dbdir;

		dbdir = debugfs_create_dir("slow_work", NULL);
		if (dbdir && !IS_ERR(dbdir))
			debugfs_create_file("runqueue", S_IFREG | 0400, dbdir,
					    NULL, &slow_work_runqueue_fops);
	}
#endif
	return 0;
}

subsys_initcall(init_slow_work);
