Hi All,

I compiled the latest git kernel today. Unfortunately my Varisys Cyrus Plus board still doesn't boot with the latest git kernel.

After that I patched the kernel source code with the spinlock patch and compiled the kernel again. With the spinlock patch, the latest git kernel boots without any problems.

Please find attached the spinlock patch.

Cheers,
Christian


On 20 November 2017 at 00:34AM, Christian Zigotzky wrote:
Hi All,

I created a patch for the git kernel today. (see attachment)
Without the patch, the latest git kernel doesn't boot on my Cyrus Plus board.

Cheers,
Christian


On 19 November 2017 at 5:57PM, Christian Zigotzky wrote:
Hi All,

A little success. :-) I reverted the following files from the bad commit a8a217c22116eff6c120d753c9934089fb229af0 [1]:

arch/powerpc/include/asm/spinlock.h
kernel/locking/spinlock.c
include/linux/spinlock_up.h
include/linux/spinlock.h
include/linux/rwlock.h

After that I compiled the latest git kernel again. Then I was able to boot the latest git kernel on my Varisys Cyrus Plus board [2][3]. :-)

That means the bug is in one of these files.

Please help me to find the bug in these files above.

Thanks,
Christian


[1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=a8a217c22116eff6c120d753c9934089fb229af0
[2] http://www.amigaos.net/hardware/133/amigaone-x5000
[3] http://wiki.amiga.org/index.php?title=AmigaONE_X5000



--- a/arch/powerpc/include/asm/spinlock.h	2017-11-18 20:57:47.921703650 +0100
+++ b/arch/powerpc/include/asm/spinlock.h	2017-11-19 18:51:51.630906446 +0100
@@ -182,6 +182,9 @@ static inline void arch_spin_unlock(arch
  * read-locks.
  */
 
+#define arch_read_can_lock(rw)		((rw)->lock >= 0)
+#define arch_write_can_lock(rw)	(!(rw)->lock)
+
 #ifdef CONFIG_PPC64
 #define __DO_SIGN_EXTEND	"extsw	%0,%0\n"
 #define WRLOCK_TOKEN		LOCK_TOKEN	/* it's negative */
--- a/kernel/locking/spinlock.c	2017-11-18 20:57:48.974708915 +0100
+++ b/kernel/locking/spinlock.c	2017-11-19 18:26:18.526892449 +0100
@@ -35,6 +35,9 @@
  */
 #else
 
+#define raw_read_can_lock(l)	read_can_lock(l)
+#define raw_write_can_lock(l)	write_can_lock(l)
+
 /*
  * Some architectures can relax in favour of the CPU owning the lock.
  */
@@ -68,7 +71,7 @@ void __lockfunc __raw_##op##_lock(lockty
 									\
 		if (!(lock)->break_lock)				\
 			(lock)->break_lock = 1;				\
-		while ((lock)->break_lock)				\
+		while (!raw_##op##_can_lock(lock) && (lock)->break_lock)\	
 			arch_##op##_relax(&lock->raw_lock);		\
 	}								\
 	(lock)->break_lock = 0;						\
@@ -88,7 +91,7 @@ unsigned long __lockfunc __raw_##op##_lo
 									\
 		if (!(lock)->break_lock)				\
 			(lock)->break_lock = 1;				\
-		while ((lock)->break_lock)				\
+		while (!raw_##op##_can_lock(lock) && (lock)->break_lock)\	
 			arch_##op##_relax(&lock->raw_lock);		\
 	}								\
 	(lock)->break_lock = 0;						\
--- a/include/linux/spinlock_up.h	2017-11-18 20:57:38.788657985 +0100
+++ b/include/linux/spinlock_up.h	2017-11-19 18:48:19.787635450 +0100
@@ -69,4 +69,7 @@ static inline void arch_spin_unlock(arch
 
 #define arch_spin_is_contended(lock)	(((void)(lock), 0))
 
+#define arch_read_can_lock(lock)	(((void)(lock), 1))
+#define arch_write_can_lock(lock)	(((void)(lock), 1))
+
 #endif /* __LINUX_SPINLOCK_UP_H */
--- a/include/linux/spinlock.h	2017-11-18 20:57:38.693657510 +0100
+++ b/include/linux/spinlock.h	2017-11-19 18:37:36.933284464 +0100
@@ -283,6 +283,12 @@ static inline void do_raw_spin_unlock(ra
 	1 : ({ local_irq_restore(flags); 0; }); \
 })
 
+/**
+ * raw_spin_can_lock - would raw_spin_trylock() succeed?
+ * @lock: the spinlock in question.
+ */
+#define raw_spin_can_lock(lock)	(!raw_spin_is_locked(lock))
+
 /* Include rwlock functions */
 #include <linux/rwlock.h>
 
@@ -395,6 +401,11 @@ static __always_inline int spin_is_conte
 	return raw_spin_is_contended(&lock->rlock);
 }
 
+static __always_inline int spin_can_lock(spinlock_t *lock)
+{
+	return raw_spin_can_lock(&lock->rlock);
+}
+
 #define assert_spin_locked(lock)	assert_raw_spin_locked(&(lock)->rlock)
 
 /*
--- a/include/linux/rwlock.h	2017-11-18 20:57:38.652657305 +0100
+++ b/include/linux/rwlock.h	2017-11-19 18:19:54.045970054 +0100
@@ -59,6 +59,9 @@ do {								\
 # define do_raw_write_unlock(rwlock)	do {arch_write_unlock(&(rwlock)->raw_lock); __release(lock); } while (0)
 #endif
 
+#define read_can_lock(rwlock)		arch_read_can_lock(&(rwlock)->raw_lock)
+#define write_can_lock(rwlock)		arch_write_can_lock(&(rwlock)->raw_lock)
+
 /*
  * Define the various rw_lock methods.  Note we define these
  * regardless of whether CONFIG_SMP or CONFIG_PREEMPT are set. The various

Reply via email to