mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PREEMPT_RT] [PATCH 1/2] Introduce write_trylock_irqsave
@ 2007-05-10  6:37 Sripathi Kodi
  0 siblings, 0 replies; only message in thread
From: Sripathi Kodi @ 2007-05-10  6:37 UTC (permalink / raw)
  To: Ingo Molnar; +Cc: linux-kernel, Andrew Morton, Oleg Nesterov, Roland McGrath

Hi Ingo,

I am trying to fix the BUG I mentioned here: 
http://lkml.org/lkml/2007/04/20/41. The problem arises because 
ptrace_attach() calls local_irq_disable() and write_trylock() and later calls 
write_unlock_irq. On -rt write_unlock_irq doesn't restore irqs for regular 
rwlock_t, so irqs remain disabled. I have also sent patches for mainline 
kernel. Please refer http://lkml.org/lkml/2007/05/09/76 , 
http://lkml.org/lkml/2007/05/09/79 and http://lkml.org/lkml/2007/05/09/550

This patch adds write_trylock_irqsave function.

Signed-off-by: Sripathi Kodi <sripathik@in.ibm.com>

Index: linux-2.6.21-rt1_patch/include/linux/spinlock.h
===================================================================
--- linux-2.6.21-rt1_patch.orig/include/linux/spinlock.h	2007-05-10 
11:28:35.000000000 +0530
+++ linux-2.6.21-rt1_patch/include/linux/spinlock.h	2007-05-10 
11:29:13.000000000 +0530
@@ -323,6 +323,7 @@
 
 # define _read_trylock(rwl)	rt_read_trylock(rwl)
 # define _write_trylock(rwl)	rt_write_trylock(rwl)
+#define _write_trylock_irqsave(rwl, flags)  rt_write_trylock_irqsave(rwl, 
flags)
 
 # define _read_lock(rwl)	rt_read_lock(rwl)
 # define _write_lock(rwl)	rt_write_lock(rwl)
@@ -398,6 +399,19 @@
 	else __bad_rwlock_type();					\
 } while (0)
 
+#define PICK_RW_OP2_RET(optype, op, lock, flags)			\
+({									\
+	unsigned long __ret;						\
+									\
+	if (TYPE_EQUAL((lock), raw_rwlock_t))				\
+		__ret = __##optype##op((raw_rwlock_t *)(lock), flags);	\
+	else if (TYPE_EQUAL(lock, rwlock_t))				\
+		__ret = _##optype##op((rwlock_t *)(lock), flags);	\
+	else __bad_rwlock_type();					\
+									\
+	__ret;								\
+})
+
 #ifdef CONFIG_DEBUG_SPINLOCK
   extern void __raw_spin_lock_init(raw_spinlock_t *lock, const char *name,
 				   struct lock_class_key *key);
@@ -473,6 +487,9 @@
 //#define write_trylock(lock)	_write_trylock(lock)
 #define write_trylock(lock)	__cond_lock(lock, PICK_RW_OP_RET(write, _trylock, 
lock))
 
+#define write_trylock_irqsave(lock, flags) \
+	__cond_lock(lock, PICK_RW_OP2_RET(write, _trylock_irqsave, lock, &flags))
+
 #define __spin_can_lock(lock)	__raw_spin_can_lock(&(lock)->raw_lock)
 #define __read_can_lock(lock)	__raw_read_can_lock(&(lock)->raw_lock)
 #define __write_can_lock(lock)	__raw_write_can_lock(&(lock)->raw_lock)
Index: linux-2.6.21-rt1_patch/include/linux/spinlock_api_smp.h
===================================================================
--- linux-2.6.21-rt1_patch.orig/include/linux/spinlock_api_smp.h	2007-05-10 
11:28:35.000000000 +0530
+++ linux-2.6.21-rt1_patch/include/linux/spinlock_api_smp.h	2007-05-10 
11:29:13.000000000 +0530
@@ -48,6 +48,8 @@
 __spin_trylock_irqsave(raw_spinlock_t *lock, unsigned long *flags);
 int __lockfunc __read_trylock(raw_rwlock_t *lock);
 int __lockfunc __write_trylock(raw_rwlock_t *lock);
+int __lockfunc
+__write_trylock_irqsave(raw_rwlock_t *lock, unsigned long *flags);
 int __lockfunc __spin_trylock_bh(raw_spinlock_t *lock);
 int __lockfunc __spin_trylock_irq(raw_spinlock_t *lock);
 void __lockfunc __spin_unlock(raw_spinlock_t *lock)		RELEASE_SPIN;
Index: linux-2.6.21-rt1_patch/include/linux/spinlock_api_up.h
===================================================================
--- linux-2.6.21-rt1_patch.orig/include/linux/spinlock_api_up.h	2007-05-10 
11:28:35.000000000 +0530
+++ linux-2.6.21-rt1_patch/include/linux/spinlock_api_up.h	2007-05-10 
11:29:13.000000000 +0530
@@ -41,6 +41,8 @@
 
 #define __spin_trylock_irqsave(lock, flags)	__TRYLOCK_IRQSAVE(lock, flags)
 
+#define __write_trylock_irqsave(lock, flags)	__TRYLOCK_IRQSAVE(lock, flags)
+
 #define __UNLOCK(lock) \
   do { preempt_enable(); __release(lock); (void)(lock); } while (0)
 
Index: linux-2.6.21-rt1_patch/kernel/rt.c
===================================================================
--- linux-2.6.21-rt1_patch.orig/kernel/rt.c	2007-05-10 11:28:35.000000000 
+0530
+++ linux-2.6.21-rt1_patch/kernel/rt.c	2007-05-10 11:29:13.000000000 +0530
@@ -173,6 +173,12 @@
 }
 EXPORT_SYMBOL(rt_write_trylock);
 
+int __lockfunc rt_write_trylock_irqsave(rwlock_t *rwlock, unsigned long 
*flags)
+{
+	*flags = 0;
+	return rt_write_trylock(rwlock);
+}
+
 int __lockfunc rt_read_trylock(rwlock_t *rwlock)
 {
 	struct rt_mutex *lock = &rwlock->lock;
Index: linux-2.6.21-rt1_patch/kernel/spinlock.c
===================================================================
--- linux-2.6.21-rt1_patch.orig/kernel/spinlock.c	2007-05-10 
11:28:35.000000000 +0530
+++ linux-2.6.21-rt1_patch/kernel/spinlock.c	2007-05-10 11:29:13.000000000 
+0530
@@ -97,6 +97,20 @@
 }
 EXPORT_SYMBOL(__write_trylock);
 
+int __lockfunc __write_trylock_irqsave(raw_rwlock_t *lock, unsigned long 
*flags)
+{
+	int ret;
+
+	local_irq_save(*flags);
+	ret = __write_trylock(lock);
+	if (ret)
+		return ret;
+
+	local_irq_restore(*flags);
+	return 0;
+}
+EXPORT_SYMBOL(__write_trylock_irqsave);
+
 /*
  * If lockdep is enabled then we use the non-preemption spin-ops
  * even on CONFIG_PREEMPT, because lockdep assumes that interrupts are

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2007-05-10  6:38 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-05-10  6:37 [PREEMPT_RT] [PATCH 1/2] Introduce write_trylock_irqsave Sripathi Kodi

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®