Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755041AbbL0Nah (ORCPT ); Sun, 27 Dec 2015 08:30:37 -0500 Received: from mail-am1on0055.outbound.protection.outlook.com ([157.56.112.55]:11721 "EHLO emea01-am1-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1754847AbbL0Naf (ORCPT ); Sun, 27 Dec 2015 08:30:35 -0500 Authentication-Results: spf=fail (sender IP is 212.179.42.66) smtp.mailfrom=ezchip.com; linaro.org; dkim=none (message not signed) header.d=none;linaro.org; dmarc=none action=none header.from=ezchip.com; From: Noam Camus To: CC: , , , , Noam Camus Subject: [PATCH v5 15/20] ARC: [plat-eznps] Use dedicated atomic/bitops/cmpxchg Date: Sun, 27 Dec 2015 15:23:34 +0200 Message-ID: <1451222619-3610-16-git-send-email-noamc@ezchip.com> X-Mailer: git-send-email 1.7.1 In-Reply-To: <1451222619-3610-1-git-send-email-noamc@ezchip.com> References: <1451222619-3610-1-git-send-email-noamc@ezchip.com> MIME-Version: 1.0 Content-Type: text/plain X-TM-AS-Product-Ver: SMEX-11.0.0.1191-8.000.1202-22026.007 X-TM-AS-Result: No--6.630000-8.000000-31 X-TM-AS-User-Approved-Sender: No X-TM-AS-User-Blocked-Sender: No X-EOPAttributedMessage: 0 X-Microsoft-Exchange-Diagnostics: 1;DB3FFO11FD040;1:4E1cPi5no2ELCuL6zBVBDNtzrx+YRgyVmrOugOyW7HhXVsR1Jj04Z6UE95PC4B1akwlNoQz+kvw9SBhcdmfOb6k8zRVOCmR/264TtAQNVs6oCsvptRm5CAfKEtkff+OMYU3CKiZKHMugtIQ+sp/1gHRw5v+jRhn9aG67/Er4TCI3H4x72g5Eb4ARl0DhCwOTUNWo5UOpM7VcjTOFPf5q2vAwuYtMoHX1atgIPIaJH/h439UIwewNXT+36gZv2jjvkP7IWoamQ+OxNv+EfVYd+KxNRoxypt6oNOcS2r1v9hkz+x2ZWNvNEPe9oWEG47TmBcPcLCF9hAQL1WYrK17s9U3LIA7u9PycG7Cg4CAA2tZTpwxmMUtGD2Et5W1Jo53IYBDb9dmLhYPZqMUo9/5HBYbAuiGBZNfXlQT3OzYbdDM= X-Forefront-Antispam-Report: CIP:212.179.42.66;CTRY:IL;IPV:NLI;EFV:NLI;SFV:NSPM;SFS:(10009020)(6009001)(2980300002)(1109001)(1110001)(339900001)(189002)(199003)(92566002)(47776003)(5001970100001)(586003)(50466002)(107886002)(110136002)(85426001)(86362001)(77096005)(48376002)(1096002)(1220700001)(87936001)(50226001)(49486002)(5003940100001)(105606002)(19580405001)(106466001)(19580395003)(104016004)(36756003)(5008740100001)(2950100001)(76176999)(50986999)(229853001)(2351001)(33646002)(4001430100002)(189998001)(6806005)(21314002);DIR:OUT;SFP:1101;SCL:1;SRVR:AM3PR02MB0325;H:ezex10.ezchip.com;FPR:;SPF:Fail;PTR:ezmail.ezchip.com;MX:1;A:1;LANG:en; X-Microsoft-Exchange-Diagnostics: 1;AM3PR02MB0325;2:w/rhM9cp3uscUCiCrgj5StYorT4re5mYlt2ewSvoYzrOjJk0KVrv0gpGnCEb68Vbib3Ziu5V4gfTWs9BodhaL0FbJEkjXqnQ/v36Ct4zRNYFF7CjlC5wTicnYvLIl+cAHy6ylBvpVAutIdX1wBFLOQ==;3:BNO/fqjW40r/NZkz+M0Fe4W4opkbB8HJrlvmVjYAfPVtwh8JEa3wEoKH/irKLERvqWIrzfaEDTmPuyzviiM8OcgVUP2+9C8tXM5KggzBjkpWi4LW4UaRGPA9/Ng1Pl6y6Js3dngq7srRrmQRU9tHtR7Wykv7A4D7W39bEG/f/pQO+MPnhyJG8rUM6npFpSqh/n7D+QOvsRWxSBbErc7SuMW9+B2B9pLfQxrKXedD4eQ=;25:AjasItEpK0BJXZz2ecmR+DOrbNPF1NwqMvNj8dVybl1K3w4OBIUiKtiHJj9lM8BqClG/3BxYi2JOR6zs6zzgFZW15WZqW41/7xPxKskpBc8BXEyGG4sIYLGgUpNgfQ1XHnKs/6nkW4v85RI2vD+R3kiRs8J3r++oEfej/ZRlSJZjCEFcIckmrSHFN3OIvHK7YoRgzY5azDtNIsdRMHCkSpRJXVew9QE4sbYpUR3qSJfS5WvCNS15U9qAY1lwn5pz;20:jJCSDs0xuCbcER7vZJXJX/m/BSn0l7PFi4ArlLNg3yxJN7kYC4bvFKScjyad8cf5UgZaoah+8wVC71AiKbJm+cZqCxptWwA5jeRLQNeosrXp9PswDzig08pz0Z4tbFOpZLBNr/7sLdWrPDdNk7tf3QLNFGKkQWDyWkB+0rQl9XE= X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:AM3PR02MB0325; X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(121898900299872); X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(601004)(2401047)(5005006)(520078)(8121501046)(10201501046)(3002001);SRVR:AM3PR02MB0325;BCL:0;PCL:0;RULEID:;SRVR:AM3PR02MB0325; X-Microsoft-Exchange-Diagnostics: 1;AM3PR02MB0325;4:hd6OEiT3FfdIshcVI0/Gexo8EDTD7iAh12pV7wy9Pbm3e5fEtnvbbW/SwTVCnHInLZ05jMZl5ojsGKmhkL/PbjgbyW3uKBNy2e5ew9HZYXJi/g0S5TfqeeodN7Vo8pVSv35oMlbB/i2fAb/4fe3694qm14okBNNnexTOoaiBukMMYRDYnAWfO5ArHUsaAY53URRBHAtyxyTuyunjamwYYJ8otmN6deyn8y6tE98z5zIJZeuJtiwrgr1W0QybryIdkXrWozFEQoGwV5asVL6uKMLrR5StgAmCikwhTB/G1a8MYziqwadaMjJTLQyCroGMMQrOO6zfBf2dCL3/kxsr9inMEJl4j+e7WIMol1klP60uPZxGXPXR2R5n12fHOUeknrdqCXQhp/gaiQLvXI//F/y5up6KXqvvEQ9YefD3his= X-Forefront-PRVS: 0803A0241F X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1;AM3PR02MB0325;23:gvCh6QeLcTCMYhibZE2Utkt5s0WVIMoLP5FpXs/Cv?= =?us-ascii?Q?MISGU2egbWcV3wWYc0h0hx6dkr2sk5jBS/IFZ13u8bk+mRA5Z99Q7YoB7whS?= =?us-ascii?Q?oUfne/Hn3iKhexDXeqx1xqK8elAQblyWIgJyGv9stx2fX5giAYsa+/7WPY+g?= =?us-ascii?Q?sn+0EN4/ohYFgzAlZOh2WNtUn67mnN2diOm2bBrfkU/XYa97ajunLALZt0Ri?= =?us-ascii?Q?r2OTmO6eBmxks2Y9M/Bookr8s801/8vnP0NIy4QBinezMylDRVMj4miWXOb9?= =?us-ascii?Q?xMHwhgwEva3eQiCXRO+J9IqRjWvoTFyUdy8kQoZ7KIvjzdzqcSh59/+etl+Y?= =?us-ascii?Q?7gXCi8WovaTSDqeG7R5iukbaCB5Dj5MbV1ZR2nueMd6gJNVUYfZ4+PQ52s/s?= =?us-ascii?Q?z+AEPYsAX19eW9DCe1G+VcdwhmfAFdSgeMrE+j/JhFuOx4zlVq3iK1EWuFIR?= =?us-ascii?Q?JTfWup6ScgRY6nNmspnRkCn0aaGyIIXpJwCOIoVOmwaHbLhgOjOBvIxV/EWx?= =?us-ascii?Q?kYZX8r9tTTaVF4+PvBXLLp8T0gbUelXuICgJi2dKoY20Jfm/7HmwL2MQOzt1?= =?us-ascii?Q?0zzneg4ZzYi4PoeOHjJoAAPHp0Tb86r8027QcnSMQoLxU2j9gxeQvjEt1EDg?= =?us-ascii?Q?RR9HoIKDO60FrBJE3byLs+NP+nkZYLlygeX/83P5gTlY0Mbzy6ju6dpGOJcA?= =?us-ascii?Q?/Ug4o4kw37WbSCY0CCHVp91jUQCCbSbf/jl9PKxB7E9Av2C1PHA26x30CghE?= =?us-ascii?Q?ePwh/zGjRiWNJcFuie0S0zRb7/CbYTsusxTG6OikpQgxPOiXS2PZiC3xzFam?= =?us-ascii?Q?C8SN2FQqZ1PMO1SAxgx+Tddk9N+RaZCng8NxINYcxa+rv8KxRm4lGMJEYZtQ?= =?us-ascii?Q?2IGCcCCvsyOmcUXb3z9lT0ZpCGs9PJpvAKvuHkd+mamoNlpkY6gM8zf0Mkrj?= =?us-ascii?Q?vRzXzCGkqeYnCR4nTByQKXE+SFWPX4e2MNXLyM8a+ZWb4xzG3jpcv+HeA0kU?= =?us-ascii?Q?W51ksZCMJTx9Yaj+XCnAfMsc672a+JyeHyXJZzQbsiNt57gATDR4D50x6Ryf?= =?us-ascii?Q?GroyjsDbyjelQtr9/oH6NSPukF/FlB/bpH2WeWTWLMFvIiysg=3D=3D?= X-Microsoft-Exchange-Diagnostics: 1;AM3PR02MB0325;5:2Be0+Wuf+FmL6qUXXwmFJQw1OLdNC5hWZcIIXa65qecs9dfAPxwoX2Wpw0yG38lylk6I7N+I6fy2ZSQsjebW3In0zFqUcAQ1i5sg5kJNqUyZetDDa+f9Sh+O5VA5nL1zShxMLcvICHXe9BU5Cj0eUQ==;24:5ej+mdbNoNgLgoJ8fLNxVfelG9w1uSS1Au2lwDVcQocG4LXB1YmhDmdlZyWABcQ1MkwEMQbeDwY4oWYV5rZ32XzWG+v1ZN9TkUDaa0ex/4s= SpamDiagnosticOutput: 1:23 SpamDiagnosticMetadata: NSPM X-OriginatorOrg: ezchip.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 27 Dec 2015 13:30:31.5965 (UTC) X-MS-Exchange-CrossTenant-Id: 0fc16e0a-3cd3-4092-8b2f-0a42cff122c3 X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=0fc16e0a-3cd3-4092-8b2f-0a42cff122c3;Ip=[212.179.42.66];Helo=[ezex10.ezchip.com] X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM3PR02MB0325 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 8813 Lines: 319 From: Noam Camus We need our own implementaions since we lack LLSC support. Our extended ISA provided with optimized solution for all 32bit operations we see in these three headers. Signed-off-by: Noam Camus --- arch/arc/include/asm/atomic.h | 79 +++++++++++++++++++++++++++++++++++- arch/arc/include/asm/bitops.h | 54 +++++++++++++++++++++++++ arch/arc/include/asm/cmpxchg.h | 87 +++++++++++++++++++++++++++++++++------- 3 files changed, 202 insertions(+), 18 deletions(-) diff --git a/arch/arc/include/asm/atomic.h b/arch/arc/include/asm/atomic.h index 7730d30..a626996 100644 --- a/arch/arc/include/asm/atomic.h +++ b/arch/arc/include/asm/atomic.h @@ -17,6 +17,7 @@ #include #include +#ifndef CONFIG_ARC_PLAT_EZNPS #define atomic_read(v) READ_ONCE((v)->counter) #ifdef CONFIG_ARC_HAS_LLSC @@ -180,12 +181,84 @@ ATOMIC_OP(andnot, &= ~, bic) ATOMIC_OP(or, |=, or) ATOMIC_OP(xor, ^=, xor) -#undef ATOMIC_OPS -#undef ATOMIC_OP_RETURN -#undef ATOMIC_OP #undef SCOND_FAIL_RETRY_VAR_DEF #undef SCOND_FAIL_RETRY_ASM #undef SCOND_FAIL_RETRY_VARS +#else /* CONFIG_ARC_PLAT_EZNPS */ +static inline int atomic_read(const atomic_t *v) +{ + int temp; + + __asm__ __volatile__( + " ld.di %0, [%1]" + : "=r"(temp) + : "r"(&v->counter) + : "memory"); + return temp; +} + +static inline void atomic_set(atomic_t *v, int i) +{ + __asm__ __volatile__( + " st.di %0,[%1]" + : + : "r"(i), "r"(&v->counter) + : "memory"); +} + +#define ATOMIC_OP(op, c_op, asm_op) \ +static inline void atomic_##op(int i, atomic_t *v) \ +{ \ + __asm__ __volatile__( \ + " mov r2, %0\n" \ + " mov r3, %1\n" \ + " .word %2\n" \ + : \ + : "r"(i), "r"(&v->counter), "i"(asm_op) \ + : "r2", "r3", "memory"); \ +} \ + +#define ATOMIC_OP_RETURN(op, c_op, asm_op) \ +static inline int atomic_##op##_return(int i, atomic_t *v) \ +{ \ + unsigned int temp = i; \ + \ + /* Explicit full memory barrier needed before/after */ \ + smp_mb(); \ + \ + __asm__ __volatile__( \ + " mov r2, %0\n" \ + " mov r3, %1\n" \ + " .word %2\n" \ + " mov %0, r2" \ + : "+r"(temp) \ + : "r"(&v->counter), "i"(asm_op) \ + : "r2", "r3", "memory"); \ + \ + smp_mb(); \ + \ + temp c_op i; \ + \ + return temp; \ +} + +#define ATOMIC_OPS(op, c_op, asm_op) \ + ATOMIC_OP(op, c_op, asm_op) \ + ATOMIC_OP_RETURN(op, c_op, asm_op) + +ATOMIC_OPS(add, +=, CTOP_INST_AADD_DI_R2_R2_R3) +#define atomic_sub(i, v) atomic_add(-(i), (v)) +#define atomic_sub_return(i, v) atomic_add_return(-(i), (v)) + +ATOMIC_OP(and, &=, CTOP_INST_AAND_DI_R2_R2_R3) +#define atomic_andnot(mask, v) atomic_and(~(mask), (v)) +ATOMIC_OP(or, |=, CTOP_INST_AOR_DI_R2_R2_R3) +ATOMIC_OP(xor, ^=, CTOP_INST_AXOR_DI_R2_R2_R3) +#endif /* CONFIG_ARC_PLAT_EZNPS */ + +#undef ATOMIC_OPS +#undef ATOMIC_OP_RETURN +#undef ATOMIC_OP /** * __atomic_add_unless - add unless the number is a given value diff --git a/arch/arc/include/asm/bitops.h b/arch/arc/include/asm/bitops.h index 57c1f33..5a29185 100644 --- a/arch/arc/include/asm/bitops.h +++ b/arch/arc/include/asm/bitops.h @@ -22,6 +22,7 @@ #include #endif +#ifndef CONFIG_ARC_PLAT_EZNPS #if defined(CONFIG_ARC_HAS_LLSC) /* @@ -155,6 +156,53 @@ static inline int test_and_##op##_bit(unsigned long nr, volatile unsigned long * } #endif /* CONFIG_ARC_HAS_LLSC */ +#else /* CONFIG_ARC_PLAT_EZNPS */ +#define BIT_OP(op, c_op, asm_op) \ +static inline void op##_bit(unsigned long nr, volatile unsigned long *m)\ +{ \ + m += nr >> 5; \ + \ + nr = (1UL << (nr & 0x1f)); \ + if (asm_op == CTOP_INST_AAND_DI_R2_R2_R3) \ + nr = ~nr; \ + \ + __asm__ __volatile__( \ + " mov r2, %0\n" \ + " mov r3, %1\n" \ + " .word %2\n" \ + : \ + : "r"(nr), "r"(m), "i"(asm_op) \ + : "r2", "r3", "memory"); \ +} + +#define TEST_N_BIT_OP(op, c_op, asm_op) \ +static inline int test_and_##op##_bit(unsigned long nr, volatile unsigned long *m)\ +{ \ + unsigned long old; \ + \ + m += nr >> 5; \ + \ + nr = old = (1UL << (nr & 0x1f)); \ + if (asm_op == CTOP_INST_AAND_DI_R2_R2_R3) \ + old = ~old; \ + \ + /* Explicit full memory barrier needed before/after */ \ + smp_mb(); \ + \ + __asm__ __volatile__( \ + " mov r2, %0\n" \ + " mov r3, %1\n" \ + " .word %2\n" \ + " mov %0, r2" \ + : "+r"(old) \ + : "r"(m), "i"(asm_op) \ + : "r2", "r3", "memory"); \ + \ + smp_mb(); \ + \ + return (old & nr) != 0; \ +} +#endif /* CONFIG_ARC_PLAT_EZNPS */ /*************************************** * Non atomic variants @@ -196,9 +244,15 @@ static inline int __test_and_##op##_bit(unsigned long nr, volatile unsigned long /* __test_and_set_bit(), __test_and_clear_bit(), __test_and_change_bit() */\ __TEST_N_BIT_OP(op, c_op, asm_op) +#ifndef CONFIG_ARC_PLAT_EZNPS BIT_OPS(set, |, bset) BIT_OPS(clear, & ~, bclr) BIT_OPS(change, ^, bxor) +#else +BIT_OPS(set, |, CTOP_INST_AOR_DI_R2_R2_R3) +BIT_OPS(clear, & ~, CTOP_INST_AAND_DI_R2_R2_R3) +BIT_OPS(change, ^, CTOP_INST_AXOR_DI_R2_R2_R3) +#endif /* * This routine doesn't need to be atomic. diff --git a/arch/arc/include/asm/cmpxchg.h b/arch/arc/include/asm/cmpxchg.h index af7a2db..6d320d3 100644 --- a/arch/arc/include/asm/cmpxchg.h +++ b/arch/arc/include/asm/cmpxchg.h @@ -14,6 +14,7 @@ #include #include +#ifndef CONFIG_ARC_PLAT_EZNPS #ifdef CONFIG_ARC_HAS_LLSC static inline unsigned long @@ -66,21 +67,6 @@ __cmpxchg(volatile void *ptr, unsigned long expected, unsigned long new) #endif /* CONFIG_ARC_HAS_LLSC */ -#define cmpxchg(ptr, o, n) ((typeof(*(ptr)))__cmpxchg((ptr), \ - (unsigned long)(o), (unsigned long)(n))) - -/* - * Since not supported natively, ARC cmpxchg() uses atomic_ops_lock (UP/SMP) - * just to gaurantee semantics. - * atomic_cmpxchg() needs to use the same locks as it's other atomic siblings - * which also happens to be atomic_ops_lock. - * - * Thus despite semantically being different, implementation of atomic_cmpxchg() - * is same as cmpxchg(). - */ -#define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n))) - - /* * xchg (reg with memory) based on "Native atomic" EX insn */ @@ -143,6 +129,63 @@ static inline unsigned long __xchg(unsigned long val, volatile void *ptr, #endif +#else /* CONFIG_ARC_PLAT_EZNPS */ +static inline unsigned long +__cmpxchg(volatile void *ptr, unsigned long expected, unsigned long new) +{ + /* + * Explicit full memory barrier needed before/after + */ + smp_mb(); + + write_aux_reg(CTOP_AUX_GPA1, expected); + + __asm__ __volatile__( + " mov r2, %0\n" + " mov r3, %1\n" + " .word %2\n" + " mov %0, r2" + : "+r"(new) + : "r"(ptr), "i"(CTOP_INST_EXC_DI_R2_R2_R3) + : "r2", "r3", "memory"); + + smp_mb(); + + return new; +} + +static inline unsigned long __xchg(unsigned long val, volatile void *ptr, + int size) +{ + extern unsigned long __xchg_bad_pointer(void); + + switch (size) { + case 4: + /* + * Explicit full memory barrier needed before/after + */ + smp_mb(); + + __asm__ __volatile__( + " mov r2, %0\n" + " mov r3, %1\n" + " .word %2\n" + " mov %0, r2\n" + : "+r"(val) + : "r"(ptr), "i"(CTOP_INST_XEX_DI_R2_R2_R3) + : "r2", "r3", "memory"); + + smp_mb(); + + return val; + } + return __xchg_bad_pointer(); +} + +#define xchg(ptr, with) ((typeof(*(ptr)))__xchg((unsigned long)(with), (ptr), \ + sizeof(*(ptr)))) +#endif /* CONFIG_ARC_PLAT_EZNPS */ + /* * "atomic" variant of xchg() * REQ: It needs to follow the same serialization rules as other atomic_xxx() @@ -158,4 +201,18 @@ static inline unsigned long __xchg(unsigned long val, volatile void *ptr, */ #define atomic_xchg(v, new) (xchg(&((v)->counter), new)) +#define cmpxchg(ptr, o, n) ((typeof(*(ptr)))__cmpxchg((ptr), \ + (unsigned long)(o), (unsigned long)(n))) + +/* + * Since not supported natively, ARC cmpxchg() uses atomic_ops_lock (UP/SMP) + * just to gaurantee semantics. + * atomic_cmpxchg() needs to use the same locks as it's other atomic siblings + * which also happens to be atomic_ops_lock. + * + * Thus despite semantically being different, implementation of atomic_cmpxchg() + * is same as cmpxchg(). + */ +#define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n))) + #endif -- 1.7.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/