From: Mikael Pettersson <mikpe@user.it.uu.se>

This patch fixes an illegal sleep issue in perfctr's virtualised
per-process counters: a spinlock is taken around calls to
perfctr_cpu_{reserve,release}() which sleeps on a mutex.  Change the
spinlock to a mutex too.

The problem was reported by Sami Farin.

Strangely enough, DEBUG_SPINLOCK_SLEEP only triggers if I also have PREEMPT
enabled.  Is it supposed to be like that?

Signed-off-by: Mikael Pettersson <mikpe@csd.uu.se>
Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 25-akpm/drivers/perfctr/virtual.c |   10 +++++-----
 1 files changed, 5 insertions(+), 5 deletions(-)

diff -puN drivers/perfctr/virtual.c~virtual-perfctr-illegal-sleep drivers/perfctr/virtual.c
--- 25/drivers/perfctr/virtual.c~virtual-perfctr-illegal-sleep	Wed Sep 22 16:37:37 2004
+++ 25-akpm/drivers/perfctr/virtual.c	Wed Sep 22 16:37:37 2004
@@ -111,7 +111,7 @@ static inline void vperfctr_task_unlock(
  ****************************************************************/
 
 /* XXX: perhaps relax this to number of _live_ perfctrs */
-static spinlock_t nrctrs_lock = SPIN_LOCK_UNLOCKED;
+static DECLARE_MUTEX(nrctrs_mutex);
 static int nrctrs;
 static const char this_service[] = __FILE__;
 
@@ -120,13 +120,13 @@ static int inc_nrctrs(void)
 	const char *other;
 
 	other = NULL;
-	spin_lock(&nrctrs_lock);
+	down(&nrctrs_mutex);
 	if (++nrctrs == 1) {
 		other = perfctr_cpu_reserve(this_service);
 		if (other)
 			nrctrs = 0;
 	}
-	spin_unlock(&nrctrs_lock);
+	up(&nrctrs_mutex);
 	if (other) {
 		printk(KERN_ERR __FILE__
 		       ": cannot operate, perfctr hardware taken by '%s'\n",
@@ -139,10 +139,10 @@ static int inc_nrctrs(void)
 
 static void dec_nrctrs(void)
 {
-	spin_lock(&nrctrs_lock);
+	down(&nrctrs_mutex);
 	if (--nrctrs == 0)
 		perfctr_cpu_release(this_service);
-	spin_unlock(&nrctrs_lock);
+	up(&nrctrs_mutex);
 }
 
 /* Allocate a `struct vperfctr'. Claim and reserve
_