/* periodic_work.c
 *
 * Copyright (C) 2010 - 2015 UNISYS CORPORATION
 * All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2, as published by the Free Software Foundation.
 *
 * 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, GOOD TITLE or
 * NON INFRINGEMENT.  See the GNU General Public License for more
 * details.
 */

/*
 *  Helper functions to schedule periodic work in Linux kernel mode.
 */
#include <linux/sched.h>

#include "periodic_work.h"

#define MYDRVNAME "periodic_work"

struct periodic_work {
	rwlock_t lock;
	struct delayed_work work;
	void (*workfunc)(void *);
	void *workfuncarg;
	bool is_scheduled;
	bool want_to_stop;
	ulong jiffy_interval;
	struct workqueue_struct *workqueue;
	const char *devnam;
};

static void periodic_work_func(struct work_struct *work)
{
	struct periodic_work *pw;

	pw = container_of(work, struct periodic_work, work.work);
	(*pw->workfunc)(pw->workfuncarg);
}

struct periodic_work
*visor_periodic_work_create(ulong jiffy_interval,
			    struct workqueue_struct *workqueue,
			    void (*workfunc)(void *),
			    void *workfuncarg,
			    const char *devnam)
{
	struct periodic_work *pw;

	pw = kzalloc(sizeof(*pw), GFP_KERNEL | __GFP_NORETRY);
	if (!pw)
		return NULL;

	rwlock_init(&pw->lock);
	pw->jiffy_interval = jiffy_interval;
	pw->workqueue = workqueue;
	pw->workfunc = workfunc;
	pw->workfuncarg = workfuncarg;
	pw->devnam = devnam;
	return pw;
}
EXPORT_SYMBOL_GPL(visor_periodic_work_create);

void visor_periodic_work_destroy(struct periodic_work *pw)
{
	kfree(pw);
}
EXPORT_SYMBOL_GPL(visor_periodic_work_destroy);

/** Call this from your periodic work worker function to schedule the next
 *  call.
 *  If this function returns false, there was a failure and the
 *  periodic work is no longer scheduled
 */
bool visor_periodic_work_nextperiod(struct periodic_work *pw)
{
	bool rc = false;

	write_lock(&pw->lock);
	if (pw->want_to_stop) {
		pw->is_scheduled = false;
		pw->want_to_stop = false;
		rc = true;  /* yes, true; see visor_periodic_work_stop() */
		goto unlock;
	} else if (!queue_delayed_work(pw->workqueue, &pw->work,
				       pw->jiffy_interval)) {
		pw->is_scheduled = false;
		rc = false;
		goto unlock;
	}
	rc = true;
unlock:
	write_unlock(&pw->lock);
	return rc;
}
EXPORT_SYMBOL_GPL(visor_periodic_work_nextperiod);

/** This function returns true iff new periodic work was actually started.
 *  If this function returns false, then no work was started
 *  (either because it was already started, or because of a failure).
 */
bool visor_periodic_work_start(struct periodic_work *pw)
{
	bool rc = false;

	write_lock(&pw->lock);
	if (pw->is_scheduled) {
		rc = false;
		goto unlock;
	}
	if (pw->want_to_stop) {
		rc = false;
		goto unlock;
	}
	INIT_DELAYED_WORK(&pw->work, &periodic_work_func);
	if (!queue_delayed_work(pw->workqueue, &pw->work,
				pw->jiffy_interval)) {
		rc = false;
		goto unlock;
	}
	pw->is_scheduled = true;
	rc = true;
unlock:
	write_unlock(&pw->lock);
	return rc;
}
EXPORT_SYMBOL_GPL(visor_periodic_work_start);

/** This function returns true iff your call actually stopped the periodic
 *  work.
 *
 *  -- PAY ATTENTION... this is important --
 *
 *  NO NO #1
 *
 *     Do NOT call this function from some function that is running on the
 *     same workqueue as the work you are trying to stop might be running
 *     on!  If you violate this rule, visor_periodic_work_stop() MIGHT work,
 *     but it also MIGHT get hung up in an infinite loop saying
 *     "waiting for delayed work...".  This will happen if the delayed work
 *     you are trying to cancel has been put in the workqueue list, but can't
 *     run yet because we are running that same workqueue thread right now.
 *
 *     Bottom line: If you need to call visor_periodic_work_stop() from a
 *     workitem, be sure the workitem is on a DIFFERENT workqueue than the
 *     workitem that you are trying to cancel.
 *
 *     If I could figure out some way to check for this "no no" condition in
 *     the code, I would.  It would have saved me the trouble of writing this
 *     long comment.  And also, don't think this is some "theoretical" race
 *     condition.  It is REAL, as I have spent the day chasing it.
 *
 *  NO NO #2
 *
 *     Take close note of the locks that you own when you call this function.
 *     You must NOT own any locks that are needed by the periodic work
 *     function that is currently installed.  If you DO, a deadlock may result,
 *     because stopping the periodic work often involves waiting for the last
 *     iteration of the periodic work function to complete.  Again, if you hit
 *     this deadlock, you will get hung up in an infinite loop saying
 *     "waiting for delayed work...".
 */
bool visor_periodic_work_stop(struct periodic_work *pw)
{
	bool stopped_something = false;

	write_lock(&pw->lock);
	stopped_something = pw->is_scheduled && (!pw->want_to_stop);
	while (pw->is_scheduled) {
		pw->want_to_stop = true;
		if (cancel_delayed_work(&pw->work)) {
			/* We get here if the delayed work was pending as
			 * delayed work, but was NOT run.
			 */
			WARN_ON(!pw->is_scheduled);
			pw->is_scheduled = false;
		} else {
			/* If we get here, either the delayed work:
			 * - was run, OR,
			 * - is running RIGHT NOW on another processor, OR,
			 * - wasn't even scheduled (there is a miniscule
			 *   timing window where this could be the case)
			 * flush_workqueue() would make sure it is finished
			 * executing, but that still isn't very useful, which
			 * explains the loop...
			 */
		}
		if (pw->is_scheduled) {
			write_unlock(&pw->lock);
			schedule_timeout_interruptible(msecs_to_jiffies(10));
			write_lock(&pw->lock);
		} else {
			pw->want_to_stop = false;
		}
	}
	write_unlock(&pw->lock);
	return stopped_something;
}
EXPORT_SYMBOL_GPL(visor_periodic_work_stop);
