/* 
 *    Debugging versions of SMP locking primitives.
 *
 *    Copyright (C) 2004 Thibaut VARENE <varenet@esiee.fr>
 *
 *    Some code stollen from alpha & sparc64 ;)
 *
 *    This program is free software; you can redistribute it and/or modify
 *    it under the terms of the GNU General Public License as published by
 *    the Free Software Foundation; either version 2 of the License, or
 *    (at your option) any later version.
 *
 *    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.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with this program; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 *    We use pdc_printf() throughout the file for all output messages, to avoid
 *    losing messages because of disabled interrupts. Since we're using these
 *    messages for debugging purposes, it makes sense not to send them to the
 *    linux console.
 */


#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/spinlock.h>
#include <linux/hardirq.h>	/* in_interrupt() */
#include <asm/system.h>
#include <asm/hardirq.h>	/* in_interrupt() */
#include <asm/pdc.h>

#undef INIT_STUCK
#define INIT_STUCK 1L << 30

#ifdef CONFIG_DEBUG_SPINLOCK


void _dbg_spin_lock(spinlock_t * lock, const char *base_file, int line_no)
{
	volatile unsigned int *a;
	long stuck = INIT_STUCK;
	void *inline_pc = __builtin_return_address(0);
	unsigned long started = jiffies;
	int printed = 0;
	int cpu = smp_processor_id();

try_again:

	/* Do the actual locking */
	/* <T-Bone> ggg: we can't get stuck on the outter loop?
	 * <ggg> T-Bone: We can hit the outer loop
	 *	alot if multiple CPUs are constantly racing for a lock
	 *	and the backplane is NOT fair about which CPU sees
	 *	the update first. But it won't hang since every failed
	 *	attempt will drop us back into the inner loop and
	 *	decrement `stuck'.
	 * <ggg> K-class and some of the others are NOT fair in the HW
	 * 	implementation so we could see false positives.
	 * 	But fixing the lock contention is easier than
	 * 	fixing the HW to be fair.
	 * <tausq> __ldcw() returns 1 if we get the lock; otherwise we
	 * 	spin until the value of the lock changes, or we time out.
	 */
	mb();
	a = __ldcw_align(lock);
	while (stuck && (__ldcw(a) == 0))
		while ((*a == 0) && --stuck);
	mb();

	if (unlikely(stuck <= 0)) {
		pdc_printf(
			"%s:%d: spin_lock(%s/%p) stuck in %s at %p(%d)"
			" owned by %s:%d in %s at %p(%d)\n",
			base_file, line_no, lock->module, lock,
			current->comm, inline_pc, cpu,
			lock->bfile, lock->bline, lock->task->comm,
			lock->previous, lock->oncpu);
		stuck = INIT_STUCK;
		printed = 1;
		goto try_again;
	}

	/* Exiting.  Got the lock.  */
	lock->oncpu = cpu;
	lock->previous = inline_pc;
	lock->task = current;
	lock->bfile = (char *)base_file;
	lock->bline = line_no;

	if (unlikely(printed)) {
		pdc_printf(
			"%s:%d: spin_lock grabbed in %s at %p(%d) %ld ticks\n",
			base_file, line_no, current->comm, inline_pc,
			cpu, jiffies - started);
	}
}

void _dbg_spin_unlock(spinlock_t * lock, const char *base_file, int line_no)
{
	CHECK_LOCK(lock);
	volatile unsigned int *a;
	mb();
	a = __ldcw_align(lock);
	if (unlikely((*a != 0) && lock->babble)) {
		lock->babble--;
		pdc_printf(
			"%s:%d: spin_unlock(%s:%p) not locked\n",
			base_file, line_no, lock->module, lock);
	}
	*a = 1;	
	mb();
}

int _dbg_spin_trylock(spinlock_t * lock, const char *base_file, int line_no)
{
	int ret;
	volatile unsigned int *a;
	mb();
	a = __ldcw_align(lock);
	ret = (__ldcw(a) != 0);
	mb();
	if (ret) {
		lock->oncpu = smp_processor_id();
		lock->previous = __builtin_return_address(0);
		lock->task = current;
	} else {
		lock->bfile = (char *)base_file;
		lock->bline = line_no;
	}
	return ret;
}

#endif /* CONFIG_DEBUG_SPINLOCK */

#ifdef CONFIG_DEBUG_RWLOCK

/* Interrupts trouble detailed explanation, thx Grant:
 *
 * o writer (wants to modify data) attempts to acquire the rwlock
 * o He gets the write lock.
 * o Interupts are still enabled, we take an interrupt with the
 *   write still holding the lock.
 * o interrupt handler tries to acquire the rwlock for read.
 * o deadlock since the writer can't release it at this point.
 * 
 * In general, any use of spinlocks that competes between "base"
 * level and interrupt level code will risk deadlock. Interrupts
 * need to be disabled in the base level routines to avoid it.
 * Or more precisely, only the IRQ the base level routine
 * is competing with for the lock.  But it's more efficient/faster
 * to just disable all interrupts on that CPU to guarantee
 * once it gets the lock it can release it quickly too.
 */
 
void _dbg_write_lock(rwlock_t *rw, const char *bfile, int bline)
{
	void *inline_pc = __builtin_return_address(0);
	unsigned long started = jiffies;
	long stuck = INIT_STUCK;
	int printed = 0;
	int cpu = smp_processor_id();
	
	if(unlikely(in_interrupt())) {	/* acquiring write lock in interrupt context, bad idea */
		pdc_printf("write_lock caller: %s:%d, IRQs enabled,\n", bfile, bline);
		BUG();
	}

	/* Note: if interrupts are disabled (which is most likely), the printk
	will never show on the console. We might need a polling method to flush
	the dmesg buffer anyhow. */
	
retry:
	_raw_spin_lock(&rw->lock);

	if(rw->counter != 0) {
		/* this basically never happens */
		_raw_spin_unlock(&rw->lock);
		
		stuck--;
		if ((unlikely(stuck <= 0)) && (rw->counter < 0)) {
			pdc_printf(
				"%s:%d: write_lock stuck on writer"
				" in %s at %p(%d) %ld ticks\n",
				bfile, bline, current->comm, inline_pc,
				cpu, jiffies - started);
			stuck = INIT_STUCK;
			printed = 1;
		}
		else if (unlikely(stuck <= 0)) {
			pdc_printf(
				"%s:%d: write_lock stuck on reader"
				" in %s at %p(%d) %ld ticks\n",
				bfile, bline, current->comm, inline_pc,
				cpu, jiffies - started);
			stuck = INIT_STUCK;
			printed = 1;
		}
		
		while(rw->counter != 0);

		goto retry;
	}

	/* got it.  now leave without unlocking */
	rw->counter = -1; /* remember we are locked */

	if (unlikely(printed)) {
		pdc_printf(
			"%s:%d: write_lock grabbed in %s at %p(%d) %ld ticks\n",
			bfile, bline, current->comm, inline_pc,
			cpu, jiffies - started);
	}
}

int _dbg_write_trylock(rwlock_t *rw, const char *bfile, int bline)
{
#if 0
	void *inline_pc = __builtin_return_address(0);
	int cpu = smp_processor_id();
#endif
	
	if(unlikely(in_interrupt())) {	/* acquiring write lock in interrupt context, bad idea */
		pdc_printf("write_lock caller: %s:%d, IRQs enabled,\n", bfile, bline);
		BUG();
	}

	/* Note: if interrupts are disabled (which is most likely), the printk
	will never show on the console. We might need a polling method to flush
	the dmesg buffer anyhow. */
	
	_raw_spin_lock(&rw->lock);

	if(rw->counter != 0) {
		/* this basically never happens */
		_raw_spin_unlock(&rw->lock);
		
		
		return 0;
	}

	/* got it.  now leave without unlocking */
	rw->counter = -1; /* remember we are locked */
#if 0
	pdc_printf("%s:%d: try write_lock grabbed in %s at %p(%d)\n",
		   bfile, bline, current->comm, inline_pc, cpu);
#endif
}

void _dbg_read_lock(rwlock_t * rw, const char *bfile, int bline)
{
#if 0
	void *inline_pc = __builtin_return_address(0);
	unsigned long started = jiffies;
	int cpu = smp_processor_id();
#endif
	unsigned long flags;

	local_irq_save(flags);
	_raw_spin_lock(&rw->lock); 

	rw->counter++;
#if 0
	pdc_printf(
		"%s:%d: read_lock grabbed in %s at %p(%d) %ld ticks\n",
		bfile, bline, current->comm, inline_pc,
		cpu, jiffies - started);
#endif
	_raw_spin_unlock(&rw->lock);
	local_irq_restore(flags);
}

#endif /* CONFIG_DEBUG_RWLOCK */
