* [PATCH] locking/atomics: Clean up the atomic.h maze of #defines
From: Peter Zijlstra @ 2018-05-05 9:32 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CACT4Y+Z1WKxdkodRBc5PzfyQQmfJCJ3n1JyQc-+WCkqGZeg5Wg@mail.gmail.com>
On Sat, May 05, 2018 at 11:05:51AM +0200, Dmitry Vyukov wrote:
> On Sat, May 5, 2018 at 10:47 AM, Peter Zijlstra <peterz@infradead.org> wrote:
> > And I seriously hate this one:
> >
> > ba1c9f83f633 ("locking/atomic/x86: Un-macro-ify atomic ops implementation")
> >
> > and will likely undo that the moment I need to change anything there.
> That was asked by Ingo:
> https://groups.google.com/d/msg/kasan-dev/3sNHjjb4GCI/Xz1uVWaaAAAJ
>
> I think in the end all of current options suck in one way or another,
> so we are just going in circles.
Yeah, and I disagree with him, but didn't have the energy to fight at
that time (and still don't really, I'm just complaining).
> We either need something different (e.g. codegen), or settle on one
> option for doing it.
Codegen I think is the only sensible option at this point for all the
wrappers. The existing ones (without the annotation muck) were already
cumbersome, the annotation stuff just makes it completely horrid.
^ permalink raw reply
* [PATCH] locking/atomics: Clean up the atomic.h maze of #defines
From: Ingo Molnar @ 2018-05-05 9:38 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180505090403.p2ywuen42rnlwizq@gmail.com>
* Ingo Molnar <mingo@kernel.org> wrote:
> * Peter Zijlstra <peterz@infradead.org> wrote:
>
> > > So we could do the following simplification on top of that:
> > >
> > > #ifndef atomic_fetch_dec_relaxed
> > > # ifndef atomic_fetch_dec
> > > # define atomic_fetch_dec(v) atomic_fetch_sub(1, (v))
> > > # define atomic_fetch_dec_relaxed(v) atomic_fetch_sub_relaxed(1, (v))
> > > # define atomic_fetch_dec_acquire(v) atomic_fetch_sub_acquire(1, (v))
> > > # define atomic_fetch_dec_release(v) atomic_fetch_sub_release(1, (v))
> > > # else
> > > # define atomic_fetch_dec_relaxed atomic_fetch_dec
> > > # define atomic_fetch_dec_acquire atomic_fetch_dec
> > > # define atomic_fetch_dec_release atomic_fetch_dec
> > > # endif
> > > #else
> > > # ifndef atomic_fetch_dec
> > > # define atomic_fetch_dec(...) __atomic_op_fence(atomic_fetch_dec, __VA_ARGS__)
> > > # define atomic_fetch_dec_acquire(...) __atomic_op_acquire(atomic_fetch_dec, __VA_ARGS__)
> > > # define atomic_fetch_dec_release(...) __atomic_op_release(atomic_fetch_dec, __VA_ARGS__)
> > > # endif
> > > #endif
> >
> > This would disallow an architecture to override just fetch_dec_release for
> > instance.
>
> Couldn't such a crazy arch just define _all_ the 3 APIs in this group?
> That's really a small price and makes the place pay the complexity
> price that does the weirdness...
>
> > I don't think there currently is any architecture that does that, but the
> > intent was to allow it to override anything and only provide defaults where it
> > does not.
>
> I'd argue that if a new arch only defines one of these APIs that's probably a bug.
> If they absolutely want to do it, they still can - by defining all 3 APIs.
>
> So there's no loss in arch flexibility.
BTW., PowerPC for example is already in such a situation, it does not define
atomic_cmpxchg_release(), only the other APIs:
#define atomic_cmpxchg(v, o, n) (cmpxchg(&((v)->counter), (o), (n)))
#define atomic_cmpxchg_relaxed(v, o, n) \
cmpxchg_relaxed(&((v)->counter), (o), (n))
#define atomic_cmpxchg_acquire(v, o, n) \
cmpxchg_acquire(&((v)->counter), (o), (n))
Was it really the intention on the PowerPC side that the generic code falls back
to cmpxchg(), i.e.:
# define atomic_cmpxchg_release(...) __atomic_op_release(atomic_cmpxchg, __VA_ARGS__)
Which after macro expansion becomes:
smp_mb__before_atomic();
atomic_cmpxchg_relaxed(v, o, n);
smp_mb__before_atomic() on PowerPC falls back to the generic __smp_mb(), which
falls back to mb(), which on PowerPC is the 'sync' instruction.
Isn't this a inefficiency bug?
While I'm pretty clueless about PowerPC low level cmpxchg atomics, they appear to
have the following basic structure:
full cmpxchg():
PPC_ATOMIC_ENTRY_BARRIER # sync
ldarx + stdcx
PPC_ATOMIC_EXIT_BARRIER # sync
cmpxchg_relaxed():
ldarx + stdcx
cmpxchg_acquire():
ldarx + stdcx
PPC_ACQUIRE_BARRIER # lwsync
The logical extension for cmpxchg_release() would be:
cmpxchg_release():
PPC_RELEASE_BARRIER # lwsync
ldarx + stdcx
But instead we silently get the generic fallback, which does:
smp_mb__before_atomic();
atomic_cmpxchg_relaxed(v, o, n);
Which maps to:
sync
ldarx + stdcx
Note that it uses a full barrier instead of lwsync (does that stand for
'lightweight sync'?).
Even if it turns out we need the full barrier, with the overly finegrained
structure of the atomics this detail is totally undocumented and non-obvious.
Thanks,
Ingo
^ permalink raw reply
* [PATCH] [stable] arm64: Add work around for Arm Cortex-A55 Erratum 1024718
From: Suzuki K Poulose @ 2018-05-05 9:49 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180504221508.GD20328@kroah.com>
Hi Greg,
On 05/04/2018 11:15 PM, Greg KH wrote:
> On Tue, May 01, 2018 at 11:26:04AM +0100, Suzuki K Poulose wrote:
>> commit ece1397cbc89c51914fae1aec729539cfd8bd62b upstream
>>
...
>>
>> Note: The upstream commit is on top of a reworked capability
>> infrastructure for arm64 heterogeneous systems, which allows
>> handling this later in the boot process. This backport
>> is based on the original version of the patch [0]. Folded the 3
>> patches into this single commit, removing the unncessary bits.
>>
>> [0] https://lkml.kernel.org/r/20180116102323.3470-1-suzuki.poulose at arm.com
>>
>> Cc: stable at vger.kernel.org # v4.3 to v4.16
>
> This only would apply to the 4.16.y tree. Can you provide working
> backports to 4.14.y, 4.9.y, and 4.4.y so I can queue them up there as
> well?
Sure, I will send them soon.
Cheers
Suzuki
^ permalink raw reply
* [PATCH v2 03/27] coresight: Add helper device type
From: Suzuki K Poulose @ 2018-05-05 9:56 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180503170040.GA11425@xps15>
On 05/03/2018 06:00 PM, Mathieu Poirier wrote:
...
>> +/*
>> + * coresight_release_device - Release this device and any of the helper
>> + * devices connected to it for trace operation.
>> + */
>> +static void coresight_release_device(struct coresight_device *csdev)
>> +{
>> + int i;
>> +
>> + for (i = 0; i < csdev->nr_outport; i++) {
>> + struct coresight_device *child = csdev->conns[i].child_dev;
>> +
>> + if (child && child->type == CORESIGHT_DEV_TYPE_HELPER)
>> + pm_runtime_put(child->dev.parent);
>> + }
>
> There is a newline here in coresight_prepare_device(). Either add one (or not)
> in both function but please be consistent.
>
>> @@ -480,8 +517,7 @@ static int _coresight_build_path(struct coresight_device *csdev,
>>
>> node->csdev = csdev;
>> list_add(&node->link, path);
>> - pm_runtime_get_sync(csdev->dev.parent);
>> -
>> + coresight_prepare_device(csdev);
>
> There was a newline between pm_runtime_get_sync() and the return statement in
> the original code.
>
>> @@ -775,6 +811,10 @@ static struct device_type coresight_dev_type[] = {
>> .name = "source",
>> .groups = coresight_source_groups,
>> },
>> + {
>> + .name = "helper",
>> + },
>> +
>
> Extra newline.
>
>> };
>> +/**
>> + * struct coresight_ops_helper - Operations for a helper device.
>> + *
>> + * All operations could pass in a device specific data, which could
>> + * help the helper device to determine what to do.
>> + *
>> + * @enable : Turn the device ON.
>> + * @disable : Turn the device OFF.
>
> There is a discrepancy between the comment and the operations, i.e enabling a
> device is not synonymous of turning it on. Looking at patch 04/27 the ops is
> called in tmc_etr_enable/disable_catu() so the comment propably needs to be
> changed.
Sure, will fix all of them.
Cheers
Suzuki
^ permalink raw reply
* [PATCH v3 01/12] ACPI / APEI: Move the estatus queue code up, and under its own ifdef
From: Borislav Petkov @ 2018-05-05 9:58 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180427153510.5799-2-james.morse@arm.com>
On Fri, Apr 27, 2018 at 04:34:59PM +0100, James Morse wrote:
> To support asynchronous NMI-like notifications on arm64 we need to use
> the estatus-queue. These patches refactor it to allow multiple APEI
> notification types to use it.
>
> First we move the estatus-queue code higher in the file so that any
> notify_foo() handler can make use of it.
>
> This patch moves code around ... and makes the following trivial change:
> Freshen the dated comment above ghes_estatus_llist. printk() is no
> longer the issue, its the helpers like memory_failure_queue() that
> still aren't nmi safe.
>
> Signed-off-by: James Morse <james.morse@arm.com>
> Reviewed-by: Punit Agrawal <punit.agrawal@arm.com>
>
> Notes for cover letter:
> ghes.c has three things all called 'estatus'. One is a pool of memory
> that has a static size, and is grown/shrunk when new NMI users are
> allocated.
> The second is the cache, this holds recent notifications so we can
> suppress notifications we've already handled.
> The last is the queue, which hold data from NMI notifications (in pool
> memory) that can't be handled immediatly.
> ---
> drivers/acpi/apei/ghes.c | 265 ++++++++++++++++++++++++-----------------------
> 1 file changed, 137 insertions(+), 128 deletions(-)
Reviewed-by: Borislav Petkov <bp@suse.de>
--
Regards/Gruss,
Boris.
Good mailing practices for 400: avoid top-posting and trim the reply.
^ permalink raw reply
* [RFC PATCH] locking/atomics/powerpc: Introduce optimized cmpxchg_release() family of APIs for PowerPC
From: Ingo Molnar @ 2018-05-05 10:00 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180505093829.xfylnedwd5nonhae@gmail.com>
* Ingo Molnar <mingo@kernel.org> wrote:
> > So there's no loss in arch flexibility.
>
> BTW., PowerPC for example is already in such a situation, it does not define
> atomic_cmpxchg_release(), only the other APIs:
>
> #define atomic_cmpxchg(v, o, n) (cmpxchg(&((v)->counter), (o), (n)))
> #define atomic_cmpxchg_relaxed(v, o, n) \
> cmpxchg_relaxed(&((v)->counter), (o), (n))
> #define atomic_cmpxchg_acquire(v, o, n) \
> cmpxchg_acquire(&((v)->counter), (o), (n))
>
> Was it really the intention on the PowerPC side that the generic code falls back
> to cmpxchg(), i.e.:
>
> # define atomic_cmpxchg_release(...) __atomic_op_release(atomic_cmpxchg, __VA_ARGS__)
>
> Which after macro expansion becomes:
>
> smp_mb__before_atomic();
> atomic_cmpxchg_relaxed(v, o, n);
>
> smp_mb__before_atomic() on PowerPC falls back to the generic __smp_mb(), which
> falls back to mb(), which on PowerPC is the 'sync' instruction.
>
> Isn't this a inefficiency bug?
>
> While I'm pretty clueless about PowerPC low level cmpxchg atomics, they appear to
> have the following basic structure:
>
> full cmpxchg():
>
> PPC_ATOMIC_ENTRY_BARRIER # sync
> ldarx + stdcx
> PPC_ATOMIC_EXIT_BARRIER # sync
>
> cmpxchg_relaxed():
>
> ldarx + stdcx
>
> cmpxchg_acquire():
>
> ldarx + stdcx
> PPC_ACQUIRE_BARRIER # lwsync
>
> The logical extension for cmpxchg_release() would be:
>
> cmpxchg_release():
>
> PPC_RELEASE_BARRIER # lwsync
> ldarx + stdcx
>
> But instead we silently get the generic fallback, which does:
>
> smp_mb__before_atomic();
> atomic_cmpxchg_relaxed(v, o, n);
>
> Which maps to:
>
> sync
> ldarx + stdcx
>
> Note that it uses a full barrier instead of lwsync (does that stand for
> 'lightweight sync'?).
>
> Even if it turns out we need the full barrier, with the overly finegrained
> structure of the atomics this detail is totally undocumented and non-obvious.
The patch below fills in those bits and implements the optimized cmpxchg_release()
family of APIs. The end effect should be that cmpxchg_release() will now use
'lwsync' instead of 'sync' on PowerPC, for the following APIs:
cmpxchg_release()
cmpxchg64_release()
atomic_cmpxchg_release()
atomic64_cmpxchg_release()
I based this choice of the release barrier on an existing bitops low level PowerPC
method:
DEFINE_BITOP(clear_bits_unlock, andc, PPC_RELEASE_BARRIER)
This clearly suggests that PPC_RELEASE_BARRIER is in active use and 'lwsync' is
the 'release barrier' instruction, if I interpreted that right.
But I know very little about PowerPC so this might be spectacularly wrong. It's
totally untested as well. I also pretty sick today so my mental capabilities are
significantly reduced ...
So not signed off and such.
Thanks,
Ingo
---
arch/powerpc/include/asm/atomic.h | 4 ++
arch/powerpc/include/asm/cmpxchg.h | 81 ++++++++++++++++++++++++++++++++++++++
2 files changed, 85 insertions(+)
diff --git a/arch/powerpc/include/asm/atomic.h b/arch/powerpc/include/asm/atomic.h
index 682b3e6a1e21..f7a6f29acb12 100644
--- a/arch/powerpc/include/asm/atomic.h
+++ b/arch/powerpc/include/asm/atomic.h
@@ -213,6 +213,8 @@ static __inline__ int atomic_dec_return_relaxed(atomic_t *v)
cmpxchg_relaxed(&((v)->counter), (o), (n))
#define atomic_cmpxchg_acquire(v, o, n) \
cmpxchg_acquire(&((v)->counter), (o), (n))
+#define atomic_cmpxchg_release(v, o, n) \
+ cmpxchg_release(&((v)->counter), (o), (n))
#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
#define atomic_xchg_relaxed(v, new) xchg_relaxed(&((v)->counter), (new))
@@ -519,6 +521,8 @@ static __inline__ long atomic64_dec_if_positive(atomic64_t *v)
cmpxchg_relaxed(&((v)->counter), (o), (n))
#define atomic64_cmpxchg_acquire(v, o, n) \
cmpxchg_acquire(&((v)->counter), (o), (n))
+#define atomic64_cmpxchg_release(v, o, n) \
+ cmpxchg_release(&((v)->counter), (o), (n))
#define atomic64_xchg(v, new) (xchg(&((v)->counter), new))
#define atomic64_xchg_relaxed(v, new) xchg_relaxed(&((v)->counter), (new))
diff --git a/arch/powerpc/include/asm/cmpxchg.h b/arch/powerpc/include/asm/cmpxchg.h
index 9b001f1f6b32..6e46310b1833 100644
--- a/arch/powerpc/include/asm/cmpxchg.h
+++ b/arch/powerpc/include/asm/cmpxchg.h
@@ -213,10 +213,12 @@ __xchg_relaxed(void *ptr, unsigned long x, unsigned int size)
CMPXCHG_GEN(u8, , PPC_ATOMIC_ENTRY_BARRIER, PPC_ATOMIC_EXIT_BARRIER, "memory");
CMPXCHG_GEN(u8, _local, , , "memory");
CMPXCHG_GEN(u8, _acquire, , PPC_ACQUIRE_BARRIER, "memory");
+CMPXCHG_GEN(u8, _release, PPC_RELEASE_BARRIER, , "memory");
CMPXCHG_GEN(u8, _relaxed, , , "cc");
CMPXCHG_GEN(u16, , PPC_ATOMIC_ENTRY_BARRIER, PPC_ATOMIC_EXIT_BARRIER, "memory");
CMPXCHG_GEN(u16, _local, , , "memory");
CMPXCHG_GEN(u16, _acquire, , PPC_ACQUIRE_BARRIER, "memory");
+CMPXCHG_GEN(u16, _release, PPC_RELEASE_BARRIER, , "memory");
CMPXCHG_GEN(u16, _relaxed, , , "cc");
static __always_inline unsigned long
@@ -314,6 +316,29 @@ __cmpxchg_u32_acquire(u32 *p, unsigned long old, unsigned long new)
return prev;
}
+static __always_inline unsigned long
+__cmpxchg_u32_release(u32 *p, unsigned long old, unsigned long new)
+{
+ unsigned long prev;
+
+ __asm__ __volatile__ (
+ PPC_RELEASE_BARRIER
+"1: lwarx %0,0,%2 # __cmpxchg_u32_release\n"
+" cmpw 0,%0,%3\n"
+" bne- 2f\n"
+ PPC405_ERR77(0, %2)
+" stwcx. %4,0,%2\n"
+" bne- 1b\n"
+ "\n"
+"2:"
+ : "=&r" (prev), "+m" (*p)
+ : "r" (p), "r" (old), "r" (new)
+ : "cc", "memory");
+
+ return prev;
+}
+
+
#ifdef CONFIG_PPC64
static __always_inline unsigned long
__cmpxchg_u64(volatile unsigned long *p, unsigned long old, unsigned long new)
@@ -397,6 +422,27 @@ __cmpxchg_u64_acquire(u64 *p, unsigned long old, unsigned long new)
return prev;
}
+
+static __always_inline unsigned long
+__cmpxchg_u64_release(u64 *p, unsigned long old, unsigned long new)
+{
+ unsigned long prev;
+
+ __asm__ __volatile__ (
+ PPC_RELEASE_BARRIER
+"1: ldarx %0,0,%2 # __cmpxchg_u64_release\n"
+" cmpd 0,%0,%3\n"
+" bne- 2f\n"
+" stdcx. %4,0,%2\n"
+" bne- 1b\n"
+ "\n"
+"2:"
+ : "=&r" (prev), "+m" (*p)
+ : "r" (p), "r" (old), "r" (new)
+ : "cc", "memory");
+
+ return prev;
+}
#endif
static __always_inline unsigned long
@@ -478,6 +524,27 @@ __cmpxchg_acquire(void *ptr, unsigned long old, unsigned long new,
BUILD_BUG_ON_MSG(1, "Unsupported size for __cmpxchg_acquire");
return old;
}
+
+static __always_inline unsigned long
+__cmpxchg_release(void *ptr, unsigned long old, unsigned long new,
+ unsigned int size)
+{
+ switch (size) {
+ case 1:
+ return __cmpxchg_u8_release(ptr, old, new);
+ case 2:
+ return __cmpxchg_u16_release(ptr, old, new);
+ case 4:
+ return __cmpxchg_u32_release(ptr, old, new);
+#ifdef CONFIG_PPC64
+ case 8:
+ return __cmpxchg_u64_release(ptr, old, new);
+#endif
+ }
+ BUILD_BUG_ON_MSG(1, "Unsupported size for __cmpxchg_release");
+ return old;
+}
+
#define cmpxchg(ptr, o, n) \
({ \
__typeof__(*(ptr)) _o_ = (o); \
@@ -512,6 +579,15 @@ __cmpxchg_acquire(void *ptr, unsigned long old, unsigned long new,
(unsigned long)_o_, (unsigned long)_n_, \
sizeof(*(ptr))); \
})
+
+#define cmpxchg_release(ptr, o, n) \
+({ \
+ __typeof__(*(ptr)) _o_ = (o); \
+ __typeof__(*(ptr)) _n_ = (n); \
+ (__typeof__(*(ptr))) __cmpxchg_release((ptr), \
+ (unsigned long)_o_, (unsigned long)_n_, \
+ sizeof(*(ptr))); \
+})
#ifdef CONFIG_PPC64
#define cmpxchg64(ptr, o, n) \
({ \
@@ -533,6 +609,11 @@ __cmpxchg_acquire(void *ptr, unsigned long old, unsigned long new,
BUILD_BUG_ON(sizeof(*(ptr)) != 8); \
cmpxchg_acquire((ptr), (o), (n)); \
})
+#define cmpxchg64_release(ptr, o, n) \
+({ \
+ BUILD_BUG_ON(sizeof(*(ptr)) != 8); \
+ cmpxchg_release((ptr), (o), (n)); \
+})
#else
#include <asm-generic/cmpxchg-local.h>
#define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n))
^ permalink raw reply related
* [PATCH v2 04/27] coresight: Introduce support for Coresight Addrss Translation Unit
From: Suzuki K Poulose @ 2018-05-05 10:03 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CANLsYkwCYUD0OSEuVML=vKJysT=xi8M0ahpU2bz=nBykSgFgGQ@mail.gmail.com>
On 05/03/2018 09:25 PM, Mathieu Poirier wrote:
> On 3 May 2018 at 11:31, Mathieu Poirier <mathieu.poirier@linaro.org> wrote:
>> On Tue, May 01, 2018 at 10:10:34AM +0100, Suzuki K Poulose wrote:
>>> Add the initial support for Coresight Address Translation Unit, which
>>> augments the TMC in Coresight SoC-600 by providing an improved Scatter
>>> Gather mechanism. CATU is always connected to a single TMC-ETR and
>>> converts the AXI address with a translated address (from a given SG
>>> table with specific format). The CATU should be programmed in pass
>>> through mode and enabled if the ETR doesn't translation by CATU.
>>>
>>> This patch provides mechanism to enable/disable the CATU always in the
>>> pass through mode.
>>>
>>> We reuse the existing ports mechanism to link the TMC-ETR to the
>>> connected CATU.
>>>
>>> i.e, TMC-ETR:output_port0 -> CATU:input_port0
>>>
>>> Reference manual for CATU component is avilable in version r2p0 of :
>>> "Arm Coresight System-on-Chip SoC-600 Technical Reference Manual",
>>> under Section 4.9.
>>
>> Please remove the part about the TRM as it is bound to change.
Ok, I will. Generally the TRM for a particular release (rXpY) doesn't
change, unless there is a change in either X or Y or both.
>>>
>>> +config CORESIGHT_CATU
>>> + bool "Coresight Address Translation Unit (CATU) driver"
>>> + depends on CORESIGHT_LINK_AND_SINK_TMC
>>> + help
>>> + Enable support for the Coresight Address Translation Unit (CATU).
>>> + CATU supports a scatter gather table of 4K pages, with forward/backward
>>> + lookup. CATU helps TMC ETR to use large physically non-contiguous trace
>>> + buffer by translating the addersses used by ETR to the corresponding
>>> + physical adderss by looking up the table.
>>
>> There is a couple of typos in the last sentence.
>
> There's also a typo in the patch title.
>
>>> diff --git a/drivers/hwtracing/coresight/coresight-catu.c b/drivers/hwtracing/coresight/coresight-catu.c
>>> new file mode 100644
>>> index 0000000..2cd69a6
>>> --- /dev/null
>>> +++ b/drivers/hwtracing/coresight/coresight-catu.c
>>> @@ -0,0 +1,195 @@
>>> +// SPDX-License-Identifier: GPL-2.0
>>> +
>>
>> Extra line
>>
>>> +/*
>>> + * Copyright (C) 2017 ARM Limited. All rights reserved.
>>
>> You sure you don't want to bump this to 2018?
>>
>>> + *
>>> + * Coresight Address Translation Unit support
>>> + *
>>> + * Author: Suzuki K Poulose <suzuki.poulose@arm.com>
>>> + */
>>> +
>>> +#include <linux/kernel.h>
>>> +#include <linux/device.h>
>>> +#include <linux/amba/bus.h>
>>> +#include <linux/io.h>
>>> +#include <linux/slab.h>
>>
>> List in alphabetical order is possible.
>>
>>> +static int catu_disable(struct coresight_device *csdev, void *__unused)
>>> +{
>>> + int rc;
>>> + struct catu_drvdata *catu_drvdata = csdev_to_catu_drvdata(csdev);
>>> +
>>> + CS_UNLOCK(catu_drvdata->base);
>>> + rc = catu_disable_hw(catu_drvdata);
>>> + CS_LOCK(catu_drvdata->base);
>>> +
>>
>> I suppose you can remove the extra line as catu_enable() doesn't have one.
>>
>>> + return rc;
>>> +}
>>> + drvdata->base = base;
>>> + catu_desc.pdata = pdata;
>>> + catu_desc.dev = dev;
>>> + catu_desc.groups = catu_groups;
>>> + catu_desc.type = CORESIGHT_DEV_TYPE_HELPER;
>>> + catu_desc.subtype.helper_subtype = CORESIGHT_DEV_SUBTYPE_HELPER_CATU;
>>> + catu_desc.ops = &catu_ops;
>>> + drvdata->csdev = coresight_register(&catu_desc);
>>> + if (IS_ERR(drvdata->csdev))
>>> + ret = PTR_ERR(drvdata->csdev);
>>> + if (!ret)
>>> + dev_info(drvdata->dev, "initialized\n");
>>
>> Please remove as it 1) doesn't convey HW related information and 2) the TMC
>> doesn't out put anything.
>>
>>> diff --git a/drivers/hwtracing/coresight/coresight-catu.h b/drivers/hwtracing/coresight/coresight-catu.h
>>> new file mode 100644
>>> index 0000000..cd58d6f
>>> --- /dev/null
>>> +++ b/drivers/hwtracing/coresight/coresight-catu.h
>>> @@ -0,0 +1,89 @@
>>> +/* SPDX-License-Identifier: GPL-2.0 */
>>> +
>>
>> Extra line
>>
>>> +/*
>>> + * Copyright (C) 2017 ARM Limited. All rights reserved.
>>> + *
>>> + * Author: Suzuki K Poulose <suzuki.poulose@arm.com>
>>> + *
>>
>> Extra line. In coresight-catu.c there isn't one.
>>
>>> +#define CATU_STATUS_READY 8
>>> +#define CATU_STATUS_ADRERR 0
>>> +#define CATU_STATUS_AXIERR 4
>>> +
>>> +
>>
>> Extra line.
>>
>>> +#define CATU_IRQEN_ON 0x1
>>> +#define CATU_IRQEN_OFF 0x0
>>> +
>>> +
>>
>> Extra line.
>>
Will address all the above.
Cheers
Suzuki
^ permalink raw reply
* [PATCH v3 02/12] ACPI / APEI: Generalise the estatus queue's add/remove and notify code
From: Borislav Petkov @ 2018-05-05 10:12 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180427153510.5799-3-james.morse@arm.com>
On Fri, Apr 27, 2018 at 04:35:00PM +0100, James Morse wrote:
> To support asynchronous NMI-like notifications on arm64 we need to use
> the estatus-queue. These patches refactor it to allow multiple APEI
> notification types to use it.
>
> Refactor the estatus queue's pool grow/shrink code and notification
> routine from NOTIFY_NMI's handlers. This will allow another notification
> method to use the estatus queue without duplicating this code.
These two are repeated from patch 1.
> This patch adds rcu_read_lock()/rcu_read_unlock() around the list
> list_for_each_entry_rcu() walker. These aren't strictly necessary as
> the whole nmi_enter/nmi_exit() window is a spooky RCU read-side
> critical section.
>
> Keep the oops_begin() call for x86, arm64 doesn't have one of these,
> and APEI is the only thing outside arch code calling this..
Next patch removes it so I guess you don't have to talk about it here.
> The existing ghes_estatus_pool_shrink() is folded into the new
> ghes_estatus_queue_shrink_pool() as only the queue uses it.
>
> _in_nmi_notify_one() is separate from the rcu-list walker for a later
> caller that doesn't need to walk a list.
>
> Signed-off-by: James Morse <james.morse@arm.com>
> Reviewed-by: Punit Agrawal <punit.agrawal@arm.com>
>
> ---
> Changes since v1:
> * Tidied up _in_nmi_notify_one().
>
> drivers/acpi/apei/ghes.c | 100 ++++++++++++++++++++++++++++++-----------------
> 1 file changed, 65 insertions(+), 35 deletions(-)
...
> +static int ghes_estatus_queue_notified(struct list_head *rcu_list)
> +{
> + int ret = -ENOENT;
> + struct ghes *ghes;
> +
> + rcu_read_lock();
> + list_for_each_entry_rcu(ghes, rcu_list, list) {
> + if (!_in_nmi_notify_one(ghes))
> + ret = 0;
> + }
> + rcu_read_unlock();
> +
> + if (IS_ENABLED(CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG) && ret == 0)
... && !ret
like the rest of the file.
> + irq_work_queue(&ghes_proc_irq_work);
> +
> + return ret;
> +}
> +
> static unsigned long ghes_esource_prealloc_size(
> const struct acpi_hest_generic *generic)
> {
--
Regards/Gruss,
Boris.
Good mailing practices for 400: avoid top-posting and trim the reply.
^ permalink raw reply
* [PATCH] ARM: dts: BCM5301X: Relicense Buffalo files to the GPL 2.0+ / MIT
From: Hauke Mehrtens @ 2018-05-05 10:15 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180504095445.30918-1-zajec5@gmail.com>
On 05/04/2018 11:54 AM, Rafa? Mi?ecki wrote:
> From: Rafa? Mi?ecki <rafal@milecki.pl>
>
> This matches licensing used by other BCM5301X files and is preferred as:
> 1) GPL 2.0+ makes is clearly compatible with Linux kernel
> 2) MIT is also permissive but preferred over ISC
>
> These files were created and ever touched by a group of four people
> only: Felix, INAGAKI, Hauke and me.
>
> Signed-off-by: Rafa? Mi?ecki <rafal@milecki.pl>
Acked-by: Hauke Mehrtens <hauke@hauke-m.de>
> ---
> Felix, INAGAKI, Hauke: I need approve for this change from each of you.
> If you are OK with it, can you reply with a line like:
>
> Acked-by: <name> "<e-mail>"
>
> please?
> ---
> arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts | 3 +--
> arch/arm/boot/dts/bcm47081-buffalo-wzr-900dhp.dts | 13 +------------
> arch/arm/boot/dts/bcm4709-buffalo-wxr-1900dhp.dts | 3 +--
> 3 files changed, 3 insertions(+), 16 deletions(-)
>
> diff --git a/arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts b/arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts
> index 8b64caabaad8..a587384f8e40 100644
> --- a/arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts
> +++ b/arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts
> @@ -1,10 +1,9 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
> /*
> * Broadcom BCM470X / BCM5301X ARM platform code.
> * DTS for Buffalo WZR-1750DHP
> *
> * Copyright (C) 2014 Rafa? Mi?ecki <zajec5@gmail.com>
> - *
> - * Licensed under the GNU/GPL. See COPYING for details.
> */
>
> /dts-v1/;
> diff --git a/arch/arm/boot/dts/bcm47081-buffalo-wzr-900dhp.dts b/arch/arm/boot/dts/bcm47081-buffalo-wzr-900dhp.dts
> index 87ea6ba664f5..8ea46eed26e2 100644
> --- a/arch/arm/boot/dts/bcm47081-buffalo-wzr-900dhp.dts
> +++ b/arch/arm/boot/dts/bcm47081-buffalo-wzr-900dhp.dts
> @@ -1,20 +1,9 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
> /*
> * Broadcom BCM470X / BCM5301X ARM platform code.
> * DTS for Buffalo WZR-900DHP
> *
> * Copyright (C) 2015 Rafa? Mi?ecki <zajec5@gmail.com>
> - *
> - * Permission to use, copy, modify, and/or distribute this software for any
> - * purpose with or without fee is hereby granted, provided that the above
> - * copyright notice and this permission notice appear in all copies.
> - *
> - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
> - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
> - * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
> - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
> - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
> - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
> - * PERFORMANCE OF THIS SOFTWARE.
> */
>
> /dts-v1/;
> diff --git a/arch/arm/boot/dts/bcm4709-buffalo-wxr-1900dhp.dts b/arch/arm/boot/dts/bcm4709-buffalo-wxr-1900dhp.dts
> index 92058c73ee59..79a9633ec417 100644
> --- a/arch/arm/boot/dts/bcm4709-buffalo-wxr-1900dhp.dts
> +++ b/arch/arm/boot/dts/bcm4709-buffalo-wxr-1900dhp.dts
> @@ -1,10 +1,9 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
> /*
> * Broadcom BCM470X / BCM5301X ARM platform code.
> * DTS for Buffalo WXR-1900DHP
> *
> * Copyright (C) 2015 Felix Fietkau <nbd@openwrt.org>
> - *
> - * Licensed under the GNU/GPL. See COPYING for details.
> */
>
> /dts-v1/;
>
^ permalink raw reply
* [PATCH] ARM: dts: BCM5301X: Relicense Asus RT-AC87U file to the GPL 2.0+ / MIT
From: Hauke Mehrtens @ 2018-05-05 10:15 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180504100324.31847-1-zajec5@gmail.com>
On 05/04/2018 12:03 PM, Rafa? Mi?ecki wrote:
> From: Rafa? Mi?ecki <rafal@milecki.pl>
>
> This matches licensing used by other BCM5301X files and is preferred as:
> 1) GPL 2.0+ makes is clearly compatible with Linux kernel
> 2) MIT is also permissive but preferred over ISC
>
> This file were created and ever touched by a group of three people only:
> ?lvaro, Hauke and me.
>
> Signed-off-by: Rafa? Mi?ecki <rafal@milecki.pl>
Acked-by: Hauke Mehrtens <hauke@hauke-m.de>
> ---
> ?lvaro, Hauke: I need approve for this change from each of you. If you
> are OK with it, can you reply with an Acked-by, please?
> ---
> arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts | 13 +------------
> 1 file changed, 1 insertion(+), 12 deletions(-)
>
> diff --git a/arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts b/arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts
> index df473cc41572..22271818f901 100644
> --- a/arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts
> +++ b/arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts
> @@ -1,20 +1,9 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
> /*
> * Broadcom BCM470X / BCM5301X ARM platform code.
> * DTS for Asus RT-AC87U
> *
> * Copyright (C) 2015 Rafa? Mi?ecki <zajec5@gmail.com>
> - *
> - * Permission to use, copy, modify, and/or distribute this software for any
> - * purpose with or without fee is hereby granted, provided that the above
> - * copyright notice and this permission notice appear in all copies.
> - *
> - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
> - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
> - * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
> - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
> - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
> - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
> - * PERFORMANCE OF THIS SOFTWARE.
> */
>
> /dts-v1/;
>
^ permalink raw reply
* [PATCH] locking/atomics: Clean up the atomic.h maze of #defines
From: Boqun Feng @ 2018-05-05 10:16 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180505093829.xfylnedwd5nonhae@gmail.com>
On Sat, May 05, 2018 at 11:38:29AM +0200, Ingo Molnar wrote:
>
> * Ingo Molnar <mingo@kernel.org> wrote:
>
> > * Peter Zijlstra <peterz@infradead.org> wrote:
> >
> > > > So we could do the following simplification on top of that:
> > > >
> > > > #ifndef atomic_fetch_dec_relaxed
> > > > # ifndef atomic_fetch_dec
> > > > # define atomic_fetch_dec(v) atomic_fetch_sub(1, (v))
> > > > # define atomic_fetch_dec_relaxed(v) atomic_fetch_sub_relaxed(1, (v))
> > > > # define atomic_fetch_dec_acquire(v) atomic_fetch_sub_acquire(1, (v))
> > > > # define atomic_fetch_dec_release(v) atomic_fetch_sub_release(1, (v))
> > > > # else
> > > > # define atomic_fetch_dec_relaxed atomic_fetch_dec
> > > > # define atomic_fetch_dec_acquire atomic_fetch_dec
> > > > # define atomic_fetch_dec_release atomic_fetch_dec
> > > > # endif
> > > > #else
> > > > # ifndef atomic_fetch_dec
> > > > # define atomic_fetch_dec(...) __atomic_op_fence(atomic_fetch_dec, __VA_ARGS__)
> > > > # define atomic_fetch_dec_acquire(...) __atomic_op_acquire(atomic_fetch_dec, __VA_ARGS__)
> > > > # define atomic_fetch_dec_release(...) __atomic_op_release(atomic_fetch_dec, __VA_ARGS__)
> > > > # endif
> > > > #endif
> > >
> > > This would disallow an architecture to override just fetch_dec_release for
> > > instance.
> >
> > Couldn't such a crazy arch just define _all_ the 3 APIs in this group?
> > That's really a small price and makes the place pay the complexity
> > price that does the weirdness...
> >
> > > I don't think there currently is any architecture that does that, but the
> > > intent was to allow it to override anything and only provide defaults where it
> > > does not.
> >
> > I'd argue that if a new arch only defines one of these APIs that's probably a bug.
> > If they absolutely want to do it, they still can - by defining all 3 APIs.
> >
> > So there's no loss in arch flexibility.
>
> BTW., PowerPC for example is already in such a situation, it does not define
> atomic_cmpxchg_release(), only the other APIs:
>
> #define atomic_cmpxchg(v, o, n) (cmpxchg(&((v)->counter), (o), (n)))
> #define atomic_cmpxchg_relaxed(v, o, n) \
> cmpxchg_relaxed(&((v)->counter), (o), (n))
> #define atomic_cmpxchg_acquire(v, o, n) \
> cmpxchg_acquire(&((v)->counter), (o), (n))
>
> Was it really the intention on the PowerPC side that the generic code falls back
> to cmpxchg(), i.e.:
>
> # define atomic_cmpxchg_release(...) __atomic_op_release(atomic_cmpxchg, __VA_ARGS__)
>
So ppc has its own definition __atomic_op_release() in
arch/powerpc/include/asm/atomic.h:
#define __atomic_op_release(op, args...) \
({ \
__asm__ __volatile__(PPC_RELEASE_BARRIER "" : : : "memory"); \
op##_relaxed(args); \
})
, and PPC_RELEASE_BARRIER is lwsync, so we map to
lwsync();
atomic_cmpxchg_relaxed(v, o, n);
And the reason, why we don't define atomic_cmpxchg_release() but define
atomic_cmpxchg_acquire() is that, atomic_cmpxchg_*() could provide no
ordering guarantee if the cmp fails, we did this for
atomic_cmpxchg_acquire() but not for atomic_cmpxchg_release(), because
doing so may introduce a memory barrier inside a ll/sc critical section,
please see the comment before __cmpxchg_u32_acquire() in
arch/powerpc/include/asm/cmpxchg.h:
/*
* cmpxchg family don't have order guarantee if cmp part fails, therefore we
* can avoid superfluous barriers if we use assembly code to implement
* cmpxchg() and cmpxchg_acquire(), however we don't do the similar for
* cmpxchg_release() because that will result in putting a barrier in the
* middle of a ll/sc loop, which is probably a bad idea. For example, this
* might cause the conditional store more likely to fail.
*/
Regards,
Boqun
> Which after macro expansion becomes:
>
> smp_mb__before_atomic();
> atomic_cmpxchg_relaxed(v, o, n);
>
> smp_mb__before_atomic() on PowerPC falls back to the generic __smp_mb(), which
> falls back to mb(), which on PowerPC is the 'sync' instruction.
>
> Isn't this a inefficiency bug?
>
> While I'm pretty clueless about PowerPC low level cmpxchg atomics, they appear to
> have the following basic structure:
>
> full cmpxchg():
>
> PPC_ATOMIC_ENTRY_BARRIER # sync
> ldarx + stdcx
> PPC_ATOMIC_EXIT_BARRIER # sync
>
> cmpxchg_relaxed():
>
> ldarx + stdcx
>
> cmpxchg_acquire():
>
> ldarx + stdcx
> PPC_ACQUIRE_BARRIER # lwsync
>
> The logical extension for cmpxchg_release() would be:
>
> cmpxchg_release():
>
> PPC_RELEASE_BARRIER # lwsync
> ldarx + stdcx
>
> But instead we silently get the generic fallback, which does:
>
> smp_mb__before_atomic();
> atomic_cmpxchg_relaxed(v, o, n);
>
> Which maps to:
>
> sync
> ldarx + stdcx
>
> Note that it uses a full barrier instead of lwsync (does that stand for
> 'lightweight sync'?).
>
> Even if it turns out we need the full barrier, with the overly finegrained
> structure of the atomics this detail is totally undocumented and non-obvious.
>
> Thanks,
>
> Ingo
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20180505/84554ee3/attachment.sig>
^ permalink raw reply
* [RFC PATCH] locking/atomics/powerpc: Introduce optimized cmpxchg_release() family of APIs for PowerPC
From: Boqun Feng @ 2018-05-05 10:26 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180505100055.yc4upauxo5etq5ud@gmail.com>
Hi Ingo,
On Sat, May 05, 2018 at 12:00:55PM +0200, Ingo Molnar wrote:
>
> * Ingo Molnar <mingo@kernel.org> wrote:
>
> > > So there's no loss in arch flexibility.
> >
> > BTW., PowerPC for example is already in such a situation, it does not define
> > atomic_cmpxchg_release(), only the other APIs:
> >
> > #define atomic_cmpxchg(v, o, n) (cmpxchg(&((v)->counter), (o), (n)))
> > #define atomic_cmpxchg_relaxed(v, o, n) \
> > cmpxchg_relaxed(&((v)->counter), (o), (n))
> > #define atomic_cmpxchg_acquire(v, o, n) \
> > cmpxchg_acquire(&((v)->counter), (o), (n))
> >
> > Was it really the intention on the PowerPC side that the generic code falls back
> > to cmpxchg(), i.e.:
> >
> > # define atomic_cmpxchg_release(...) __atomic_op_release(atomic_cmpxchg, __VA_ARGS__)
> >
> > Which after macro expansion becomes:
> >
> > smp_mb__before_atomic();
> > atomic_cmpxchg_relaxed(v, o, n);
> >
> > smp_mb__before_atomic() on PowerPC falls back to the generic __smp_mb(), which
> > falls back to mb(), which on PowerPC is the 'sync' instruction.
> >
> > Isn't this a inefficiency bug?
> >
> > While I'm pretty clueless about PowerPC low level cmpxchg atomics, they appear to
> > have the following basic structure:
> >
> > full cmpxchg():
> >
> > PPC_ATOMIC_ENTRY_BARRIER # sync
> > ldarx + stdcx
> > PPC_ATOMIC_EXIT_BARRIER # sync
> >
> > cmpxchg_relaxed():
> >
> > ldarx + stdcx
> >
> > cmpxchg_acquire():
> >
> > ldarx + stdcx
> > PPC_ACQUIRE_BARRIER # lwsync
> >
> > The logical extension for cmpxchg_release() would be:
> >
> > cmpxchg_release():
> >
> > PPC_RELEASE_BARRIER # lwsync
> > ldarx + stdcx
> >
> > But instead we silently get the generic fallback, which does:
> >
> > smp_mb__before_atomic();
> > atomic_cmpxchg_relaxed(v, o, n);
> >
> > Which maps to:
> >
> > sync
> > ldarx + stdcx
> >
> > Note that it uses a full barrier instead of lwsync (does that stand for
> > 'lightweight sync'?).
> >
> > Even if it turns out we need the full barrier, with the overly finegrained
> > structure of the atomics this detail is totally undocumented and non-obvious.
>
> The patch below fills in those bits and implements the optimized cmpxchg_release()
> family of APIs. The end effect should be that cmpxchg_release() will now use
> 'lwsync' instead of 'sync' on PowerPC, for the following APIs:
>
> cmpxchg_release()
> cmpxchg64_release()
> atomic_cmpxchg_release()
> atomic64_cmpxchg_release()
>
> I based this choice of the release barrier on an existing bitops low level PowerPC
> method:
>
> DEFINE_BITOP(clear_bits_unlock, andc, PPC_RELEASE_BARRIER)
>
> This clearly suggests that PPC_RELEASE_BARRIER is in active use and 'lwsync' is
> the 'release barrier' instruction, if I interpreted that right.
>
Thanks for looking into this, but as I said in other email:
https://marc.info/?l=linux-kernel&m=152551511324210&w=2
, we actually generate light weight barriers for cmpxchg_release()
familiy.
The reason of the asymmetry between cmpxchg_acquire() and
cmpxchg_release() is that we want to save a barrier for
cmpxchg_acquire() if the cmp fails, but doing the similar for
cmpxchg_release() will introduce a scenario that puts a barrier in a
ll/sc loop, which may be a bad idea.
> But I know very little about PowerPC so this might be spectacularly wrong. It's
> totally untested as well. I also pretty sick today so my mental capabilities are
> significantly reduced ...
>
Feel sorry about that, hope you well!
Please let me know if you think I should provide more document work to
make this more informative.
Regards,
Boqun
> So not signed off and such.
>
> Thanks,
>
> Ingo
>
> ---
> arch/powerpc/include/asm/atomic.h | 4 ++
> arch/powerpc/include/asm/cmpxchg.h | 81 ++++++++++++++++++++++++++++++++++++++
> 2 files changed, 85 insertions(+)
>
> diff --git a/arch/powerpc/include/asm/atomic.h b/arch/powerpc/include/asm/atomic.h
> index 682b3e6a1e21..f7a6f29acb12 100644
> --- a/arch/powerpc/include/asm/atomic.h
> +++ b/arch/powerpc/include/asm/atomic.h
> @@ -213,6 +213,8 @@ static __inline__ int atomic_dec_return_relaxed(atomic_t *v)
> cmpxchg_relaxed(&((v)->counter), (o), (n))
> #define atomic_cmpxchg_acquire(v, o, n) \
> cmpxchg_acquire(&((v)->counter), (o), (n))
> +#define atomic_cmpxchg_release(v, o, n) \
> + cmpxchg_release(&((v)->counter), (o), (n))
>
> #define atomic_xchg(v, new) (xchg(&((v)->counter), new))
> #define atomic_xchg_relaxed(v, new) xchg_relaxed(&((v)->counter), (new))
> @@ -519,6 +521,8 @@ static __inline__ long atomic64_dec_if_positive(atomic64_t *v)
> cmpxchg_relaxed(&((v)->counter), (o), (n))
> #define atomic64_cmpxchg_acquire(v, o, n) \
> cmpxchg_acquire(&((v)->counter), (o), (n))
> +#define atomic64_cmpxchg_release(v, o, n) \
> + cmpxchg_release(&((v)->counter), (o), (n))
>
> #define atomic64_xchg(v, new) (xchg(&((v)->counter), new))
> #define atomic64_xchg_relaxed(v, new) xchg_relaxed(&((v)->counter), (new))
> diff --git a/arch/powerpc/include/asm/cmpxchg.h b/arch/powerpc/include/asm/cmpxchg.h
> index 9b001f1f6b32..6e46310b1833 100644
> --- a/arch/powerpc/include/asm/cmpxchg.h
> +++ b/arch/powerpc/include/asm/cmpxchg.h
> @@ -213,10 +213,12 @@ __xchg_relaxed(void *ptr, unsigned long x, unsigned int size)
> CMPXCHG_GEN(u8, , PPC_ATOMIC_ENTRY_BARRIER, PPC_ATOMIC_EXIT_BARRIER, "memory");
> CMPXCHG_GEN(u8, _local, , , "memory");
> CMPXCHG_GEN(u8, _acquire, , PPC_ACQUIRE_BARRIER, "memory");
> +CMPXCHG_GEN(u8, _release, PPC_RELEASE_BARRIER, , "memory");
> CMPXCHG_GEN(u8, _relaxed, , , "cc");
> CMPXCHG_GEN(u16, , PPC_ATOMIC_ENTRY_BARRIER, PPC_ATOMIC_EXIT_BARRIER, "memory");
> CMPXCHG_GEN(u16, _local, , , "memory");
> CMPXCHG_GEN(u16, _acquire, , PPC_ACQUIRE_BARRIER, "memory");
> +CMPXCHG_GEN(u16, _release, PPC_RELEASE_BARRIER, , "memory");
> CMPXCHG_GEN(u16, _relaxed, , , "cc");
>
> static __always_inline unsigned long
> @@ -314,6 +316,29 @@ __cmpxchg_u32_acquire(u32 *p, unsigned long old, unsigned long new)
> return prev;
> }
>
> +static __always_inline unsigned long
> +__cmpxchg_u32_release(u32 *p, unsigned long old, unsigned long new)
> +{
> + unsigned long prev;
> +
> + __asm__ __volatile__ (
> + PPC_RELEASE_BARRIER
> +"1: lwarx %0,0,%2 # __cmpxchg_u32_release\n"
> +" cmpw 0,%0,%3\n"
> +" bne- 2f\n"
> + PPC405_ERR77(0, %2)
> +" stwcx. %4,0,%2\n"
> +" bne- 1b\n"
> + "\n"
> +"2:"
> + : "=&r" (prev), "+m" (*p)
> + : "r" (p), "r" (old), "r" (new)
> + : "cc", "memory");
> +
> + return prev;
> +}
> +
> +
> #ifdef CONFIG_PPC64
> static __always_inline unsigned long
> __cmpxchg_u64(volatile unsigned long *p, unsigned long old, unsigned long new)
> @@ -397,6 +422,27 @@ __cmpxchg_u64_acquire(u64 *p, unsigned long old, unsigned long new)
>
> return prev;
> }
> +
> +static __always_inline unsigned long
> +__cmpxchg_u64_release(u64 *p, unsigned long old, unsigned long new)
> +{
> + unsigned long prev;
> +
> + __asm__ __volatile__ (
> + PPC_RELEASE_BARRIER
> +"1: ldarx %0,0,%2 # __cmpxchg_u64_release\n"
> +" cmpd 0,%0,%3\n"
> +" bne- 2f\n"
> +" stdcx. %4,0,%2\n"
> +" bne- 1b\n"
> + "\n"
> +"2:"
> + : "=&r" (prev), "+m" (*p)
> + : "r" (p), "r" (old), "r" (new)
> + : "cc", "memory");
> +
> + return prev;
> +}
> #endif
>
> static __always_inline unsigned long
> @@ -478,6 +524,27 @@ __cmpxchg_acquire(void *ptr, unsigned long old, unsigned long new,
> BUILD_BUG_ON_MSG(1, "Unsupported size for __cmpxchg_acquire");
> return old;
> }
> +
> +static __always_inline unsigned long
> +__cmpxchg_release(void *ptr, unsigned long old, unsigned long new,
> + unsigned int size)
> +{
> + switch (size) {
> + case 1:
> + return __cmpxchg_u8_release(ptr, old, new);
> + case 2:
> + return __cmpxchg_u16_release(ptr, old, new);
> + case 4:
> + return __cmpxchg_u32_release(ptr, old, new);
> +#ifdef CONFIG_PPC64
> + case 8:
> + return __cmpxchg_u64_release(ptr, old, new);
> +#endif
> + }
> + BUILD_BUG_ON_MSG(1, "Unsupported size for __cmpxchg_release");
> + return old;
> +}
> +
> #define cmpxchg(ptr, o, n) \
> ({ \
> __typeof__(*(ptr)) _o_ = (o); \
> @@ -512,6 +579,15 @@ __cmpxchg_acquire(void *ptr, unsigned long old, unsigned long new,
> (unsigned long)_o_, (unsigned long)_n_, \
> sizeof(*(ptr))); \
> })
> +
> +#define cmpxchg_release(ptr, o, n) \
> +({ \
> + __typeof__(*(ptr)) _o_ = (o); \
> + __typeof__(*(ptr)) _n_ = (n); \
> + (__typeof__(*(ptr))) __cmpxchg_release((ptr), \
> + (unsigned long)_o_, (unsigned long)_n_, \
> + sizeof(*(ptr))); \
> +})
> #ifdef CONFIG_PPC64
> #define cmpxchg64(ptr, o, n) \
> ({ \
> @@ -533,6 +609,11 @@ __cmpxchg_acquire(void *ptr, unsigned long old, unsigned long new,
> BUILD_BUG_ON(sizeof(*(ptr)) != 8); \
> cmpxchg_acquire((ptr), (o), (n)); \
> })
> +#define cmpxchg64_release(ptr, o, n) \
> +({ \
> + BUILD_BUG_ON(sizeof(*(ptr)) != 8); \
> + cmpxchg_release((ptr), (o), (n)); \
> +})
> #else
> #include <asm-generic/cmpxchg-local.h>
> #define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n))
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20180505/064f3b95/attachment-0001.sig>
^ permalink raw reply
* [RFC PATCH] locking/atomics/powerpc: Clarify why the cmpxchg_relaxed() family of APIs falls back to full cmpxchg()
From: Ingo Molnar @ 2018-05-05 10:35 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180505101609.5wb56j4mspjkokmw@tardis>
* Boqun Feng <boqun.feng@gmail.com> wrote:
> On Sat, May 05, 2018 at 11:38:29AM +0200, Ingo Molnar wrote:
> >
> > * Ingo Molnar <mingo@kernel.org> wrote:
> >
> > > * Peter Zijlstra <peterz@infradead.org> wrote:
> > >
> > > > > So we could do the following simplification on top of that:
> > > > >
> > > > > #ifndef atomic_fetch_dec_relaxed
> > > > > # ifndef atomic_fetch_dec
> > > > > # define atomic_fetch_dec(v) atomic_fetch_sub(1, (v))
> > > > > # define atomic_fetch_dec_relaxed(v) atomic_fetch_sub_relaxed(1, (v))
> > > > > # define atomic_fetch_dec_acquire(v) atomic_fetch_sub_acquire(1, (v))
> > > > > # define atomic_fetch_dec_release(v) atomic_fetch_sub_release(1, (v))
> > > > > # else
> > > > > # define atomic_fetch_dec_relaxed atomic_fetch_dec
> > > > > # define atomic_fetch_dec_acquire atomic_fetch_dec
> > > > > # define atomic_fetch_dec_release atomic_fetch_dec
> > > > > # endif
> > > > > #else
> > > > > # ifndef atomic_fetch_dec
> > > > > # define atomic_fetch_dec(...) __atomic_op_fence(atomic_fetch_dec, __VA_ARGS__)
> > > > > # define atomic_fetch_dec_acquire(...) __atomic_op_acquire(atomic_fetch_dec, __VA_ARGS__)
> > > > > # define atomic_fetch_dec_release(...) __atomic_op_release(atomic_fetch_dec, __VA_ARGS__)
> > > > > # endif
> > > > > #endif
> > > >
> > > > This would disallow an architecture to override just fetch_dec_release for
> > > > instance.
> > >
> > > Couldn't such a crazy arch just define _all_ the 3 APIs in this group?
> > > That's really a small price and makes the place pay the complexity
> > > price that does the weirdness...
> > >
> > > > I don't think there currently is any architecture that does that, but the
> > > > intent was to allow it to override anything and only provide defaults where it
> > > > does not.
> > >
> > > I'd argue that if a new arch only defines one of these APIs that's probably a bug.
> > > If they absolutely want to do it, they still can - by defining all 3 APIs.
> > >
> > > So there's no loss in arch flexibility.
> >
> > BTW., PowerPC for example is already in such a situation, it does not define
> > atomic_cmpxchg_release(), only the other APIs:
> >
> > #define atomic_cmpxchg(v, o, n) (cmpxchg(&((v)->counter), (o), (n)))
> > #define atomic_cmpxchg_relaxed(v, o, n) \
> > cmpxchg_relaxed(&((v)->counter), (o), (n))
> > #define atomic_cmpxchg_acquire(v, o, n) \
> > cmpxchg_acquire(&((v)->counter), (o), (n))
> >
> > Was it really the intention on the PowerPC side that the generic code falls back
> > to cmpxchg(), i.e.:
> >
> > # define atomic_cmpxchg_release(...) __atomic_op_release(atomic_cmpxchg, __VA_ARGS__)
> >
>
> So ppc has its own definition __atomic_op_release() in
> arch/powerpc/include/asm/atomic.h:
>
> #define __atomic_op_release(op, args...) \
> ({ \
> __asm__ __volatile__(PPC_RELEASE_BARRIER "" : : : "memory"); \
> op##_relaxed(args); \
> })
>
> , and PPC_RELEASE_BARRIER is lwsync, so we map to
>
> lwsync();
> atomic_cmpxchg_relaxed(v, o, n);
>
> And the reason, why we don't define atomic_cmpxchg_release() but define
> atomic_cmpxchg_acquire() is that, atomic_cmpxchg_*() could provide no
> ordering guarantee if the cmp fails, we did this for
> atomic_cmpxchg_acquire() but not for atomic_cmpxchg_release(), because
> doing so may introduce a memory barrier inside a ll/sc critical section,
> please see the comment before __cmpxchg_u32_acquire() in
> arch/powerpc/include/asm/cmpxchg.h:
>
> /*
> * cmpxchg family don't have order guarantee if cmp part fails, therefore we
> * can avoid superfluous barriers if we use assembly code to implement
> * cmpxchg() and cmpxchg_acquire(), however we don't do the similar for
> * cmpxchg_release() because that will result in putting a barrier in the
> * middle of a ll/sc loop, which is probably a bad idea. For example, this
> * might cause the conditional store more likely to fail.
> */
Makes sense, thanks a lot for the explanation, missed that comment in the middle
of the assembly functions!
So the patch I sent is buggy, please disregard it.
May I suggest the patch below? No change in functionality, but it documents the
lack of the cmpxchg_release() APIs and maps them explicitly to the full cmpxchg()
version. (Which the generic code does now in a rather roundabout way.)
Also, the change to arch/powerpc/include/asm/atomic.h has no functional effect
right now either, but should anyone add a _relaxed() variant in the future, with
this change atomic_cmpxchg_release() and atomic64_cmpxchg_release() will pick that
up automatically.
Would this be acceptable?
Thanks,
Ingo
---
arch/powerpc/include/asm/atomic.h | 4 ++++
arch/powerpc/include/asm/cmpxchg.h | 13 +++++++++++++
2 files changed, 17 insertions(+)
diff --git a/arch/powerpc/include/asm/atomic.h b/arch/powerpc/include/asm/atomic.h
index 682b3e6a1e21..f7a6f29acb12 100644
--- a/arch/powerpc/include/asm/atomic.h
+++ b/arch/powerpc/include/asm/atomic.h
@@ -213,6 +213,8 @@ static __inline__ int atomic_dec_return_relaxed(atomic_t *v)
cmpxchg_relaxed(&((v)->counter), (o), (n))
#define atomic_cmpxchg_acquire(v, o, n) \
cmpxchg_acquire(&((v)->counter), (o), (n))
+#define atomic_cmpxchg_release(v, o, n) \
+ cmpxchg_release(&((v)->counter), (o), (n))
#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
#define atomic_xchg_relaxed(v, new) xchg_relaxed(&((v)->counter), (new))
@@ -519,6 +521,8 @@ static __inline__ long atomic64_dec_if_positive(atomic64_t *v)
cmpxchg_relaxed(&((v)->counter), (o), (n))
#define atomic64_cmpxchg_acquire(v, o, n) \
cmpxchg_acquire(&((v)->counter), (o), (n))
+#define atomic64_cmpxchg_release(v, o, n) \
+ cmpxchg_release(&((v)->counter), (o), (n))
#define atomic64_xchg(v, new) (xchg(&((v)->counter), new))
#define atomic64_xchg_relaxed(v, new) xchg_relaxed(&((v)->counter), (new))
diff --git a/arch/powerpc/include/asm/cmpxchg.h b/arch/powerpc/include/asm/cmpxchg.h
index 9b001f1f6b32..1f1d35062f3a 100644
--- a/arch/powerpc/include/asm/cmpxchg.h
+++ b/arch/powerpc/include/asm/cmpxchg.h
@@ -512,6 +512,13 @@ __cmpxchg_acquire(void *ptr, unsigned long old, unsigned long new,
(unsigned long)_o_, (unsigned long)_n_, \
sizeof(*(ptr))); \
})
+
+/*
+ * cmpxchg_release() falls back to a full cmpxchg(),
+ * see the comments at __cmpxchg_u32_acquire():
+ */
+#define cmpxchg_release cmpxchg
+
#ifdef CONFIG_PPC64
#define cmpxchg64(ptr, o, n) \
({ \
@@ -538,5 +545,11 @@ __cmpxchg_acquire(void *ptr, unsigned long old, unsigned long new,
#define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n))
#endif
+/*
+ * cmpxchg64_release() falls back to a full cmpxchg(),
+ * see the comments at __cmpxchg_u32_acquire():
+ */
+#define cmpxchg64_release cmpxchg64
+
#endif /* __KERNEL__ */
#endif /* _ASM_POWERPC_CMPXCHG_H_ */
^ permalink raw reply related
* [PATCH v14 8/8] ASoC: sun4i-codec: Add Left Capture Select, Right Capture Select
From: Danny Milosavljevic @ 2018-05-05 10:40 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180503145408.yymk2ndt4sm2yt4i@flea>
Hi Maxime,
On Thu, 3 May 2018 16:54:08 +0200
Maxime Ripard <maxime.ripard@bootlin.com> wrote:
> > +static const char * const sun4i_codec_capture_source[] = {
> > + "Line",
> > + "FM",
> > + "Mic1",
> > + "Mic2",
> > + "Mic1,Mic2",
> > + "Mic1+Mic2",
> > + "Output Mixer",
> > + "Line,Mic1",
> > +};
>
> Shouldn't that be defined in a more generic way? As far as I know,
> there's no way to tell what the difference between "Mic1,Mic2" and
> "Mic1+Mic2" would be from the userspace.
Sounds good - but how?
Here, "Mic1,Mic2" means the left channel captured is Mic1 and the right
channel captured is Mic2.
On the other hand, "Mic1+Mic2" means that the signals from Mic1 and
Mic2 are added together and that is captured (both as left and as right).
"Mic1" means both the left channel and the right channel captured is
from Mic1. Likewise "Mic2".
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 488 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20180505/01a96e0c/attachment.sig>
^ permalink raw reply
* [PATCH] locking/atomics: Shorten the __atomic_op() defines to __op()
From: Ingo Molnar @ 2018-05-05 10:48 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180505092911.GC12217@hirez.programming.kicks-ass.net>
* Peter Zijlstra <peterz@infradead.org> wrote:
> On Sat, May 05, 2018 at 11:09:03AM +0200, Ingo Molnar wrote:
> > > > # ifndef atomic_fetch_dec_acquire
> > > > # define atomic_fetch_dec_acquire(...) __atomic_op_acquire(atomic_fetch_dec, __VA_ARGS__)
> > > > # endif
> > > > # ifndef atomic_fetch_dec_release
> > > > # define atomic_fetch_dec_release(...) __atomic_op_release(atomic_fetch_dec, __VA_ARGS__)
> > > > # endif
> > > > # ifndef atomic_fetch_dec
> > > > # define atomic_fetch_dec(...) __atomic_op_fence(atomic_fetch_dec, __VA_ARGS__)
> > > > # endif
> > > > #endif
> > > >
> > > > The new variant is readable at a glance, and the hierarchy of defines is very
> > > > obvious as well.
> > >
> > > It wraps and looks hideous in my normal setup. And I do detest that indent
> > > after # thing.
> >
> > You should use wider terminals if you take a look at such code - there's already
> > numerous areas of the kernel that are not readable on 80x25 terminals.
> >
> > _Please_ try the following experiment, for me:
> >
> > Enter the 21st century temporarily and widen two of your terminals from 80 cols to
> > 100 cols - it's only ~20% wider.
>
> Doesn't work that way. The only way I get more columns is if I shrink my
> font further. I work with tiles per monitor (left/right obv.) and use
> two columns per editor. This gets me a total of 4 columns.
>
> On my desktop that is slightly over 100 characters per column, on my
> laptop that is slightly below 100 -- mostly because I'm pixel limited on
> fontsize on that thing (FullHD sucks).
>
> If it wraps it wraps.
Out of the 707 lines in atomic.h only 25 are wider than 100 chars - and the max
length is 104 chars.
If that's too then there's a few more things we could do - for example the
attached patch renames a (very minor) misnomer to a shorter name and thus saves on
the longest lines, the column histogram now looks like this:
79 4
80 7
81 3
82 9
84 4
85 2
86 3
87 1
88 4
89 13
90 7
91 20
92 18
93 12
94 11
96 5
I.e. the longest line is down to 96 columns, and 99% of the file is 94 cols or
shorter.
Is this still too long?
Thanks,
Ingo
============================>
From: Ingo Molnar <mingo@kernel.org>
Date: Sat, 5 May 2018 12:41:57 +0200
Subject: [PATCH] locking/atomics: Shorten the __atomic_op() defines to __op()
The __atomic prefix is somewhat of a misnomer, because not all
APIs we use with these macros have an atomic_ prefix.
This also reduces the length of the longest lines in the header,
making them more readable on PeterZ's terminals.
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Cc: Paul E. McKenney <paulmck@us.ibm.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Will Deacon <will.deacon@arm.com>
Cc: aryabinin at virtuozzo.com
Cc: boqun.feng at gmail.com
Cc: catalin.marinas at arm.com
Cc: dvyukov at google.com
Cc: linux-arm-kernel at lists.infradead.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
include/linux/atomic.h | 204 +++++++++++++++++++++++++------------------------
1 file changed, 103 insertions(+), 101 deletions(-)
diff --git a/include/linux/atomic.h b/include/linux/atomic.h
index 1176cf7c6f03..f32ff6d9e4d2 100644
--- a/include/linux/atomic.h
+++ b/include/linux/atomic.h
@@ -37,33 +37,35 @@
* variant is already fully ordered, no additional barriers are needed.
*
* Besides, if an arch has a special barrier for acquire/release, it could
- * implement its own __atomic_op_* and use the same framework for building
+ * implement its own __op_* and use the same framework for building
* variants
*
- * If an architecture overrides __atomic_op_acquire() it will probably want
+ * If an architecture overrides __op_acquire() it will probably want
* to define smp_mb__after_spinlock().
*/
-#ifndef __atomic_op_acquire
-#define __atomic_op_acquire(op, args...) \
+#ifndef __op_acquire
+#define __op_acquire(op, args...) \
({ \
typeof(op##_relaxed(args)) __ret = op##_relaxed(args); \
+ \
smp_mb__after_atomic(); \
__ret; \
})
#endif
-#ifndef __atomic_op_release
-#define __atomic_op_release(op, args...) \
+#ifndef __op_release
+#define __op_release(op, args...) \
({ \
smp_mb__before_atomic(); \
op##_relaxed(args); \
})
#endif
-#ifndef __atomic_op_fence
-#define __atomic_op_fence(op, args...) \
+#ifndef __op_fence
+#define __op_fence(op, args...) \
({ \
typeof(op##_relaxed(args)) __ret; \
+ \
smp_mb__before_atomic(); \
__ret = op##_relaxed(args); \
smp_mb__after_atomic(); \
@@ -77,9 +79,9 @@
# define atomic_add_return_release atomic_add_return
#else
# ifndef atomic_add_return
-# define atomic_add_return(...) __atomic_op_fence(atomic_add_return, __VA_ARGS__)
-# define atomic_add_return_acquire(...) __atomic_op_acquire(atomic_add_return, __VA_ARGS__)
-# define atomic_add_return_release(...) __atomic_op_release(atomic_add_return, __VA_ARGS__)
+# define atomic_add_return(...) __op_fence(atomic_add_return, __VA_ARGS__)
+# define atomic_add_return_acquire(...) __op_acquire(atomic_add_return, __VA_ARGS__)
+# define atomic_add_return_release(...) __op_release(atomic_add_return, __VA_ARGS__)
# endif
#endif
@@ -89,9 +91,9 @@
# define atomic_inc_return_release atomic_inc_return
#else
# ifndef atomic_inc_return
-# define atomic_inc_return(...) __atomic_op_fence(atomic_inc_return, __VA_ARGS__)
-# define atomic_inc_return_acquire(...) __atomic_op_acquire(atomic_inc_return, __VA_ARGS__)
-# define atomic_inc_return_release(...) __atomic_op_release(atomic_inc_return, __VA_ARGS__)
+# define atomic_inc_return(...) __op_fence(atomic_inc_return, __VA_ARGS__)
+# define atomic_inc_return_acquire(...) __op_acquire(atomic_inc_return, __VA_ARGS__)
+# define atomic_inc_return_release(...) __op_release(atomic_inc_return, __VA_ARGS__)
# endif
#endif
@@ -101,9 +103,9 @@
# define atomic_sub_return_release atomic_sub_return
#else
# ifndef atomic_sub_return
-# define atomic_sub_return(...) __atomic_op_fence(atomic_sub_return, __VA_ARGS__)
-# define atomic_sub_return_acquire(...) __atomic_op_acquire(atomic_sub_return, __VA_ARGS__)
-# define atomic_sub_return_release(...) __atomic_op_release(atomic_sub_return, __VA_ARGS__)
+# define atomic_sub_return(...) __op_fence(atomic_sub_return, __VA_ARGS__)
+# define atomic_sub_return_acquire(...) __op_acquire(atomic_sub_return, __VA_ARGS__)
+# define atomic_sub_return_release(...) __op_release(atomic_sub_return, __VA_ARGS__)
# endif
#endif
@@ -113,9 +115,9 @@
# define atomic_dec_return_release atomic_dec_return
#else
# ifndef atomic_dec_return
-# define atomic_dec_return(...) __atomic_op_fence(atomic_dec_return, __VA_ARGS__)
-# define atomic_dec_return_acquire(...) __atomic_op_acquire(atomic_dec_return, __VA_ARGS__)
-# define atomic_dec_return_release(...) __atomic_op_release(atomic_dec_return, __VA_ARGS__)
+# define atomic_dec_return(...) __op_fence(atomic_dec_return, __VA_ARGS__)
+# define atomic_dec_return_acquire(...) __op_acquire(atomic_dec_return, __VA_ARGS__)
+# define atomic_dec_return_release(...) __op_release(atomic_dec_return, __VA_ARGS__)
# endif
#endif
@@ -125,9 +127,9 @@
# define atomic_fetch_add_release atomic_fetch_add
#else
# ifndef atomic_fetch_add
-# define atomic_fetch_add(...) __atomic_op_fence(atomic_fetch_add, __VA_ARGS__)
-# define atomic_fetch_add_acquire(...) __atomic_op_acquire(atomic_fetch_add, __VA_ARGS__)
-# define atomic_fetch_add_release(...) __atomic_op_release(atomic_fetch_add, __VA_ARGS__)
+# define atomic_fetch_add(...) __op_fence(atomic_fetch_add, __VA_ARGS__)
+# define atomic_fetch_add_acquire(...) __op_acquire(atomic_fetch_add, __VA_ARGS__)
+# define atomic_fetch_add_release(...) __op_release(atomic_fetch_add, __VA_ARGS__)
# endif
#endif
@@ -144,9 +146,9 @@
# endif
#else
# ifndef atomic_fetch_inc
-# define atomic_fetch_inc(...) __atomic_op_fence(atomic_fetch_inc, __VA_ARGS__)
-# define atomic_fetch_inc_acquire(...) __atomic_op_acquire(atomic_fetch_inc, __VA_ARGS__)
-# define atomic_fetch_inc_release(...) __atomic_op_release(atomic_fetch_inc, __VA_ARGS__)
+# define atomic_fetch_inc(...) __op_fence(atomic_fetch_inc, __VA_ARGS__)
+# define atomic_fetch_inc_acquire(...) __op_acquire(atomic_fetch_inc, __VA_ARGS__)
+# define atomic_fetch_inc_release(...) __op_release(atomic_fetch_inc, __VA_ARGS__)
# endif
#endif
@@ -156,9 +158,9 @@
# define atomic_fetch_sub_release atomic_fetch_sub
#else
# ifndef atomic_fetch_sub
-# define atomic_fetch_sub(...) __atomic_op_fence(atomic_fetch_sub, __VA_ARGS__)
-# define atomic_fetch_sub_acquire(...) __atomic_op_acquire(atomic_fetch_sub, __VA_ARGS__)
-# define atomic_fetch_sub_release(...) __atomic_op_release(atomic_fetch_sub, __VA_ARGS__)
+# define atomic_fetch_sub(...) __op_fence(atomic_fetch_sub, __VA_ARGS__)
+# define atomic_fetch_sub_acquire(...) __op_acquire(atomic_fetch_sub, __VA_ARGS__)
+# define atomic_fetch_sub_release(...) __op_release(atomic_fetch_sub, __VA_ARGS__)
# endif
#endif
@@ -175,9 +177,9 @@
# endif
#else
# ifndef atomic_fetch_dec
-# define atomic_fetch_dec(...) __atomic_op_fence(atomic_fetch_dec, __VA_ARGS__)
-# define atomic_fetch_dec_acquire(...) __atomic_op_acquire(atomic_fetch_dec, __VA_ARGS__)
-# define atomic_fetch_dec_release(...) __atomic_op_release(atomic_fetch_dec, __VA_ARGS__)
+# define atomic_fetch_dec(...) __op_fence(atomic_fetch_dec, __VA_ARGS__)
+# define atomic_fetch_dec_acquire(...) __op_acquire(atomic_fetch_dec, __VA_ARGS__)
+# define atomic_fetch_dec_release(...) __op_release(atomic_fetch_dec, __VA_ARGS__)
# endif
#endif
@@ -187,9 +189,9 @@
# define atomic_fetch_or_release atomic_fetch_or
#else
# ifndef atomic_fetch_or
-# define atomic_fetch_or(...) __atomic_op_fence(atomic_fetch_or, __VA_ARGS__)
-# define atomic_fetch_or_acquire(...) __atomic_op_acquire(atomic_fetch_or, __VA_ARGS__)
-# define atomic_fetch_or_release(...) __atomic_op_release(atomic_fetch_or, __VA_ARGS__)
+# define atomic_fetch_or(...) __op_fence(atomic_fetch_or, __VA_ARGS__)
+# define atomic_fetch_or_acquire(...) __op_acquire(atomic_fetch_or, __VA_ARGS__)
+# define atomic_fetch_or_release(...) __op_release(atomic_fetch_or, __VA_ARGS__)
# endif
#endif
@@ -199,9 +201,9 @@
# define atomic_fetch_and_release atomic_fetch_and
#else
# ifndef atomic_fetch_and
-# define atomic_fetch_and(...) __atomic_op_fence(atomic_fetch_and, __VA_ARGS__)
-# define atomic_fetch_and_acquire(...) __atomic_op_acquire(atomic_fetch_and, __VA_ARGS__)
-# define atomic_fetch_and_release(...) __atomic_op_release(atomic_fetch_and, __VA_ARGS__)
+# define atomic_fetch_and(...) __op_fence(atomic_fetch_and, __VA_ARGS__)
+# define atomic_fetch_and_acquire(...) __op_acquire(atomic_fetch_and, __VA_ARGS__)
+# define atomic_fetch_and_release(...) __op_release(atomic_fetch_and, __VA_ARGS__)
# endif
#endif
@@ -211,9 +213,9 @@
# define atomic_fetch_xor_release atomic_fetch_xor
#else
# ifndef atomic_fetch_xor
-# define atomic_fetch_xor(...) __atomic_op_fence(atomic_fetch_xor, __VA_ARGS__)
-# define atomic_fetch_xor_acquire(...) __atomic_op_acquire(atomic_fetch_xor, __VA_ARGS__)
-# define atomic_fetch_xor_release(...) __atomic_op_release(atomic_fetch_xor, __VA_ARGS__)
+# define atomic_fetch_xor(...) __op_fence(atomic_fetch_xor, __VA_ARGS__)
+# define atomic_fetch_xor_acquire(...) __op_acquire(atomic_fetch_xor, __VA_ARGS__)
+# define atomic_fetch_xor_release(...) __op_release(atomic_fetch_xor, __VA_ARGS__)
# endif
#endif
@@ -223,9 +225,9 @@
#define atomic_xchg_release atomic_xchg
#else
# ifndef atomic_xchg
-# define atomic_xchg(...) __atomic_op_fence(atomic_xchg, __VA_ARGS__)
-# define atomic_xchg_acquire(...) __atomic_op_acquire(atomic_xchg, __VA_ARGS__)
-# define atomic_xchg_release(...) __atomic_op_release(atomic_xchg, __VA_ARGS__)
+# define atomic_xchg(...) __op_fence(atomic_xchg, __VA_ARGS__)
+# define atomic_xchg_acquire(...) __op_acquire(atomic_xchg, __VA_ARGS__)
+# define atomic_xchg_release(...) __op_release(atomic_xchg, __VA_ARGS__)
# endif
#endif
@@ -235,9 +237,9 @@
# define atomic_cmpxchg_release atomic_cmpxchg
#else
# ifndef atomic_cmpxchg
-# define atomic_cmpxchg(...) __atomic_op_fence(atomic_cmpxchg, __VA_ARGS__)
-# define atomic_cmpxchg_acquire(...) __atomic_op_acquire(atomic_cmpxchg, __VA_ARGS__)
-# define atomic_cmpxchg_release(...) __atomic_op_release(atomic_cmpxchg, __VA_ARGS__)
+# define atomic_cmpxchg(...) __op_fence(atomic_cmpxchg, __VA_ARGS__)
+# define atomic_cmpxchg_acquire(...) __op_acquire(atomic_cmpxchg, __VA_ARGS__)
+# define atomic_cmpxchg_release(...) __op_release(atomic_cmpxchg, __VA_ARGS__)
# endif
#endif
@@ -267,9 +269,9 @@
# define cmpxchg_release cmpxchg
#else
# ifndef cmpxchg
-# define cmpxchg(...) __atomic_op_fence(cmpxchg, __VA_ARGS__)
-# define cmpxchg_acquire(...) __atomic_op_acquire(cmpxchg, __VA_ARGS__)
-# define cmpxchg_release(...) __atomic_op_release(cmpxchg, __VA_ARGS__)
+# define cmpxchg(...) __op_fence(cmpxchg, __VA_ARGS__)
+# define cmpxchg_acquire(...) __op_acquire(cmpxchg, __VA_ARGS__)
+# define cmpxchg_release(...) __op_release(cmpxchg, __VA_ARGS__)
# endif
#endif
@@ -279,9 +281,9 @@
# define cmpxchg64_release cmpxchg64
#else
# ifndef cmpxchg64
-# define cmpxchg64(...) __atomic_op_fence(cmpxchg64, __VA_ARGS__)
-# define cmpxchg64_acquire(...) __atomic_op_acquire(cmpxchg64, __VA_ARGS__)
-# define cmpxchg64_release(...) __atomic_op_release(cmpxchg64, __VA_ARGS__)
+# define cmpxchg64(...) __op_fence(cmpxchg64, __VA_ARGS__)
+# define cmpxchg64_acquire(...) __op_acquire(cmpxchg64, __VA_ARGS__)
+# define cmpxchg64_release(...) __op_release(cmpxchg64, __VA_ARGS__)
# endif
#endif
@@ -291,9 +293,9 @@
# define xchg_release xchg
#else
# ifndef xchg
-# define xchg(...) __atomic_op_fence(xchg, __VA_ARGS__)
-# define xchg_acquire(...) __atomic_op_acquire(xchg, __VA_ARGS__)
-# define xchg_release(...) __atomic_op_release(xchg, __VA_ARGS__)
+# define xchg(...) __op_fence(xchg, __VA_ARGS__)
+# define xchg_acquire(...) __op_acquire(xchg, __VA_ARGS__)
+# define xchg_release(...) __op_release(xchg, __VA_ARGS__)
# endif
#endif
@@ -330,9 +332,9 @@ static inline int atomic_add_unless(atomic_t *v, int a, int u)
# define atomic_fetch_andnot_release atomic_fetch_andnot
#else
# ifndef atomic_fetch_andnot
-# define atomic_fetch_andnot(...) __atomic_op_fence(atomic_fetch_andnot, __VA_ARGS__)
-# define atomic_fetch_andnot_acquire(...) __atomic_op_acquire(atomic_fetch_andnot, __VA_ARGS__)
-# define atomic_fetch_andnot_release(...) __atomic_op_release(atomic_fetch_andnot, __VA_ARGS__)
+# define atomic_fetch_andnot(...) __op_fence(atomic_fetch_andnot, __VA_ARGS__)
+# define atomic_fetch_andnot_acquire(...) __op_acquire(atomic_fetch_andnot, __VA_ARGS__)
+# define atomic_fetch_andnot_release(...) __op_release(atomic_fetch_andnot, __VA_ARGS__)
# endif
#endif
@@ -472,9 +474,9 @@ static inline int atomic_dec_if_positive(atomic_t *v)
# define atomic64_add_return_release atomic64_add_return
#else
# ifndef atomic64_add_return
-# define atomic64_add_return(...) __atomic_op_fence(atomic64_add_return, __VA_ARGS__)
-# define atomic64_add_return_acquire(...) __atomic_op_acquire(atomic64_add_return, __VA_ARGS__)
-# define atomic64_add_return_release(...) __atomic_op_release(atomic64_add_return, __VA_ARGS__)
+# define atomic64_add_return(...) __op_fence(atomic64_add_return, __VA_ARGS__)
+# define atomic64_add_return_acquire(...) __op_acquire(atomic64_add_return, __VA_ARGS__)
+# define atomic64_add_return_release(...) __op_release(atomic64_add_return, __VA_ARGS__)
# endif
#endif
@@ -484,9 +486,9 @@ static inline int atomic_dec_if_positive(atomic_t *v)
# define atomic64_inc_return_release atomic64_inc_return
#else
# ifndef atomic64_inc_return
-# define atomic64_inc_return(...) __atomic_op_fence(atomic64_inc_return, __VA_ARGS__)
-# define atomic64_inc_return_acquire(...) __atomic_op_acquire(atomic64_inc_return, __VA_ARGS__)
-# define atomic64_inc_return_release(...) __atomic_op_release(atomic64_inc_return, __VA_ARGS__)
+# define atomic64_inc_return(...) __op_fence(atomic64_inc_return, __VA_ARGS__)
+# define atomic64_inc_return_acquire(...) __op_acquire(atomic64_inc_return, __VA_ARGS__)
+# define atomic64_inc_return_release(...) __op_release(atomic64_inc_return, __VA_ARGS__)
# endif
#endif
@@ -496,9 +498,9 @@ static inline int atomic_dec_if_positive(atomic_t *v)
# define atomic64_sub_return_release atomic64_sub_return
#else
# ifndef atomic64_sub_return
-# define atomic64_sub_return(...) __atomic_op_fence(atomic64_sub_return, __VA_ARGS__)
-# define atomic64_sub_return_acquire(...) __atomic_op_acquire(atomic64_sub_return, __VA_ARGS__)
-# define atomic64_sub_return_release(...) __atomic_op_release(atomic64_sub_return, __VA_ARGS__)
+# define atomic64_sub_return(...) __op_fence(atomic64_sub_return, __VA_ARGS__)
+# define atomic64_sub_return_acquire(...) __op_acquire(atomic64_sub_return, __VA_ARGS__)
+# define atomic64_sub_return_release(...) __op_release(atomic64_sub_return, __VA_ARGS__)
# endif
#endif
@@ -508,9 +510,9 @@ static inline int atomic_dec_if_positive(atomic_t *v)
# define atomic64_dec_return_release atomic64_dec_return
#else
# ifndef atomic64_dec_return
-# define atomic64_dec_return(...) __atomic_op_fence(atomic64_dec_return, __VA_ARGS__)
-# define atomic64_dec_return_acquire(...) __atomic_op_acquire(atomic64_dec_return, __VA_ARGS__)
-# define atomic64_dec_return_release(...) __atomic_op_release(atomic64_dec_return, __VA_ARGS__)
+# define atomic64_dec_return(...) __op_fence(atomic64_dec_return, __VA_ARGS__)
+# define atomic64_dec_return_acquire(...) __op_acquire(atomic64_dec_return, __VA_ARGS__)
+# define atomic64_dec_return_release(...) __op_release(atomic64_dec_return, __VA_ARGS__)
# endif
#endif
@@ -520,9 +522,9 @@ static inline int atomic_dec_if_positive(atomic_t *v)
# define atomic64_fetch_add_release atomic64_fetch_add
#else
# ifndef atomic64_fetch_add
-# define atomic64_fetch_add(...) __atomic_op_fence(atomic64_fetch_add, __VA_ARGS__)
-# define atomic64_fetch_add_acquire(...) __atomic_op_acquire(atomic64_fetch_add, __VA_ARGS__)
-# define atomic64_fetch_add_release(...) __atomic_op_release(atomic64_fetch_add, __VA_ARGS__)
+# define atomic64_fetch_add(...) __op_fence(atomic64_fetch_add, __VA_ARGS__)
+# define atomic64_fetch_add_acquire(...) __op_acquire(atomic64_fetch_add, __VA_ARGS__)
+# define atomic64_fetch_add_release(...) __op_release(atomic64_fetch_add, __VA_ARGS__)
# endif
#endif
@@ -539,9 +541,9 @@ static inline int atomic_dec_if_positive(atomic_t *v)
# endif
#else
# ifndef atomic64_fetch_inc
-# define atomic64_fetch_inc(...) __atomic_op_fence(atomic64_fetch_inc, __VA_ARGS__)
-# define atomic64_fetch_inc_acquire(...) __atomic_op_acquire(atomic64_fetch_inc, __VA_ARGS__)
-# define atomic64_fetch_inc_release(...) __atomic_op_release(atomic64_fetch_inc, __VA_ARGS__)
+# define atomic64_fetch_inc(...) __op_fence(atomic64_fetch_inc, __VA_ARGS__)
+# define atomic64_fetch_inc_acquire(...) __op_acquire(atomic64_fetch_inc, __VA_ARGS__)
+# define atomic64_fetch_inc_release(...) __op_release(atomic64_fetch_inc, __VA_ARGS__)
# endif
#endif
@@ -551,9 +553,9 @@ static inline int atomic_dec_if_positive(atomic_t *v)
# define atomic64_fetch_sub_release atomic64_fetch_sub
#else
# ifndef atomic64_fetch_sub
-# define atomic64_fetch_sub(...) __atomic_op_fence(atomic64_fetch_sub, __VA_ARGS__)
-# define atomic64_fetch_sub_acquire(...) __atomic_op_acquire(atomic64_fetch_sub, __VA_ARGS__)
-# define atomic64_fetch_sub_release(...) __atomic_op_release(atomic64_fetch_sub, __VA_ARGS__)
+# define atomic64_fetch_sub(...) __op_fence(atomic64_fetch_sub, __VA_ARGS__)
+# define atomic64_fetch_sub_acquire(...) __op_acquire(atomic64_fetch_sub, __VA_ARGS__)
+# define atomic64_fetch_sub_release(...) __op_release(atomic64_fetch_sub, __VA_ARGS__)
# endif
#endif
@@ -570,9 +572,9 @@ static inline int atomic_dec_if_positive(atomic_t *v)
# endif
#else
# ifndef atomic64_fetch_dec
-# define atomic64_fetch_dec(...) __atomic_op_fence(atomic64_fetch_dec, __VA_ARGS__)
-# define atomic64_fetch_dec_acquire(...) __atomic_op_acquire(atomic64_fetch_dec, __VA_ARGS__)
-# define atomic64_fetch_dec_release(...) __atomic_op_release(atomic64_fetch_dec, __VA_ARGS__)
+# define atomic64_fetch_dec(...) __op_fence(atomic64_fetch_dec, __VA_ARGS__)
+# define atomic64_fetch_dec_acquire(...) __op_acquire(atomic64_fetch_dec, __VA_ARGS__)
+# define atomic64_fetch_dec_release(...) __op_release(atomic64_fetch_dec, __VA_ARGS__)
# endif
#endif
@@ -582,9 +584,9 @@ static inline int atomic_dec_if_positive(atomic_t *v)
# define atomic64_fetch_or_release atomic64_fetch_or
#else
# ifndef atomic64_fetch_or
-# define atomic64_fetch_or(...) __atomic_op_fence(atomic64_fetch_or, __VA_ARGS__)
-# define atomic64_fetch_or_acquire(...) __atomic_op_acquire(atomic64_fetch_or, __VA_ARGS__)
-# define atomic64_fetch_or_release(...) __atomic_op_release(atomic64_fetch_or, __VA_ARGS__)
+# define atomic64_fetch_or(...) __op_fence(atomic64_fetch_or, __VA_ARGS__)
+# define atomic64_fetch_or_acquire(...) __op_acquire(atomic64_fetch_or, __VA_ARGS__)
+# define atomic64_fetch_or_release(...) __op_release(atomic64_fetch_or, __VA_ARGS__)
# endif
#endif
@@ -594,9 +596,9 @@ static inline int atomic_dec_if_positive(atomic_t *v)
# define atomic64_fetch_and_release atomic64_fetch_and
#else
# ifndef atomic64_fetch_and
-# define atomic64_fetch_and(...) __atomic_op_fence(atomic64_fetch_and, __VA_ARGS__)
-# define atomic64_fetch_and_acquire(...) __atomic_op_acquire(atomic64_fetch_and, __VA_ARGS__)
-# define atomic64_fetch_and_release(...) __atomic_op_release(atomic64_fetch_and, __VA_ARGS__)
+# define atomic64_fetch_and(...) __op_fence(atomic64_fetch_and, __VA_ARGS__)
+# define atomic64_fetch_and_acquire(...) __op_acquire(atomic64_fetch_and, __VA_ARGS__)
+# define atomic64_fetch_and_release(...) __op_release(atomic64_fetch_and, __VA_ARGS__)
# endif
#endif
@@ -606,9 +608,9 @@ static inline int atomic_dec_if_positive(atomic_t *v)
# define atomic64_fetch_xor_release atomic64_fetch_xor
#else
# ifndef atomic64_fetch_xor
-# define atomic64_fetch_xor(...) __atomic_op_fence(atomic64_fetch_xor, __VA_ARGS__)
-# define atomic64_fetch_xor_acquire(...) __atomic_op_acquire(atomic64_fetch_xor, __VA_ARGS__)
-# define atomic64_fetch_xor_release(...) __atomic_op_release(atomic64_fetch_xor, __VA_ARGS__)
+# define atomic64_fetch_xor(...) __op_fence(atomic64_fetch_xor, __VA_ARGS__)
+# define atomic64_fetch_xor_acquire(...) __op_acquire(atomic64_fetch_xor, __VA_ARGS__)
+# define atomic64_fetch_xor_release(...) __op_release(atomic64_fetch_xor, __VA_ARGS__)
# endif
#endif
@@ -618,9 +620,9 @@ static inline int atomic_dec_if_positive(atomic_t *v)
# define atomic64_xchg_release atomic64_xchg
#else
# ifndef atomic64_xchg
-# define atomic64_xchg(...) __atomic_op_fence(atomic64_xchg, __VA_ARGS__)
-# define atomic64_xchg_acquire(...) __atomic_op_acquire(atomic64_xchg, __VA_ARGS__)
-# define atomic64_xchg_release(...) __atomic_op_release(atomic64_xchg, __VA_ARGS__)
+# define atomic64_xchg(...) __op_fence(atomic64_xchg, __VA_ARGS__)
+# define atomic64_xchg_acquire(...) __op_acquire(atomic64_xchg, __VA_ARGS__)
+# define atomic64_xchg_release(...) __op_release(atomic64_xchg, __VA_ARGS__)
# endif
#endif
@@ -630,9 +632,9 @@ static inline int atomic_dec_if_positive(atomic_t *v)
# define atomic64_cmpxchg_release atomic64_cmpxchg
#else
# ifndef atomic64_cmpxchg
-# define atomic64_cmpxchg(...) __atomic_op_fence(atomic64_cmpxchg, __VA_ARGS__)
-# define atomic64_cmpxchg_acquire(...) __atomic_op_acquire(atomic64_cmpxchg, __VA_ARGS__)
-# define atomic64_cmpxchg_release(...) __atomic_op_release(atomic64_cmpxchg, __VA_ARGS__)
+# define atomic64_cmpxchg(...) __op_fence(atomic64_cmpxchg, __VA_ARGS__)
+# define atomic64_cmpxchg_acquire(...) __op_acquire(atomic64_cmpxchg, __VA_ARGS__)
+# define atomic64_cmpxchg_release(...) __op_release(atomic64_cmpxchg, __VA_ARGS__)
# endif
#endif
@@ -664,9 +666,9 @@ static inline int atomic_dec_if_positive(atomic_t *v)
# define atomic64_fetch_andnot_release atomic64_fetch_andnot
#else
# ifndef atomic64_fetch_andnot
-# define atomic64_fetch_andnot(...) __atomic_op_fence(atomic64_fetch_andnot, __VA_ARGS__)
-# define atomic64_fetch_andnot_acquire(...) __atomic_op_acquire(atomic64_fetch_andnot, __VA_ARGS__)
-# define atomic64_fetch_andnot_release(...) __atomic_op_release(atomic64_fetch_andnot, __VA_ARGS__)
+# define atomic64_fetch_andnot(...) __op_fence(atomic64_fetch_andnot, __VA_ARGS__)
+# define atomic64_fetch_andnot_acquire(...) __op_acquire(atomic64_fetch_andnot, __VA_ARGS__)
+# define atomic64_fetch_andnot_release(...) __op_release(atomic64_fetch_andnot, __VA_ARGS__)
# endif
#endif
^ permalink raw reply related
* [PATCH] locking/atomics: Shorten the __atomic_op() defines to __op()
From: Ingo Molnar @ 2018-05-05 10:59 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180505104858.ap4bfv6ip2vprzyj@gmail.com>
* Ingo Molnar <mingo@kernel.org> wrote:
> If that's too then there's a few more things we could do - for example the
^--too much
> attached patch renames a (very minor) misnomer to a shorter name and thus saves on
> the longest lines, the column histogram now looks like this:
Thanks,
Ingo
^ permalink raw reply
* [RFC PATCH] locking/atomics/powerpc: Clarify why the cmpxchg_relaxed() family of APIs falls back to full cmpxchg()
From: Boqun Feng @ 2018-05-05 11:28 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180505103550.s7xsnto7tgppkmle@gmail.com>
On Sat, May 05, 2018 at 12:35:50PM +0200, Ingo Molnar wrote:
>
> * Boqun Feng <boqun.feng@gmail.com> wrote:
>
> > On Sat, May 05, 2018 at 11:38:29AM +0200, Ingo Molnar wrote:
> > >
> > > * Ingo Molnar <mingo@kernel.org> wrote:
> > >
> > > > * Peter Zijlstra <peterz@infradead.org> wrote:
> > > >
> > > > > > So we could do the following simplification on top of that:
> > > > > >
> > > > > > #ifndef atomic_fetch_dec_relaxed
> > > > > > # ifndef atomic_fetch_dec
> > > > > > # define atomic_fetch_dec(v) atomic_fetch_sub(1, (v))
> > > > > > # define atomic_fetch_dec_relaxed(v) atomic_fetch_sub_relaxed(1, (v))
> > > > > > # define atomic_fetch_dec_acquire(v) atomic_fetch_sub_acquire(1, (v))
> > > > > > # define atomic_fetch_dec_release(v) atomic_fetch_sub_release(1, (v))
> > > > > > # else
> > > > > > # define atomic_fetch_dec_relaxed atomic_fetch_dec
> > > > > > # define atomic_fetch_dec_acquire atomic_fetch_dec
> > > > > > # define atomic_fetch_dec_release atomic_fetch_dec
> > > > > > # endif
> > > > > > #else
> > > > > > # ifndef atomic_fetch_dec
> > > > > > # define atomic_fetch_dec(...) __atomic_op_fence(atomic_fetch_dec, __VA_ARGS__)
> > > > > > # define atomic_fetch_dec_acquire(...) __atomic_op_acquire(atomic_fetch_dec, __VA_ARGS__)
> > > > > > # define atomic_fetch_dec_release(...) __atomic_op_release(atomic_fetch_dec, __VA_ARGS__)
> > > > > > # endif
> > > > > > #endif
> > > > >
> > > > > This would disallow an architecture to override just fetch_dec_release for
> > > > > instance.
> > > >
> > > > Couldn't such a crazy arch just define _all_ the 3 APIs in this group?
> > > > That's really a small price and makes the place pay the complexity
> > > > price that does the weirdness...
> > > >
> > > > > I don't think there currently is any architecture that does that, but the
> > > > > intent was to allow it to override anything and only provide defaults where it
> > > > > does not.
> > > >
> > > > I'd argue that if a new arch only defines one of these APIs that's probably a bug.
> > > > If they absolutely want to do it, they still can - by defining all 3 APIs.
> > > >
> > > > So there's no loss in arch flexibility.
> > >
> > > BTW., PowerPC for example is already in such a situation, it does not define
> > > atomic_cmpxchg_release(), only the other APIs:
> > >
> > > #define atomic_cmpxchg(v, o, n) (cmpxchg(&((v)->counter), (o), (n)))
> > > #define atomic_cmpxchg_relaxed(v, o, n) \
> > > cmpxchg_relaxed(&((v)->counter), (o), (n))
> > > #define atomic_cmpxchg_acquire(v, o, n) \
> > > cmpxchg_acquire(&((v)->counter), (o), (n))
> > >
> > > Was it really the intention on the PowerPC side that the generic code falls back
> > > to cmpxchg(), i.e.:
> > >
> > > # define atomic_cmpxchg_release(...) __atomic_op_release(atomic_cmpxchg, __VA_ARGS__)
> > >
> >
> > So ppc has its own definition __atomic_op_release() in
> > arch/powerpc/include/asm/atomic.h:
> >
> > #define __atomic_op_release(op, args...) \
> > ({ \
> > __asm__ __volatile__(PPC_RELEASE_BARRIER "" : : : "memory"); \
> > op##_relaxed(args); \
> > })
> >
> > , and PPC_RELEASE_BARRIER is lwsync, so we map to
> >
> > lwsync();
> > atomic_cmpxchg_relaxed(v, o, n);
> >
> > And the reason, why we don't define atomic_cmpxchg_release() but define
> > atomic_cmpxchg_acquire() is that, atomic_cmpxchg_*() could provide no
> > ordering guarantee if the cmp fails, we did this for
> > atomic_cmpxchg_acquire() but not for atomic_cmpxchg_release(), because
> > doing so may introduce a memory barrier inside a ll/sc critical section,
> > please see the comment before __cmpxchg_u32_acquire() in
> > arch/powerpc/include/asm/cmpxchg.h:
> >
> > /*
> > * cmpxchg family don't have order guarantee if cmp part fails, therefore we
> > * can avoid superfluous barriers if we use assembly code to implement
> > * cmpxchg() and cmpxchg_acquire(), however we don't do the similar for
> > * cmpxchg_release() because that will result in putting a barrier in the
> > * middle of a ll/sc loop, which is probably a bad idea. For example, this
> > * might cause the conditional store more likely to fail.
> > */
>
> Makes sense, thanks a lot for the explanation, missed that comment in the middle
> of the assembly functions!
>
;-) I could move it so somewhere else in the future.
> So the patch I sent is buggy, please disregard it.
>
> May I suggest the patch below? No change in functionality, but it documents the
> lack of the cmpxchg_release() APIs and maps them explicitly to the full cmpxchg()
> version. (Which the generic code does now in a rather roundabout way.)
>
Hmm.. cmpxchg_release() is actually lwsync() + cmpxchg_relaxed(), but
you just make it sync() + cmpxchg_relaxed() + sync() with the fallback,
and sync() is much heavier, so I don't think the fallback is correct.
I think maybe you can move powerpc's __atomic_op_{acqurie,release}()
from atomic.h to cmpxchg.h (in arch/powerpc/include/asm), and
#define cmpxchg_release __atomic_op_release(cmpxchg, __VA_ARGS__);
#define cmpxchg64_release __atomic_op_release(cmpxchg64, __VA_ARGS__);
I put a diff below to say what I mean (untested).
> Also, the change to arch/powerpc/include/asm/atomic.h has no functional effect
> right now either, but should anyone add a _relaxed() variant in the future, with
> this change atomic_cmpxchg_release() and atomic64_cmpxchg_release() will pick that
> up automatically.
>
You mean with your other modification in include/linux/atomic.h, right?
Because with the unmodified include/linux/atomic.h, we already pick that
autmatically. If so, I think that's fine.
Here is the diff for the modification for cmpxchg_release(), the idea is
we generate them in asm/cmpxchg.h other than linux/atomic.h for ppc, so
we keep the new linux/atomic.h working. Because if I understand
correctly, the next linux/atomic.h only accepts that
1) architecture only defines fully ordered primitives
or
2) architecture only defines _relaxed primitives
or
3) architecture defines all four (fully, _relaxed, _acquire,
_release) primitives
So powerpc needs to define all four primitives in its only
asm/cmpxchg.h.
Regards,
Boqun
diff --git a/arch/powerpc/include/asm/atomic.h b/arch/powerpc/include/asm/atomic.h
index 682b3e6a1e21..0136be11c84f 100644
--- a/arch/powerpc/include/asm/atomic.h
+++ b/arch/powerpc/include/asm/atomic.h
@@ -13,24 +13,6 @@
#define ATOMIC_INIT(i) { (i) }
-/*
- * Since *_return_relaxed and {cmp}xchg_relaxed are implemented with
- * a "bne-" instruction at the end, so an isync is enough as a acquire barrier
- * on the platform without lwsync.
- */
-#define __atomic_op_acquire(op, args...) \
-({ \
- typeof(op##_relaxed(args)) __ret = op##_relaxed(args); \
- __asm__ __volatile__(PPC_ACQUIRE_BARRIER "" : : : "memory"); \
- __ret; \
-})
-
-#define __atomic_op_release(op, args...) \
-({ \
- __asm__ __volatile__(PPC_RELEASE_BARRIER "" : : : "memory"); \
- op##_relaxed(args); \
-})
-
static __inline__ int atomic_read(const atomic_t *v)
{
int t;
diff --git a/arch/powerpc/include/asm/cmpxchg.h b/arch/powerpc/include/asm/cmpxchg.h
index 9b001f1f6b32..9e20a942aff9 100644
--- a/arch/powerpc/include/asm/cmpxchg.h
+++ b/arch/powerpc/include/asm/cmpxchg.h
@@ -8,6 +8,24 @@
#include <asm/asm-compat.h>
#include <linux/bug.h>
+/*
+ * Since *_return_relaxed and {cmp}xchg_relaxed are implemented with
+ * a "bne-" instruction at the end, so an isync is enough as a acquire barrier
+ * on the platform without lwsync.
+ */
+#define __atomic_op_acquire(op, args...) \
+({ \
+ typeof(op##_relaxed(args)) __ret = op##_relaxed(args); \
+ __asm__ __volatile__(PPC_ACQUIRE_BARRIER "" : : : "memory"); \
+ __ret; \
+})
+
+#define __atomic_op_release(op, args...) \
+({ \
+ __asm__ __volatile__(PPC_RELEASE_BARRIER "" : : : "memory"); \
+ op##_relaxed(args); \
+})
+
#ifdef __BIG_ENDIAN
#define BITOFF_CAL(size, off) ((sizeof(u32) - size - off) * BITS_PER_BYTE)
#else
@@ -512,6 +530,8 @@ __cmpxchg_acquire(void *ptr, unsigned long old, unsigned long new,
(unsigned long)_o_, (unsigned long)_n_, \
sizeof(*(ptr))); \
})
+
+#define cmpxchg_release(ptr, o, n) __atomic_op_release(cmpxchg, __VA_ARGS__)
#ifdef CONFIG_PPC64
#define cmpxchg64(ptr, o, n) \
({ \
@@ -533,6 +553,7 @@ __cmpxchg_acquire(void *ptr, unsigned long old, unsigned long new,
BUILD_BUG_ON(sizeof(*(ptr)) != 8); \
cmpxchg_acquire((ptr), (o), (n)); \
})
+#define cmpxchg64_release(ptr, o, n) __atomic_op_release(cmpxchg64, __VA_ARGS__)
#else
#include <asm-generic/cmpxchg-local.h>
#define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n))
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20180505/f4d4dc74/attachment.sig>
^ permalink raw reply related
* [PATCH V6 7/7] ARM: dts: imx6sx-sabreauto: add egalax touch screen support
From: Fabio Estevam @ 2018-05-05 11:56 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1525508963-7986-7-git-send-email-Anson.Huang@nxp.com>
Hi Anson,
On Sat, May 5, 2018 at 5:29 AM, Anson Huang <Anson.Huang@nxp.com> wrote:
> Add egalax touch screen support on i2c2 bus.
>
> Signed-off-by: Haibo Chen <haibo.chen@freescale.com>
Is Haibo the author of this patch? If so, his name should appear in
the From field.
> Signed-off-by: Anson Huang <Anson.Huang@nxp.com>
> ---
> changes since V5:
> improve pinctrl node name and touchscreen node name.
> arch/arm/boot/dts/imx6sx-sabreauto.dts | 16 ++++++++++++++++
> 1 file changed, 16 insertions(+)
>
> diff --git a/arch/arm/boot/dts/imx6sx-sabreauto.dts b/arch/arm/boot/dts/imx6sx-sabreauto.dts
> index 1dc5b58..3fe41d3 100644
> --- a/arch/arm/boot/dts/imx6sx-sabreauto.dts
> +++ b/arch/arm/boot/dts/imx6sx-sabreauto.dts
> @@ -122,6 +122,12 @@
> };
>
> &iomuxc {
> + pinctrl_egalax_int: egalax-intgrp {
> + fsl,pins = <
> + MX6SX_PAD_SD4_RESET_B__GPIO6_IO_22 0x80000000
> + >;
> + };
> +
> pinctrl_enet1: enet1grp {
> fsl,pins = <
> MX6SX_PAD_ENET1_MDIO__ENET1_MDIO 0xa0b1
> @@ -264,6 +270,16 @@
> pinctrl-0 = <&pinctrl_i2c2>;
> status = "okay";
>
> + egalax_touchscreen at 4 {
Should be touchscreen at 4.
^ permalink raw reply
* [arm-platforms:irq/level-msi 5/13] kernel//irq/msi.c:88:12: error: 'struct irq_domain' has no member named 'chip'
From: kbuild test robot @ 2018-05-05 11:56 UTC (permalink / raw)
To: linux-arm-kernel
tree: https://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms.git irq/level-msi
head: 899ce68260999a53b26b3ba17836a080882e0e08
commit: 95d17381c804c678329b04e7967c4b3c94d44745 [5/13] genirq/msi: Allow level-triggered MSIs to be exposed by MSI providers
config: i386-randconfig-x013-201817 (attached as .config)
compiler: gcc-7 (Debian 7.3.0-16) 7.3.0
reproduce:
git checkout 95d17381c804c678329b04e7967c4b3c94d44745
# save the attached .config to linux build tree
make ARCH=i386
All errors (new ones prefixed by >>):
In file included from arch/x86/include/asm/bug.h:83:0,
from include/linux/bug.h:5,
from include/linux/debug_locks.h:7,
from include/linux/lockdep.h:28,
from include/linux/spinlock_types.h:18,
from include/linux/mutex.h:16,
from include/linux/kernfs.h:13,
from include/linux/sysfs.h:16,
from include/linux/kobject.h:20,
from include/linux/device.h:16,
from kernel//irq/msi.c:12:
kernel//irq/msi.c: In function 'msi_check_level':
>> kernel//irq/msi.c:88:12: error: 'struct irq_domain' has no member named 'chip'
(domain->chip->flags & IRQCHIP_SUPPORTS_LEVEL_MSI)) &&
^
include/asm-generic/bug.h:112:25: note: in definition of macro 'WARN_ON'
int __ret_warn_on = !!(condition); \
^~~~~~~~~
kernel//irq/msi.c:88:28: error: 'IRQCHIP_SUPPORTS_LEVEL_MSI' undeclared (first use in this function); did you mean 'IRQCHIP_STATE_LINE_LEVEL'?
(domain->chip->flags & IRQCHIP_SUPPORTS_LEVEL_MSI)) &&
^
include/asm-generic/bug.h:112:25: note: in definition of macro 'WARN_ON'
int __ret_warn_on = !!(condition); \
^~~~~~~~~
kernel//irq/msi.c:88:28: note: each undeclared identifier is reported only once for each function it appears in
(domain->chip->flags & IRQCHIP_SUPPORTS_LEVEL_MSI)) &&
^
include/asm-generic/bug.h:112:25: note: in definition of macro 'WARN_ON'
int __ret_warn_on = !!(condition); \
^~~~~~~~~
vim +88 kernel//irq/msi.c
> 12 #include <linux/device.h>
13 #include <linux/irq.h>
14 #include <linux/irqdomain.h>
15 #include <linux/msi.h>
16 #include <linux/slab.h>
17
18 #include "internals.h"
19
20 /**
21 * alloc_msi_entry - Allocate an initialize msi_entry
22 * @dev: Pointer to the device for which this is allocated
23 * @nvec: The number of vectors used in this entry
24 * @affinity: Optional pointer to an affinity mask array size of @nvec
25 *
26 * If @affinity is not NULL then a an affinity array[@nvec] is allocated
27 * and the affinity masks from @affinity are copied.
28 */
29 struct msi_desc *
30 alloc_msi_entry(struct device *dev, int nvec, const struct cpumask *affinity)
31 {
32 struct msi_desc *desc;
33
34 desc = kzalloc(sizeof(*desc), GFP_KERNEL);
35 if (!desc)
36 return NULL;
37
38 INIT_LIST_HEAD(&desc->list);
39 desc->dev = dev;
40 desc->nvec_used = nvec;
41 if (affinity) {
42 desc->affinity = kmemdup(affinity,
43 nvec * sizeof(*desc->affinity), GFP_KERNEL);
44 if (!desc->affinity) {
45 kfree(desc);
46 return NULL;
47 }
48 }
49
50 return desc;
51 }
52
53 void free_msi_entry(struct msi_desc *entry)
54 {
55 kfree(entry->affinity);
56 kfree(entry);
57 }
58
59 void __get_cached_msi_msg(struct msi_desc *entry, struct msi_msg *msg)
60 {
61 *msg = entry->msg;
62 }
63
64 void get_cached_msi_msg(unsigned int irq, struct msi_msg *msg)
65 {
66 struct msi_desc *entry = irq_get_msi_desc(irq);
67
68 __get_cached_msi_msg(entry, msg);
69 }
70 EXPORT_SYMBOL_GPL(get_cached_msi_msg);
71
72 #ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN
73 static inline void irq_chip_write_msi_msg(struct irq_data *data,
74 struct msi_msg *msg)
75 {
76 data->chip->irq_write_msi_msg(data, msg);
77 }
78
79 static void msi_check_level(struct irq_domain *domain, struct msi_msg *msg)
80 {
81 struct msi_domain_info *info = domain->host_data;
82
83 /*
84 * If the MSI provider has messed with the second message and
85 * not advertized that it is level-capable, signal the breakage.
86 */
87 WARN_ON(!((info->flags & MSI_FLAG_LEVEL_CAPABLE) &&
> 88 (domain->chip->flags & IRQCHIP_SUPPORTS_LEVEL_MSI)) &&
89 (msg[1].address_lo || msg[1].address_hi || msg[1].data));
90 }
91
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
-------------- next part --------------
A non-text attachment was scrubbed...
Name: .config.gz
Type: application/gzip
Size: 27761 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20180505/64d1e552/attachment-0001.gz>
^ permalink raw reply
* [PATCH V6 4/7] ARM: dts: imx6sx-sabreauto: add fec support
From: Fabio Estevam @ 2018-05-05 12:10 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1525508963-7986-4-git-send-email-Anson.Huang@nxp.com>
On Sat, May 5, 2018 at 5:29 AM, Anson Huang <Anson.Huang@nxp.com> wrote:
> Add FEC support on i.MX6SX Sabre Auto board.
>
> Signed-off-by: Fugang Duan <fugang.duan@nxp.com>
Again, it is not clear who is the author here. Is it Fugang or yourself?
> Signed-off-by: Anson Huang <Anson.Huang@nxp.com>
> ---
> changes since V5:
> use "gpios" instead of "enable-gpio".
> arch/arm/boot/dts/imx6sx-sabreauto.dts | 80 ++++++++++++++++++++++++++++++++++
> 1 file changed, 80 insertions(+)
>
> diff --git a/arch/arm/boot/dts/imx6sx-sabreauto.dts b/arch/arm/boot/dts/imx6sx-sabreauto.dts
> index 4d41b4d..7dda741 100644
> --- a/arch/arm/boot/dts/imx6sx-sabreauto.dts
> +++ b/arch/arm/boot/dts/imx6sx-sabreauto.dts
> @@ -18,6 +18,17 @@
> reg = <0x80000000 0x80000000>;
> };
>
> + reg_fec: fec_io_supply {
> + compatible = "regulator-gpio";
> + regulator-name = "1.8V_1.5V_FEC";
> + regulator-min-microvolt = <1500000>;
> + regulator-max-microvolt = <1800000>;
> + states = <1500000 0x0 1800000 0x1>;
> + gpios = <&max7322 0 GPIO_ACTIVE_HIGH>;
> + vin-supply = <&sw2_reg>;
> + enable-active-high;
> + };
I still find this confusing.
There is no consumer for reg_fec in, so it seems you are relying on
the fact that the kernel regulator core will disable reg_fec to put
the regulator in the state you require.
^ permalink raw reply
* [PATCH v3 07/12] ACPI / APEI: Make the nmi_fixmap_idx per-ghes to allow multiple in_nmi() users
From: Borislav Petkov @ 2018-05-05 12:27 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180427153510.5799-8-james.morse@arm.com>
On Fri, Apr 27, 2018 at 04:35:05PM +0100, James Morse wrote:
> Arm64 has multiple NMI-like notifications, but ghes.c only has one
> in_nmi() path, risking deadlock if one NMI-like notification can
> interrupt another.
>
> To support this we need a fixmap entry and lock for each notification
> type. But ghes_probe() attempts to process each struct ghes at probe
> time, to ensure any error that was notified before ghes_probe() was
> called has been done, and the buffer released (and maybe acknowledge
> to firmware) so that future errors can be delivered.
>
> This means NMI-like notifications need two fixmap entries and locks,
> one for the ghes_probe() time call, and another for the actual NMI
> that could interrupt ghes_probe().
>
> Split this single path up by adding an NMI fixmap idx and lock into
> the struct ghes. Any notification that can be called as an NMI can
> use these to separate its resources from any other notification it
> may interrupt.
>
> The majority of notifications occur in IRQ context, so unless its
> called in_nmi(), ghes_copy_tofrom_phys() will use the FIX_APEI_GHES_IRQ
> fixmap entry and the ghes_fixmap_lock_irq lock. This allows
> NMI-notifications to be processed by ghes_probe(), and then taken
> as an NMI.
>
> The double-underscore version of fix_to_virt() is used because the index
> to be mapped can't be tested against the end of the enum at compile
> time.
>
> Signed-off-by: James Morse <james.morse@arm.com>
>
> ---
> Changes since v1:
> * Fixed for ghes_proc() always calling every notification in process context.
> Now only NMI-like notifications need an additional fixmap-slot/lock.
...
> @@ -986,6 +960,8 @@ int ghes_notify_sea(void)
>
> static void ghes_sea_add(struct ghes *ghes)
> {
> + ghes->nmi_fixmap_lock = &ghes_fixmap_lock_nmi;
> + ghes->nmi_fixmap_idx = FIX_APEI_GHES_NMI;
> ghes_estatus_queue_grow_pool(ghes);
>
> mutex_lock(&ghes_list_mutex);
> @@ -1032,6 +1008,8 @@ static int ghes_notify_nmi(unsigned int cmd, struct pt_regs *regs)
>
> static void ghes_nmi_add(struct ghes *ghes)
> {
> + ghes->nmi_fixmap_lock = &ghes_fixmap_lock_nmi;
Ewww, we're assigning the spinlock to a pointer which we'll take later?
Yuck.
Why?
Do I see it correctly that one can have ACPI_HEST_NOTIFY_SEA and
ACPI_HEST_NOTIFY_NMI coexist in parallel on a single system?
If not, you can use a single spinlock.
If yes, then I'd prefer to make it less ugly and do the notification
type check ghes_probe() does:
switch (generic->notify.type)
and take the respective spinlock in ghes_copy_tofrom_phys(). This way it
is a bit better than using a spinlock ptr.
Thx.
--
Regards/Gruss,
Boris.
Good mailing practices for 400: avoid top-posting and trim the reply.
^ permalink raw reply
* [arm-platforms:irq/level-msi 11/13] drivers/irqchip/irq-gic-v3-mbi.c:26:8: error: unknown type name 'mutex_t'
From: kbuild test robot @ 2018-05-05 12:55 UTC (permalink / raw)
To: linux-arm-kernel
tree: https://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms.git irq/level-msi
head: 899ce68260999a53b26b3ba17836a080882e0e08
commit: 37b3cc58b06bf28420f0bff0b20fddf21b9c6b01 [11/13] irqchip/gic-v3: Add support for Message Based Interrupts as an MSI controller
config: arm64-defconfig (attached as .config)
compiler: aarch64-linux-gnu-gcc (Debian 7.2.0-11) 7.2.0
reproduce:
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
git checkout 37b3cc58b06bf28420f0bff0b20fddf21b9c6b01
# save the attached .config to linux build tree
make.cross ARCH=arm64
All errors (new ones prefixed by >>):
>> drivers/irqchip/irq-gic-v3-mbi.c:26:8: error: unknown type name 'mutex_t'
static mutex_t mbi_lock;
^~~~~~~
drivers/irqchip/irq-gic-v3-mbi.c: In function 'mbi_free_msi':
>> drivers/irqchip/irq-gic-v3-mbi.c:77:13: error: passing argument 1 of 'mutex_lock' from incompatible pointer type [-Werror=incompatible-pointer-types]
mutex_lock(&mbi_lock);
^
In file included from include/linux/kernfs.h:13:0,
from include/linux/sysfs.h:16,
from include/linux/kobject.h:20,
from include/linux/device.h:16,
from include/linux/dma-mapping.h:7,
from include/linux/dma-iommu.h:24,
from drivers/irqchip/irq-gic-v3-mbi.c:9:
include/linux/mutex.h:181:13: note: expected 'struct mutex *' but argument is of type 'int *'
extern void mutex_lock(struct mutex *lock);
^~~~~~~~~~
>> drivers/irqchip/irq-gic-v3-mbi.c:80:15: error: passing argument 1 of 'mutex_unlock' from incompatible pointer type [-Werror=incompatible-pointer-types]
mutex_unlock(&mbi_lock);
^
In file included from include/linux/kernfs.h:13:0,
from include/linux/sysfs.h:16,
from include/linux/kobject.h:20,
from include/linux/device.h:16,
from include/linux/dma-mapping.h:7,
from include/linux/dma-iommu.h:24,
from drivers/irqchip/irq-gic-v3-mbi.c:9:
include/linux/mutex.h:200:13: note: expected 'struct mutex *' but argument is of type 'int *'
extern void mutex_unlock(struct mutex *lock);
^~~~~~~~~~~~
drivers/irqchip/irq-gic-v3-mbi.c: In function 'mbi_irq_domain_alloc':
drivers/irqchip/irq-gic-v3-mbi.c:89:13: error: passing argument 1 of 'mutex_lock' from incompatible pointer type [-Werror=incompatible-pointer-types]
mutex_lock(&mbi_lock);
^
In file included from include/linux/kernfs.h:13:0,
from include/linux/sysfs.h:16,
from include/linux/kobject.h:20,
from include/linux/device.h:16,
from include/linux/dma-mapping.h:7,
from include/linux/dma-iommu.h:24,
from drivers/irqchip/irq-gic-v3-mbi.c:9:
include/linux/mutex.h:181:13: note: expected 'struct mutex *' but argument is of type 'int *'
extern void mutex_lock(struct mutex *lock);
^~~~~~~~~~
drivers/irqchip/irq-gic-v3-mbi.c:99:15: error: passing argument 1 of 'mutex_unlock' from incompatible pointer type [-Werror=incompatible-pointer-types]
mutex_unlock(&mbi_lock);
^
In file included from include/linux/kernfs.h:13:0,
from include/linux/sysfs.h:16,
from include/linux/kobject.h:20,
from include/linux/device.h:16,
from include/linux/dma-mapping.h:7,
from include/linux/dma-iommu.h:24,
from drivers/irqchip/irq-gic-v3-mbi.c:9:
include/linux/mutex.h:200:13: note: expected 'struct mutex *' but argument is of type 'int *'
extern void mutex_unlock(struct mutex *lock);
^~~~~~~~~~~~
cc1: some warnings being treated as errors
vim +/mutex_t +26 drivers/irqchip/irq-gic-v3-mbi.c
8
> 9 #include <linux/dma-iommu.h>
10 #include <linux/irq.h>
11 #include <linux/irqdomain.h>
12 #include <linux/kernel.h>
13 #include <linux/msi.h>
14 #include <linux/of_address.h>
15 #include <linux/slab.h>
16 #include <linux/spinlock.h>
17
18 #include <linux/irqchip/arm-gic-v3.h>
19
20 struct mbi_range {
21 u32 spi_start;
22 u32 nr_spis;
23 unsigned long *bm;
24 };
25
> 26 static mutex_t mbi_lock;
27 static phys_addr_t mbi_phys_base;
28 static struct mbi_range *mbi_ranges;
29 static unsigned int mbi_range_nr;
30
31 static struct irq_chip mbi_irq_chip = {
32 .name = "MBI",
33 .irq_mask = irq_chip_mask_parent,
34 .irq_unmask = irq_chip_unmask_parent,
35 .irq_eoi = irq_chip_eoi_parent,
36 .irq_set_type = irq_chip_set_type_parent,
37 .irq_set_affinity = irq_chip_set_affinity_parent,
38 };
39
40 static int mbi_irq_gic_domain_alloc(struct irq_domain *domain,
41 unsigned int virq,
42 irq_hw_number_t hwirq)
43 {
44 struct irq_fwspec fwspec;
45 struct irq_data *d;
46 int err;
47
48 /*
49 * Using ACPI? There is no MBI support in the spec, you
50 * shouldn't even be here.
51 */
52 if (!is_of_node(domain->parent->fwnode))
53 return -EINVAL;
54
55 /*
56 * Let's default to edge. This is consistent with traditional
57 * MSIs, and systems requiring level signaling will just
58 * enforce the trigger on their own.
59 */
60 fwspec.fwnode = domain->parent->fwnode;
61 fwspec.param_count = 3;
62 fwspec.param[0] = 0;
63 fwspec.param[1] = hwirq - 32;
64 fwspec.param[2] = IRQ_TYPE_EDGE_RISING;
65
66 err = irq_domain_alloc_irqs_parent(domain, virq, 1, &fwspec);
67 if (err)
68 return err;
69
70 d = irq_domain_get_irq_data(domain->parent, virq);
71 return d->chip->irq_set_type(d, IRQ_TYPE_EDGE_RISING);
72 }
73
74 static void mbi_free_msi(struct mbi_range *mbi, unsigned int hwirq,
75 int nr_irqs)
76 {
> 77 mutex_lock(&mbi_lock);
78 bitmap_release_region(mbi->bm, hwirq - mbi->spi_start,
79 get_count_order(nr_irqs));
> 80 mutex_unlock(&mbi_lock);
81 }
82
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
-------------- next part --------------
A non-text attachment was scrubbed...
Name: .config.gz
Type: application/gzip
Size: 38203 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20180505/e7fd47e4/attachment-0001.gz>
^ permalink raw reply
* [RFC PATCH 0/3] serial: uartps: Add run time support for more IPs than hardcoded 2
From: Maarten Brock @ 2018-05-05 13:10 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <cover.1524751696.git.michal.simek@xilinx.com>
On 2018-04-26 16:08, Michal Simek wrote:
> Hi,
>
> this series is trying to address discussion I had with Alan in past
> https://patchwork.kernel.org/patch/9738445/.
>
> It is moving uart_register_driver() to probe function like it is done
> in
> pl011 driver.
> And also introducing new function for alias compatibility checking to
> resolve cases where some IPs have alias and some of them not.
> This case is detected in pl011_probe_dt_alias() but not properly
> solved.
>
> Also keep status of free ids/minor numbers in bitmap to know what's the
> next unallocated number.
>
> The same solution can be used in pl011, uart16550 and uartlite to
> really
> get unified kernel.
>
> Tested on these use cases:
> Notes:
> ff000000 is the first PS uart listed in dtsi
> ff010000 is the second PS uart listed in dtsi
>
> Standard zcu102 setting
> serial0 = &uart0;
> serial1 = &uart1;
> [ 0.196628] ff000000.serial: ttyPS0 at MMIO 0xff000000 (irq = 33,
> base_baud = 6250000) is a xuartps
> [ 0.642542] ff010000.serial: ttyPS1 at MMIO 0xff010000 (irq = 34,
> base_baud = 6250000) is a xuartps
>
> Swapped zcu102 setting
> serial0 = &uart1;
> serial1 = &uart0;
> [ 0.196472] ff000000.serial: ttyPS1 at MMIO 0xff000000 (irq = 33,
> base_baud = 6250000) is a xuartps
> [ 0.196824] ff010000.serial: ttyPS0 at MMIO 0xff010000 (irq = 34,
> base_baud = 6250000) is a xuartps
>
> uart0 on alias higher then MAX uart ports
> serial0 = &uart1;
> serial200 = &uart0;
> [ 0.176793] ff000000.serial: ttyPS200 at MMIO 0xff000000 (irq = 33,
> base_baud = 6250000) is a xuartps
> [ 0.177288] ff010000.serial: ttyPS0 at MMIO 0xff010000 (irq = 34,
> base_baud = 6250000) is a xuartps
>
> Both uarts on higher aliases
> serial1 = &uart1;
> serial2 = &uart0;
> [ 0.196470] ff000000.serial: ttyPS2 at MMIO 0xff000000 (irq = 33,
> base_baud = 6250000) is a xuartps
> [ 0.196823] ff010000.serial: ttyPS1 at MMIO 0xff010000 (irq = 34,
> base_baud = 6250000) is a xuartps
>
> uart0 not listed but it is probed first that's why should be ttyPS0 but
> there is uart1 via alias
> serial0 = &uart1;
> [ 0.176656] xuartps ff000000.serial: No serial alias passed. Using
> the first free id
> [ 0.176671] xuartps ff000000.serial: Validate id 0
> [ 0.176680] xuartps ff000000.serial: The empty id is 0
> [ 0.176692] xuartps ff000000.serial: ID 0 already taken - skipped
> [ 0.176701] xuartps ff000000.serial: Validate id 1
> [ 0.176710] xuartps ff000000.serial: The empty id is 1
> [ 0.176719] xuartps ff000000.serial: Selected ID 1 allocation passed
> [ 0.176760] ff000000.serial: ttyPS1 at MMIO 0xff000000 (irq = 33,
> base_baud = 6250000) is a xuartps
> [ 0.177104] ff010000.serial: ttyPS0 at MMIO 0xff010000 (irq = 34,
> base_baud = 6250000) is a xuartps
>
> uart0 not listed but it is probed first that's why should be ttyPS0
> serial1 = &uart1;
> [ 0.176661] xuartps ff000000.serial: No serial alias passed. Using
> the first free id
> [ 0.176676] xuartps ff000000.serial: Validate id 0
> [ 0.176686] xuartps ff000000.serial: The empty id is 0
> [ 0.176696] xuartps ff000000.serial: Selected ID 0 allocation passed
> [ 0.176737] ff000000.serial: ttyPS0 at MMIO 0xff000000 (irq = 33,
> base_baud = 6250000) is a xuartps
> [ 0.177069] ff010000.serial: ttyPS1 at MMIO 0xff010000 (irq = 34,
> base_baud = 6250000) is a xuartps
>
> uarts not listed in aliases list
> [ 0.176673] xuartps ff000000.serial: No serial alias passed. Using
> the first free id
> [ 0.176687] xuartps ff000000.serial: Validate id 0
> [ 0.176697] xuartps ff000000.serial: The empty id is 0
> [ 0.176707] xuartps ff000000.serial: Selected ID 0 allocation passed
> [ 0.176746] ff000000.serial: ttyPS0 at MMIO 0xff000000 (irq = 33,
> base_baud = 6250000) is a xuartps
> [ 0.177057] xuartps ff010000.serial: No serial alias passed. Using
> the first free id
> [ 0.177070] xuartps ff010000.serial: Validate id 0
> [ 0.177079] xuartps ff010000.serial: The empty id is 0
> [ 0.177089] xuartps ff010000.serial: Selected ID 0 allocation failed
> [ 0.177098] xuartps ff010000.serial: Validate id 1
> [ 0.177107] xuartps ff010000.serial: The empty id is 1
> [ 0.177116] xuartps ff010000.serial: Selected ID 1 allocation passed
> [ 0.177149] ff010000.serial: ttyPS1 at MMIO 0xff010000 (irq = 34,
> base_baud = 6250000) is a xuartps
>
> Thanks,
> Michal
Hello Michal,
How will this interact with ns16550 based UARTs?
Can we have both /dev/ttyS0 and /dev/ttyPS0?
Currently we can't unless we create *no* serialN alias for the ns16550.
And there is no other means to lock the /dev/ttySx name to a device
either.
Or will the xuartps driver eventually use /dev/ttySx as well?
Maarten
^ permalink raw reply
* [PATCH 1/7] i2c: i2c-gpio: move header to platform_data
From: Mauro Carvalho Chehab @ 2018-05-05 13:26 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180419200015.15095-2-wsa@the-dreams.de>
Em Thu, 19 Apr 2018 22:00:07 +0200
Wolfram Sang <wsa@the-dreams.de> escreveu:
> This header only contains platform_data. Move it to the proper directory.
>
> Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
> ---
> MAINTAINERS | 2 +-
> arch/arm/mach-ks8695/board-acs5k.c | 2 +-
> arch/arm/mach-omap1/board-htcherald.c | 2 +-
> arch/arm/mach-pxa/palmz72.c | 2 +-
> arch/arm/mach-pxa/viper.c | 2 +-
> arch/arm/mach-sa1100/simpad.c | 2 +-
> arch/mips/alchemy/board-gpr.c | 2 +-
> drivers/i2c/busses/i2c-gpio.c | 2 +-
> drivers/media/platform/marvell-ccic/mmp-driver.c | 2 +-
Acked-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
> drivers/mfd/sm501.c | 2 +-
> include/linux/{ => platform_data}/i2c-gpio.h | 0
> 11 files changed, 10 insertions(+), 10 deletions(-)
> rename include/linux/{ => platform_data}/i2c-gpio.h (100%)
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 0a1410d5a621..7aad64b62102 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -5872,7 +5872,7 @@ GENERIC GPIO I2C DRIVER
> M: Haavard Skinnemoen <hskinnemoen@gmail.com>
> S: Supported
> F: drivers/i2c/busses/i2c-gpio.c
> -F: include/linux/i2c-gpio.h
> +F: include/linux/platform_data/i2c-gpio.h
>
> GENERIC GPIO I2C MULTIPLEXER DRIVER
> M: Peter Korsgaard <peter.korsgaard@barco.com>
> diff --git a/arch/arm/mach-ks8695/board-acs5k.c b/arch/arm/mach-ks8695/board-acs5k.c
> index 937eb1d47e7b..ef835d82cdb9 100644
> --- a/arch/arm/mach-ks8695/board-acs5k.c
> +++ b/arch/arm/mach-ks8695/board-acs5k.c
> @@ -19,7 +19,7 @@
> #include <linux/gpio/machine.h>
> #include <linux/i2c.h>
> #include <linux/i2c-algo-bit.h>
> -#include <linux/i2c-gpio.h>
> +#include <linux/platform_data/i2c-gpio.h>
> #include <linux/platform_data/pca953x.h>
>
> #include <linux/mtd/mtd.h>
> diff --git a/arch/arm/mach-omap1/board-htcherald.c b/arch/arm/mach-omap1/board-htcherald.c
> index 67d46690a56e..da8f3fc3180f 100644
> --- a/arch/arm/mach-omap1/board-htcherald.c
> +++ b/arch/arm/mach-omap1/board-htcherald.c
> @@ -31,7 +31,7 @@
> #include <linux/gpio.h>
> #include <linux/gpio_keys.h>
> #include <linux/i2c.h>
> -#include <linux/i2c-gpio.h>
> +#include <linux/platform_data/i2c-gpio.h>
> #include <linux/htcpld.h>
> #include <linux/leds.h>
> #include <linux/spi/spi.h>
> diff --git a/arch/arm/mach-pxa/palmz72.c b/arch/arm/mach-pxa/palmz72.c
> index 5877e547cecd..c053c8ce1586 100644
> --- a/arch/arm/mach-pxa/palmz72.c
> +++ b/arch/arm/mach-pxa/palmz72.c
> @@ -30,7 +30,7 @@
> #include <linux/wm97xx.h>
> #include <linux/power_supply.h>
> #include <linux/usb/gpio_vbus.h>
> -#include <linux/i2c-gpio.h>
> +#include <linux/platform_data/i2c-gpio.h>
> #include <linux/gpio/machine.h>
>
> #include <asm/mach-types.h>
> diff --git a/arch/arm/mach-pxa/viper.c b/arch/arm/mach-pxa/viper.c
> index 90d0f277de55..39e05b7008d8 100644
> --- a/arch/arm/mach-pxa/viper.c
> +++ b/arch/arm/mach-pxa/viper.c
> @@ -35,7 +35,7 @@
> #include <linux/sched.h>
> #include <linux/gpio.h>
> #include <linux/jiffies.h>
> -#include <linux/i2c-gpio.h>
> +#include <linux/platform_data/i2c-gpio.h>
> #include <linux/gpio/machine.h>
> #include <linux/platform_data/i2c-pxa.h>
> #include <linux/serial_8250.h>
> diff --git a/arch/arm/mach-sa1100/simpad.c b/arch/arm/mach-sa1100/simpad.c
> index ace010479eb6..49a61e6f3c5f 100644
> --- a/arch/arm/mach-sa1100/simpad.c
> +++ b/arch/arm/mach-sa1100/simpad.c
> @@ -37,7 +37,7 @@
> #include <linux/input.h>
> #include <linux/gpio_keys.h>
> #include <linux/leds.h>
> -#include <linux/i2c-gpio.h>
> +#include <linux/platform_data/i2c-gpio.h>
>
> #include "generic.h"
>
> diff --git a/arch/mips/alchemy/board-gpr.c b/arch/mips/alchemy/board-gpr.c
> index 4e79dbd54a33..fa75d75b5ba9 100644
> --- a/arch/mips/alchemy/board-gpr.c
> +++ b/arch/mips/alchemy/board-gpr.c
> @@ -29,7 +29,7 @@
> #include <linux/leds.h>
> #include <linux/gpio.h>
> #include <linux/i2c.h>
> -#include <linux/i2c-gpio.h>
> +#include <linux/platform_data/i2c-gpio.h>
> #include <linux/gpio/machine.h>
> #include <asm/bootinfo.h>
> #include <asm/idle.h>
> diff --git a/drivers/i2c/busses/i2c-gpio.c b/drivers/i2c/busses/i2c-gpio.c
> index 58abb3eced58..005e6e0330c2 100644
> --- a/drivers/i2c/busses/i2c-gpio.c
> +++ b/drivers/i2c/busses/i2c-gpio.c
> @@ -11,7 +11,7 @@
> #include <linux/delay.h>
> #include <linux/i2c.h>
> #include <linux/i2c-algo-bit.h>
> -#include <linux/i2c-gpio.h>
> +#include <linux/platform_data/i2c-gpio.h>
> #include <linux/init.h>
> #include <linux/module.h>
> #include <linux/slab.h>
> diff --git a/drivers/media/platform/marvell-ccic/mmp-driver.c b/drivers/media/platform/marvell-ccic/mmp-driver.c
> index 816f4b6a7b8e..d9f0dd0d3525 100644
> --- a/drivers/media/platform/marvell-ccic/mmp-driver.c
> +++ b/drivers/media/platform/marvell-ccic/mmp-driver.c
> @@ -12,7 +12,7 @@
> #include <linux/kernel.h>
> #include <linux/module.h>
> #include <linux/i2c.h>
> -#include <linux/i2c-gpio.h>
> +#include <linux/platform_data/i2c-gpio.h>
> #include <linux/interrupt.h>
> #include <linux/spinlock.h>
> #include <linux/slab.h>
> diff --git a/drivers/mfd/sm501.c b/drivers/mfd/sm501.c
> index ad774161a22d..66af659b01b2 100644
> --- a/drivers/mfd/sm501.c
> +++ b/drivers/mfd/sm501.c
> @@ -19,7 +19,7 @@
> #include <linux/device.h>
> #include <linux/platform_device.h>
> #include <linux/pci.h>
> -#include <linux/i2c-gpio.h>
> +#include <linux/platform_data/i2c-gpio.h>
> #include <linux/gpio/machine.h>
> #include <linux/slab.h>
>
> diff --git a/include/linux/i2c-gpio.h b/include/linux/platform_data/i2c-gpio.h
> similarity index 100%
> rename from include/linux/i2c-gpio.h
> rename to include/linux/platform_data/i2c-gpio.h
Thanks,
Mauro
^ permalink raw reply
* [PATCH] locking/atomics/powerpc: Move cmpxchg helpers to asm/cmpxchg.h and define the full set of cmpxchg APIs
From: Ingo Molnar @ 2018-05-05 13:27 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180505112817.ihrb726i37bwm4cj@tardis>
* Boqun Feng <boqun.feng@gmail.com> wrote:
> > May I suggest the patch below? No change in functionality, but it documents the
> > lack of the cmpxchg_release() APIs and maps them explicitly to the full cmpxchg()
> > version. (Which the generic code does now in a rather roundabout way.)
> >
>
> Hmm.. cmpxchg_release() is actually lwsync() + cmpxchg_relaxed(), but
> you just make it sync() + cmpxchg_relaxed() + sync() with the fallback,
> and sync() is much heavier, so I don't think the fallback is correct.
Indeed!
The bit I missed previously is that PowerPC provides its own __atomic_op_release()
method:
#define __atomic_op_release(op, args...) \
({ \
__asm__ __volatile__(PPC_RELEASE_BARRIER "" : : : "memory"); \
op##_relaxed(args); \
})
... which maps to LWSYNC as you say, and my patch made that worse.
> I think maybe you can move powerpc's __atomic_op_{acqurie,release}()
> from atomic.h to cmpxchg.h (in arch/powerpc/include/asm), and
>
> #define cmpxchg_release __atomic_op_release(cmpxchg, __VA_ARGS__);
> #define cmpxchg64_release __atomic_op_release(cmpxchg64, __VA_ARGS__);
>
> I put a diff below to say what I mean (untested).
>
> > Also, the change to arch/powerpc/include/asm/atomic.h has no functional effect
> > right now either, but should anyone add a _relaxed() variant in the future, with
> > this change atomic_cmpxchg_release() and atomic64_cmpxchg_release() will pick that
> > up automatically.
> >
>
> You mean with your other modification in include/linux/atomic.h, right?
> Because with the unmodified include/linux/atomic.h, we already pick that
> autmatically. If so, I think that's fine.
>
> Here is the diff for the modification for cmpxchg_release(), the idea is
> we generate them in asm/cmpxchg.h other than linux/atomic.h for ppc, so
> we keep the new linux/atomic.h working. Because if I understand
> correctly, the next linux/atomic.h only accepts that
>
> 1) architecture only defines fully ordered primitives
>
> or
>
> 2) architecture only defines _relaxed primitives
>
> or
>
> 3) architecture defines all four (fully, _relaxed, _acquire,
> _release) primitives
>
> So powerpc needs to define all four primitives in its only
> asm/cmpxchg.h.
Correct, although the new logic is still RFC, PeterZ didn't like the first version
I proposed and might NAK them.
Thanks for the patch - I have created the patch below from it and added your
Signed-off-by.
The only change I made beyond a trivial build fix is that I also added the release
atomics variants explicitly:
+#define atomic_cmpxchg_release(v, o, n) \
+ cmpxchg_release(&((v)->counter), (o), (n))
+#define atomic64_cmpxchg_release(v, o, n) \
+ cmpxchg_release(&((v)->counter), (o), (n))
It has passed a PowerPC cross-build test here, but no runtime tests.
Does this patch look good to you?
(Still subject to PeterZ's Ack/NAK.)
Thanks,
Ingo
======================>
From: Boqun Feng <boqun.feng@gmail.com>
Date: Sat, 5 May 2018 19:28:17 +0800
Subject: [PATCH] locking/atomics/powerpc: Move cmpxchg helpers to asm/cmpxchg.h and define the full set of cmpxchg APIs
Move PowerPC's __op_{acqurie,release}() from atomic.h to
cmpxchg.h (in arch/powerpc/include/asm), plus use them to
define these two methods:
#define cmpxchg_release __op_release(cmpxchg, __VA_ARGS__);
#define cmpxchg64_release __op_release(cmpxchg64, __VA_ARGS__);
... the idea is to generate all these methods in cmpxchg.h and to define the full
array of atomic primitives, including the cmpxchg_release() methods which were
defined by the generic code before.
Also define the atomic[64]_() variants explicitly.
This ensures that all these low level cmpxchg APIs are defined in
PowerPC headers, with no generic header fallbacks.
No change in functionality or code generation.
Signed-off-by: Boqun Feng <boqun.feng@gmail.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: aryabinin at virtuozzo.com
Cc: catalin.marinas at arm.com
Cc: dvyukov at google.com
Cc: linux-arm-kernel at lists.infradead.org
Cc: will.deacon at arm.com
Link: http://lkml.kernel.org/r/20180505112817.ihrb726i37bwm4cj at tardis
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
arch/powerpc/include/asm/atomic.h | 22 ++++------------------
arch/powerpc/include/asm/cmpxchg.h | 24 ++++++++++++++++++++++++
2 files changed, 28 insertions(+), 18 deletions(-)
diff --git a/arch/powerpc/include/asm/atomic.h b/arch/powerpc/include/asm/atomic.h
index 682b3e6a1e21..4e06955ec10f 100644
--- a/arch/powerpc/include/asm/atomic.h
+++ b/arch/powerpc/include/asm/atomic.h
@@ -13,24 +13,6 @@
#define ATOMIC_INIT(i) { (i) }
-/*
- * Since *_return_relaxed and {cmp}xchg_relaxed are implemented with
- * a "bne-" instruction at the end, so an isync is enough as a acquire barrier
- * on the platform without lwsync.
- */
-#define __atomic_op_acquire(op, args...) \
-({ \
- typeof(op##_relaxed(args)) __ret = op##_relaxed(args); \
- __asm__ __volatile__(PPC_ACQUIRE_BARRIER "" : : : "memory"); \
- __ret; \
-})
-
-#define __atomic_op_release(op, args...) \
-({ \
- __asm__ __volatile__(PPC_RELEASE_BARRIER "" : : : "memory"); \
- op##_relaxed(args); \
-})
-
static __inline__ int atomic_read(const atomic_t *v)
{
int t;
@@ -213,6 +195,8 @@ static __inline__ int atomic_dec_return_relaxed(atomic_t *v)
cmpxchg_relaxed(&((v)->counter), (o), (n))
#define atomic_cmpxchg_acquire(v, o, n) \
cmpxchg_acquire(&((v)->counter), (o), (n))
+#define atomic_cmpxchg_release(v, o, n) \
+ cmpxchg_release(&((v)->counter), (o), (n))
#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
#define atomic_xchg_relaxed(v, new) xchg_relaxed(&((v)->counter), (new))
@@ -519,6 +503,8 @@ static __inline__ long atomic64_dec_if_positive(atomic64_t *v)
cmpxchg_relaxed(&((v)->counter), (o), (n))
#define atomic64_cmpxchg_acquire(v, o, n) \
cmpxchg_acquire(&((v)->counter), (o), (n))
+#define atomic64_cmpxchg_release(v, o, n) \
+ cmpxchg_release(&((v)->counter), (o), (n))
#define atomic64_xchg(v, new) (xchg(&((v)->counter), new))
#define atomic64_xchg_relaxed(v, new) xchg_relaxed(&((v)->counter), (new))
diff --git a/arch/powerpc/include/asm/cmpxchg.h b/arch/powerpc/include/asm/cmpxchg.h
index 9b001f1f6b32..e27a612b957f 100644
--- a/arch/powerpc/include/asm/cmpxchg.h
+++ b/arch/powerpc/include/asm/cmpxchg.h
@@ -8,6 +8,24 @@
#include <asm/asm-compat.h>
#include <linux/bug.h>
+/*
+ * Since *_return_relaxed and {cmp}xchg_relaxed are implemented with
+ * a "bne-" instruction at the end, so an isync is enough as a acquire barrier
+ * on the platform without lwsync.
+ */
+#define __atomic_op_acquire(op, args...) \
+({ \
+ typeof(op##_relaxed(args)) __ret = op##_relaxed(args); \
+ __asm__ __volatile__(PPC_ACQUIRE_BARRIER "" : : : "memory"); \
+ __ret; \
+})
+
+#define __atomic_op_release(op, args...) \
+({ \
+ __asm__ __volatile__(PPC_RELEASE_BARRIER "" : : : "memory"); \
+ op##_relaxed(args); \
+})
+
#ifdef __BIG_ENDIAN
#define BITOFF_CAL(size, off) ((sizeof(u32) - size - off) * BITS_PER_BYTE)
#else
@@ -512,6 +530,9 @@ __cmpxchg_acquire(void *ptr, unsigned long old, unsigned long new,
(unsigned long)_o_, (unsigned long)_n_, \
sizeof(*(ptr))); \
})
+
+#define cmpxchg_release(...) __atomic_op_release(cmpxchg, __VA_ARGS__)
+
#ifdef CONFIG_PPC64
#define cmpxchg64(ptr, o, n) \
({ \
@@ -533,6 +554,9 @@ __cmpxchg_acquire(void *ptr, unsigned long old, unsigned long new,
BUILD_BUG_ON(sizeof(*(ptr)) != 8); \
cmpxchg_acquire((ptr), (o), (n)); \
})
+
+#define cmpxchg64_release(...) __atomic_op_release(cmpxchg64, __VA_ARGS__)
+
#else
#include <asm-generic/cmpxchg-local.h>
#define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n))
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox