All of lore.kernel.org
 help / color / mirror / Atom feed
From: Dave Jones <davej@redhat.com>
To: linux-sparse@vger.kernel.org
Subject: annotating semaphores.
Date: Wed, 12 Dec 2007 15:00:53 -0500	[thread overview]
Message-ID: <20071212200053.GA19747@redhat.com> (raw)

Today I came across a bug in the kernel cpufreq code where
we were missing a bunch of up_write() calls in error paths
of a function.

I've been trying to get sparse's context checking to pick up
on the errors and failing.  The kernel patch below is what I have
so far, but it seems to report no output whatsoever.
What am I missing ?

	Dave

diff --git a/include/asm-x86/rwsem.h b/include/asm-x86/rwsem.h
index 041906f..3111853 100644
--- a/include/asm-x86/rwsem.h
+++ b/include/asm-x86/rwsem.h
@@ -106,6 +106,7 @@ LOCK_PREFIX	"  incl      (%%eax)\n\t" /* adds 0x00000001, returns the old value
 		: "+m" (sem->count)
 		: "a" (sem)
 		: "memory", "cc");
+	__acquire(sem);
 }
 
 /*
@@ -128,6 +129,7 @@ LOCK_PREFIX	"  cmpxchgl  %2,%0\n\t"
 		: "+m" (sem->count), "=&a" (result), "=&r" (tmp)
 		: "i" (RWSEM_ACTIVE_READ_BIAS)
 		: "memory", "cc");
+	__acquire(sem);
 	return result>=0 ? 1 : 0;
 }
 
@@ -167,6 +169,7 @@ static inline int __down_write_trylock(struct rw_semaphore *sem)
 				  RWSEM_ACTIVE_WRITE_BIAS);
 	if (ret == RWSEM_UNLOCKED_VALUE)
 		return 1;
+	__acquire(sem);
 	return 0;
 }
 
@@ -186,6 +189,7 @@ LOCK_PREFIX	"  xadd      %%edx,(%%eax)\n\t" /* subtracts 1, returns the old valu
 		: "+m" (sem->count), "=d" (tmp)
 		: "a" (sem), "1" (tmp)
 		: "memory", "cc");
+	__release(sem);
 }
 
 /*
@@ -204,6 +208,7 @@ LOCK_PREFIX	"  xaddl     %%edx,(%%eax)\n\t" /* tries to transition 0xffff0001 ->
 		: "+m" (sem->count)
 		: "a" (sem), "i" (-RWSEM_ACTIVE_WRITE_BIAS)
 		: "memory", "cc", "edx");
+	__release(sem);
 }
 
 /*
diff --git a/include/linux/cpuidle.h b/include/linux/cpuidle.h
index c4e0016..cf110b0 100644
diff --git a/include/linux/rwsem-spinlock.h b/include/linux/rwsem-spinlock.h
index 813cee1..90a4b2b 100644
--- a/include/linux/rwsem-spinlock.h
+++ b/include/linux/rwsem-spinlock.h
@@ -60,13 +60,13 @@ do {								\
 	__init_rwsem((sem), #sem, &__key);			\
 } while (0)
 
-extern void FASTCALL(__down_read(struct rw_semaphore *sem));
-extern int FASTCALL(__down_read_trylock(struct rw_semaphore *sem));
-extern void FASTCALL(__down_write(struct rw_semaphore *sem));
+extern void FASTCALL(__down_read(struct rw_semaphore *sem)) __acquires(sem);
+extern int FASTCALL(__down_read_trylock(struct rw_semaphore *sem)) __acquires(sem);
+extern void FASTCALL(__down_write(struct rw_semaphore *sem)) __acquires(sem);
 extern void FASTCALL(__down_write_nested(struct rw_semaphore *sem, int subclass));
-extern int FASTCALL(__down_write_trylock(struct rw_semaphore *sem));
-extern void FASTCALL(__up_read(struct rw_semaphore *sem));
-extern void FASTCALL(__up_write(struct rw_semaphore *sem));
+extern int FASTCALL(__down_write_trylock(struct rw_semaphore *sem) __acquires(sem));
+extern void FASTCALL(__up_read(struct rw_semaphore *sem)) __releases(sem);
+extern void FASTCALL(__up_write(struct rw_semaphore *sem)) __releases(sem);
 extern void FASTCALL(__downgrade_write(struct rw_semaphore *sem));
 
 static inline int rwsem_is_locked(struct rw_semaphore *sem)
diff --git a/lib/rwsem-spinlock.c b/lib/rwsem-spinlock.c
index c4cfd6c..c13d112 100644
--- a/lib/rwsem-spinlock.c
+++ b/lib/rwsem-spinlock.c
@@ -162,6 +162,7 @@ void fastcall __sched __down_read(struct rw_semaphore *sem)
 
 	tsk->state = TASK_RUNNING;
  out:
+	__acquire(sem);
 	;
 }
 
@@ -184,6 +185,7 @@ int fastcall __down_read_trylock(struct rw_semaphore *sem)
 
 	spin_unlock_irqrestore(&sem->wait_lock, flags);
 
+	__acquire(sem);
 	return ret;
 }
 
@@ -228,6 +230,7 @@ void fastcall __sched __down_write_nested(struct rw_semaphore *sem, int subclass
 
 	tsk->state = TASK_RUNNING;
  out:
+	__acquire(sem);
 	;
 }
 
@@ -253,6 +256,7 @@ int fastcall __down_write_trylock(struct rw_semaphore *sem)
 	}
 
 	spin_unlock_irqrestore(&sem->wait_lock, flags);
+	__acquire(sem);
 
 	return ret;
 }
@@ -270,6 +274,7 @@ void fastcall __up_read(struct rw_semaphore *sem)
 		sem = __rwsem_wake_one_writer(sem);
 
 	spin_unlock_irqrestore(&sem->wait_lock, flags);
+	__release(sem);
 }
 
 /*
@@ -286,6 +291,7 @@ void fastcall __up_write(struct rw_semaphore *sem)
 		sem = __rwsem_do_wake(sem, 1);
 
 	spin_unlock_irqrestore(&sem->wait_lock, flags);
+	__release(sem);
 }
 
 /*
-- 
http://www.codemonkey.org.uk

             reply	other threads:[~2007-12-12 20:00 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-12-12 20:00 Dave Jones [this message]
2007-12-13 22:00 ` annotating semaphores Christopher Li
2007-12-13 22:05   ` Dave Jones

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20071212200053.GA19747@redhat.com \
    --to=davej@redhat.com \
    --cc=linux-sparse@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.