linux-arch.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Babu Moger <babu.moger@oracle.com>
To: peterz@infradead.org, mingo@redhat.com, arnd@arndb.de,
	davem@davemloft.net
Cc: linux-arch@vger.kernel.org, linux-kernel@vger.kernel.org,
	sparclinux@vger.kernel.org, geert@linux-m68k.org,
	babu.moger@oracle.com, shannon.nelson@oracle.com,
	haakon.bugge@oracle.com, steven.sistare@oracle.com,
	vijay.ac.kumar@oracle.com, jane.chu@oracle.com
Subject: [PATCH v4 4/7] arch/sparc: Introduce cmpxchg_u8 SPARC
Date: Wed, 24 May 2017 17:55:12 -0600	[thread overview]
Message-ID: <1495670115-63960-5-git-send-email-babu.moger@oracle.com> (raw)
In-Reply-To: <1495670115-63960-1-git-send-email-babu.moger@oracle.com>

SPARC supports 32 bit and 64 bit cmpxchg right now. Add support
for 8 bit (1 byte) cmpxchg. This is required to support queued
rwlocks feature  which uses 1 byte cmpxchg.

The function __cmpxchg_u8 here uses the 4 byte cas instruction with a
byte manipulation to achieve 1 byte cmpxchg.

Signed-off-by: Babu Moger <babu.moger@oracle.com>
Reviewed-by: Håkon Bugge <haakon.bugge@oracle.com>
Reviewed-by: Steve Sistare <steven.sistare@oracle.com>
Reviewed-by: Shannon Nelson <shannon.nelson@oracle.com>
Reviewed-by: Jane Chu <jane.chu@oracle.com>
Reviewed-by: Vijay Kumar <vijay.ac.kumar@oracle.com>
---
 arch/sparc/include/asm/cmpxchg_64.h |   29 +++++++++++++++++++++++++++++
 1 files changed, 29 insertions(+), 0 deletions(-)

diff --git a/arch/sparc/include/asm/cmpxchg_64.h b/arch/sparc/include/asm/cmpxchg_64.h
index faa2f61..000f7d7 100644
--- a/arch/sparc/include/asm/cmpxchg_64.h
+++ b/arch/sparc/include/asm/cmpxchg_64.h
@@ -87,6 +87,33 @@ static inline unsigned long __xchg(unsigned long x, __volatile__ void * ptr,
 	return new;
 }
 
+/*
+ * Use 4 byte cas instruction to achieve 1 byte cmpxchg. Main logic
+ * here is to get the bit shift of the byte we are interested in.
+ * The XOR is handy for reversing the bits for big-endian byte order
+ */
+static inline unsigned long
+__cmpxchg_u8(volatile unsigned char *m, unsigned char old, unsigned char new)
+{
+	unsigned long maddr = (unsigned long)m;
+	int bit_shift = (((unsigned long)m & 3) ^ 3) << 3;
+	unsigned int mask = 0xff << bit_shift;
+	unsigned int *ptr = (unsigned int *) (maddr & ~3);
+	unsigned int old32, new32, load;
+	unsigned int load32 = *ptr;
+
+	do {
+		new32 = (load32 & ~mask) | (new << bit_shift);
+		old32 = (load32 & ~mask) | (old << bit_shift);
+		load32 = __cmpxchg_u32(ptr, old32, new32);
+		if (load32 == old32)
+			return old;
+		load = (load32 & mask) >> bit_shift;
+	} while (load == old);
+
+	return load;
+}
+
 /* This function doesn't exist, so you'll get a linker error
    if something tries to do an invalid cmpxchg().  */
 void __cmpxchg_called_with_bad_pointer(void);
@@ -95,6 +122,8 @@ static inline unsigned long __xchg(unsigned long x, __volatile__ void * ptr,
 __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size)
 {
 	switch (size) {
+		case 1:
+			return __cmpxchg_u8(ptr, old, new);
 		case 4:
 			return __cmpxchg_u32(ptr, old, new);
 		case 8:
-- 
1.7.1

  parent reply	other threads:[~2017-05-24 23:55 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-05-24 23:55 [PATCH v4 0/7] Enable queued rwlock and queued spinlock for SPARC Babu Moger
2017-05-24 23:55 ` Babu Moger
2017-05-24 23:55 ` [PATCH v4 1/7] arch/sparc: Remove the check #ifndef __LINUX_SPINLOCK_TYPES_H Babu Moger
2017-05-24 23:55   ` Babu Moger
2017-05-24 23:55 ` [PATCH v4 2/7] kernel/locking: Fix compile error with qrwlock.c Babu Moger
2017-05-24 23:55 ` [PATCH v4 3/7] arch/sparc: Define config parameter CPU_BIG_ENDIAN Babu Moger
2017-05-24 23:55   ` Babu Moger
2017-05-24 23:55 ` Babu Moger [this message]
2017-05-24 23:55   ` [PATCH v4 4/7] arch/sparc: Introduce cmpxchg_u8 SPARC Babu Moger
2017-05-24 23:55 ` [PATCH v4 5/7] arch/sparc: Enable queued rwlocks for SPARC Babu Moger
2017-05-24 23:55 ` [PATCH v4 6/7] arch/sparc: Introduce xchg16 " Babu Moger
2017-05-24 23:55   ` Babu Moger
2017-05-24 23:55 ` [PATCH v4 7/7] arch/sparc: Enable queued spinlock support " Babu Moger
2017-05-24 23:55   ` Babu Moger
2017-05-25 19:18 ` [PATCH v4 0/7] Enable queued rwlock and queued spinlock " David Miller

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=1495670115-63960-5-git-send-email-babu.moger@oracle.com \
    --to=babu.moger@oracle.com \
    --cc=arnd@arndb.de \
    --cc=davem@davemloft.net \
    --cc=geert@linux-m68k.org \
    --cc=haakon.bugge@oracle.com \
    --cc=jane.chu@oracle.com \
    --cc=linux-arch@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@redhat.com \
    --cc=peterz@infradead.org \
    --cc=shannon.nelson@oracle.com \
    --cc=sparclinux@vger.kernel.org \
    --cc=steven.sistare@oracle.com \
    --cc=vijay.ac.kumar@oracle.com \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).