* [kvm-unit-tests PATCH v2 0/3] lib/on-cpus: A couple of fixes
@ 2024-10-31 12:39 Andrew Jones
2024-10-31 12:39 ` [kvm-unit-tests PATCH v2 1/3] lib/on-cpus: Correct and simplify synchronization Andrew Jones
` (3 more replies)
0 siblings, 4 replies; 10+ messages in thread
From: Andrew Jones @ 2024-10-31 12:39 UTC (permalink / raw)
To: kvm, kvm-riscv, kvmarm; +Cc: atishp, jamestiotio, alexandru.elisei, eric.auger
While creating riscv SBI HSM tests a couple strange on-cpus behaviors
were observed. Fix 'em.
v2:
- Added patch for barrier after func() [Alex]
- Improved commit message for patch1 [Alex]
Andrew Jones (3):
lib/on-cpus: Correct and simplify synchronization
lib/on-cpus: Add barrier after func call
lib/on-cpus: Fix on_cpumask
lib/cpumask.h | 14 +++++++++++++
lib/on-cpus.c | 56 ++++++++++++++++++++-------------------------------
2 files changed, 36 insertions(+), 34 deletions(-)
--
2.47.0
^ permalink raw reply [flat|nested] 10+ messages in thread
* [kvm-unit-tests PATCH v2 1/3] lib/on-cpus: Correct and simplify synchronization
2024-10-31 12:39 [kvm-unit-tests PATCH v2 0/3] lib/on-cpus: A couple of fixes Andrew Jones
@ 2024-10-31 12:39 ` Andrew Jones
2024-11-07 10:01 ` Eric Auger
2024-10-31 12:39 ` [kvm-unit-tests PATCH v2 2/3] lib/on-cpus: Add barrier after func call Andrew Jones
` (2 subsequent siblings)
3 siblings, 1 reply; 10+ messages in thread
From: Andrew Jones @ 2024-10-31 12:39 UTC (permalink / raw)
To: kvm, kvm-riscv, kvmarm; +Cc: atishp, jamestiotio, alexandru.elisei, eric.auger
get/put_on_cpu_info() were providing per-cpu locking for the per-cpu
on_cpu info, but it's difficult to reason that they're correct since
they use test_and_set/clear rather than a typical lock. Just revert
to a typical spinlock to simplify it. Also simplify the break case
for on_cpu_async() - we don't care if func is NULL, we only care
that the cpu is idle. And, finally, add a missing barrier to
on_cpu_async(). Before commit 018550041b38 ("arm/arm64: Remove
spinlocks from on_cpu_async") the spin_unlock() provided an implicit
barrier at the correct location, but moving the release to the more
logical location, below the setting of idle, lost it.
Fixes: 018550041b38 ("arm/arm64: Remove spinlocks from on_cpu_async")
Signed-off-by: Andrew Jones <andrew.jones@linux.dev>
---
lib/on-cpus.c | 36 +++++++++++-------------------------
1 file changed, 11 insertions(+), 25 deletions(-)
diff --git a/lib/on-cpus.c b/lib/on-cpus.c
index 892149338419..f6072117fa1b 100644
--- a/lib/on-cpus.c
+++ b/lib/on-cpus.c
@@ -9,6 +9,7 @@
#include <on-cpus.h>
#include <asm/barrier.h>
#include <asm/smp.h>
+#include <asm/spinlock.h>
bool cpu0_calls_idle;
@@ -18,18 +19,7 @@ struct on_cpu_info {
cpumask_t waiters;
};
static struct on_cpu_info on_cpu_info[NR_CPUS];
-static cpumask_t on_cpu_info_lock;
-
-static bool get_on_cpu_info(int cpu)
-{
- return !cpumask_test_and_set_cpu(cpu, &on_cpu_info_lock);
-}
-
-static void put_on_cpu_info(int cpu)
-{
- int ret = cpumask_test_and_clear_cpu(cpu, &on_cpu_info_lock);
- assert(ret);
-}
+static struct spinlock lock;
static void __deadlock_check(int cpu, const cpumask_t *waiters, bool *found)
{
@@ -81,18 +71,14 @@ void do_idle(void)
if (cpu == 0)
cpu0_calls_idle = true;
- set_cpu_idle(cpu, true);
- smp_send_event();
-
for (;;) {
+ set_cpu_idle(cpu, true);
+ smp_send_event();
+
while (cpu_idle(cpu))
smp_wait_for_event();
smp_rmb();
on_cpu_info[cpu].func(on_cpu_info[cpu].data);
- on_cpu_info[cpu].func = NULL;
- smp_wmb();
- set_cpu_idle(cpu, true);
- smp_send_event();
}
}
@@ -110,17 +96,17 @@ void on_cpu_async(int cpu, void (*func)(void *data), void *data)
for (;;) {
cpu_wait(cpu);
- if (get_on_cpu_info(cpu)) {
- if ((volatile void *)on_cpu_info[cpu].func == NULL)
- break;
- put_on_cpu_info(cpu);
- }
+ spin_lock(&lock);
+ if (cpu_idle(cpu))
+ break;
+ spin_unlock(&lock);
}
on_cpu_info[cpu].func = func;
on_cpu_info[cpu].data = data;
+ smp_wmb();
set_cpu_idle(cpu, false);
- put_on_cpu_info(cpu);
+ spin_unlock(&lock);
smp_send_event();
}
--
2.47.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [kvm-unit-tests PATCH v2 2/3] lib/on-cpus: Add barrier after func call
2024-10-31 12:39 [kvm-unit-tests PATCH v2 0/3] lib/on-cpus: A couple of fixes Andrew Jones
2024-10-31 12:39 ` [kvm-unit-tests PATCH v2 1/3] lib/on-cpus: Correct and simplify synchronization Andrew Jones
@ 2024-10-31 12:39 ` Andrew Jones
2024-11-06 8:15 ` Andrew Jones
2024-11-07 10:02 ` Eric Auger
2024-10-31 12:39 ` [kvm-unit-tests PATCH v2 3/3] lib/on-cpus: Fix on_cpumask Andrew Jones
2024-11-11 14:36 ` [kvm-unit-tests PATCH v2 0/3] lib/on-cpus: A couple of fixes Andrew Jones
3 siblings, 2 replies; 10+ messages in thread
From: Andrew Jones @ 2024-10-31 12:39 UTC (permalink / raw)
To: kvm, kvm-riscv, kvmarm; +Cc: atishp, jamestiotio, alexandru.elisei, eric.auger
It's reasonable for users of on_cpu() and on_cpumask() to assume
they can read data that 'func' has written when the call completes.
Ensure the caller doesn't observe a completion (target cpus are again
idle) without also being able to observe any writes which were made
by func(). Do so by adding barriers to implement the following
target-cpu calling-cpu
---------- -----------
func() /* store something */ /* wait for target to be idle */
smp_wmb(); smp_rmb();
set_cpu_idle(smp_processor_id(), true); /* load what func() stored */
Signed-off-by: Andrew Jones <andrew.jones@linux.dev>
---
lib/on-cpus.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/lib/on-cpus.c b/lib/on-cpus.c
index f6072117fa1b..356f284be61b 100644
--- a/lib/on-cpus.c
+++ b/lib/on-cpus.c
@@ -79,6 +79,7 @@ void do_idle(void)
smp_wait_for_event();
smp_rmb();
on_cpu_info[cpu].func(on_cpu_info[cpu].data);
+ smp_wmb(); /* pairs with the smp_rmb() in on_cpu() and on_cpumask() */
}
}
@@ -145,12 +146,14 @@ void on_cpumask(const cpumask_t *mask, void (*func)(void *data), void *data)
smp_wait_for_event();
for_each_cpu(cpu, mask)
cpumask_clear_cpu(me, &on_cpu_info[cpu].waiters);
+ smp_rmb(); /* pairs with the smp_wmb() in do_idle() */
}
void on_cpu(int cpu, void (*func)(void *data), void *data)
{
on_cpu_async(cpu, func, data);
cpu_wait(cpu);
+ smp_rmb(); /* pairs with the smp_wmb() in do_idle() */
}
void on_cpus(void (*func)(void *data), void *data)
--
2.47.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [kvm-unit-tests PATCH v2 3/3] lib/on-cpus: Fix on_cpumask
2024-10-31 12:39 [kvm-unit-tests PATCH v2 0/3] lib/on-cpus: A couple of fixes Andrew Jones
2024-10-31 12:39 ` [kvm-unit-tests PATCH v2 1/3] lib/on-cpus: Correct and simplify synchronization Andrew Jones
2024-10-31 12:39 ` [kvm-unit-tests PATCH v2 2/3] lib/on-cpus: Add barrier after func call Andrew Jones
@ 2024-10-31 12:39 ` Andrew Jones
2024-11-07 17:55 ` Eric Auger
2024-11-11 14:36 ` [kvm-unit-tests PATCH v2 0/3] lib/on-cpus: A couple of fixes Andrew Jones
3 siblings, 1 reply; 10+ messages in thread
From: Andrew Jones @ 2024-10-31 12:39 UTC (permalink / raw)
To: kvm, kvm-riscv, kvmarm; +Cc: atishp, jamestiotio, alexandru.elisei, eric.auger
on_cpumask should wait until the cpus in the mask, not including
the calling cpu, are idle. Checking the weight against nr_cpus
minus 1 only works when the mask is the same as the present mask.
Fixes: d012cfd5d309 ("lib/on-cpus: Introduce on_cpumask and on_cpumask_async")
Signed-off-by: Andrew Jones <andrew.jones@linux.dev>
---
lib/cpumask.h | 14 ++++++++++++++
lib/on-cpus.c | 17 ++++++++---------
2 files changed, 22 insertions(+), 9 deletions(-)
diff --git a/lib/cpumask.h b/lib/cpumask.h
index e1e92aacd1f1..37d360786573 100644
--- a/lib/cpumask.h
+++ b/lib/cpumask.h
@@ -58,6 +58,20 @@ static inline void cpumask_clear(cpumask_t *mask)
memset(mask, 0, sizeof(*mask));
}
+/* true if src1 is a subset of src2 */
+static inline bool cpumask_subset(const struct cpumask *src1, const struct cpumask *src2)
+{
+ unsigned long lastmask = BIT_MASK(nr_cpus) - 1;
+ int i;
+
+ for (i = 0; i < BIT_WORD(nr_cpus); ++i) {
+ if (cpumask_bits(src1)[i] & ~cpumask_bits(src2)[i])
+ return false;
+ }
+
+ return !lastmask || !((cpumask_bits(src1)[i] & ~cpumask_bits(src2)[i]) & lastmask);
+}
+
static inline bool cpumask_empty(const cpumask_t *mask)
{
unsigned long lastmask = BIT_MASK(nr_cpus) - 1;
diff --git a/lib/on-cpus.c b/lib/on-cpus.c
index 356f284be61b..889b6bc8a186 100644
--- a/lib/on-cpus.c
+++ b/lib/on-cpus.c
@@ -127,24 +127,23 @@ void on_cpumask_async(const cpumask_t *mask, void (*func)(void *data), void *dat
void on_cpumask(const cpumask_t *mask, void (*func)(void *data), void *data)
{
int cpu, me = smp_processor_id();
+ cpumask_t tmp;
- for_each_cpu(cpu, mask) {
- if (cpu == me)
- continue;
+ cpumask_copy(&tmp, mask);
+ cpumask_clear_cpu(me, &tmp);
+
+ for_each_cpu(cpu, &tmp)
on_cpu_async(cpu, func, data);
- }
if (cpumask_test_cpu(me, mask))
func(data);
- for_each_cpu(cpu, mask) {
- if (cpu == me)
- continue;
+ for_each_cpu(cpu, &tmp) {
cpumask_set_cpu(me, &on_cpu_info[cpu].waiters);
deadlock_check(me, cpu);
}
- while (cpumask_weight(&cpu_idle_mask) < nr_cpus - 1)
+ while (!cpumask_subset(&tmp, &cpu_idle_mask))
smp_wait_for_event();
- for_each_cpu(cpu, mask)
+ for_each_cpu(cpu, &tmp)
cpumask_clear_cpu(me, &on_cpu_info[cpu].waiters);
smp_rmb(); /* pairs with the smp_wmb() in do_idle() */
}
--
2.47.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [kvm-unit-tests PATCH v2 2/3] lib/on-cpus: Add barrier after func call
2024-10-31 12:39 ` [kvm-unit-tests PATCH v2 2/3] lib/on-cpus: Add barrier after func call Andrew Jones
@ 2024-11-06 8:15 ` Andrew Jones
2024-11-07 10:02 ` Eric Auger
1 sibling, 0 replies; 10+ messages in thread
From: Andrew Jones @ 2024-11-06 8:15 UTC (permalink / raw)
To: kvm, kvm-riscv, kvmarm; +Cc: atishp, jamestiotio, alexandru.elisei, eric.auger
On Thu, Oct 31, 2024 at 01:39:51PM +0100, Andrew Jones wrote:
> It's reasonable for users of on_cpu() and on_cpumask() to assume
> they can read data that 'func' has written when the call completes.
> Ensure the caller doesn't observe a completion (target cpus are again
> idle) without also being able to observe any writes which were made
> by func(). Do so by adding barriers to implement the following
>
> target-cpu calling-cpu
> ---------- -----------
> func() /* store something */ /* wait for target to be idle */
> smp_wmb(); smp_rmb();
> set_cpu_idle(smp_processor_id(), true); /* load what func() stored */
>
> Signed-off-by: Andrew Jones <andrew.jones@linux.dev>
I added a
Suggested-by: Alexandru Elisei <alexandru.elisei@arm.com>
to this patch.
> ---
> lib/on-cpus.c | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/lib/on-cpus.c b/lib/on-cpus.c
> index f6072117fa1b..356f284be61b 100644
> --- a/lib/on-cpus.c
> +++ b/lib/on-cpus.c
> @@ -79,6 +79,7 @@ void do_idle(void)
> smp_wait_for_event();
> smp_rmb();
> on_cpu_info[cpu].func(on_cpu_info[cpu].data);
> + smp_wmb(); /* pairs with the smp_rmb() in on_cpu() and on_cpumask() */
> }
> }
>
> @@ -145,12 +146,14 @@ void on_cpumask(const cpumask_t *mask, void (*func)(void *data), void *data)
> smp_wait_for_event();
> for_each_cpu(cpu, mask)
> cpumask_clear_cpu(me, &on_cpu_info[cpu].waiters);
> + smp_rmb(); /* pairs with the smp_wmb() in do_idle() */
> }
>
> void on_cpu(int cpu, void (*func)(void *data), void *data)
> {
> on_cpu_async(cpu, func, data);
> cpu_wait(cpu);
> + smp_rmb(); /* pairs with the smp_wmb() in do_idle() */
> }
>
> void on_cpus(void (*func)(void *data), void *data)
> --
> 2.47.0
>
>
> --
> kvm-riscv mailing list
> kvm-riscv@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/kvm-riscv
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [kvm-unit-tests PATCH v2 1/3] lib/on-cpus: Correct and simplify synchronization
2024-10-31 12:39 ` [kvm-unit-tests PATCH v2 1/3] lib/on-cpus: Correct and simplify synchronization Andrew Jones
@ 2024-11-07 10:01 ` Eric Auger
0 siblings, 0 replies; 10+ messages in thread
From: Eric Auger @ 2024-11-07 10:01 UTC (permalink / raw)
To: Andrew Jones, kvm, kvm-riscv, kvmarm
Cc: atishp, jamestiotio, alexandru.elisei
On 10/31/24 13:39, Andrew Jones wrote:
> get/put_on_cpu_info() were providing per-cpu locking for the per-cpu
> on_cpu info, but it's difficult to reason that they're correct since
> they use test_and_set/clear rather than a typical lock. Just revert
> to a typical spinlock to simplify it. Also simplify the break case
> for on_cpu_async() - we don't care if func is NULL, we only care
> that the cpu is idle. And, finally, add a missing barrier to
> on_cpu_async(). Before commit 018550041b38 ("arm/arm64: Remove
> spinlocks from on_cpu_async") the spin_unlock() provided an implicit
> barrier at the correct location, but moving the release to the more
> logical location, below the setting of idle, lost it.
>
> Fixes: 018550041b38 ("arm/arm64: Remove spinlocks from on_cpu_async")
> Signed-off-by: Andrew Jones <andrew.jones@linux.dev>
Reviewed-by: Eric Auger <eric.auger@redhat.com>
Eric
> ---
> lib/on-cpus.c | 36 +++++++++++-------------------------
> 1 file changed, 11 insertions(+), 25 deletions(-)
>
> diff --git a/lib/on-cpus.c b/lib/on-cpus.c
> index 892149338419..f6072117fa1b 100644
> --- a/lib/on-cpus.c
> +++ b/lib/on-cpus.c
> @@ -9,6 +9,7 @@
> #include <on-cpus.h>
> #include <asm/barrier.h>
> #include <asm/smp.h>
> +#include <asm/spinlock.h>
>
> bool cpu0_calls_idle;
>
> @@ -18,18 +19,7 @@ struct on_cpu_info {
> cpumask_t waiters;
> };
> static struct on_cpu_info on_cpu_info[NR_CPUS];
> -static cpumask_t on_cpu_info_lock;
> -
> -static bool get_on_cpu_info(int cpu)
> -{
> - return !cpumask_test_and_set_cpu(cpu, &on_cpu_info_lock);
> -}
> -
> -static void put_on_cpu_info(int cpu)
> -{
> - int ret = cpumask_test_and_clear_cpu(cpu, &on_cpu_info_lock);
> - assert(ret);
> -}
> +static struct spinlock lock;
>
> static void __deadlock_check(int cpu, const cpumask_t *waiters, bool *found)
> {
> @@ -81,18 +71,14 @@ void do_idle(void)
> if (cpu == 0)
> cpu0_calls_idle = true;
>
> - set_cpu_idle(cpu, true);
> - smp_send_event();
> -
> for (;;) {
> + set_cpu_idle(cpu, true);
> + smp_send_event();
> +
> while (cpu_idle(cpu))
> smp_wait_for_event();
> smp_rmb();
> on_cpu_info[cpu].func(on_cpu_info[cpu].data);
> - on_cpu_info[cpu].func = NULL;
> - smp_wmb();
> - set_cpu_idle(cpu, true);
> - smp_send_event();
> }
> }
>
> @@ -110,17 +96,17 @@ void on_cpu_async(int cpu, void (*func)(void *data), void *data)
>
> for (;;) {
> cpu_wait(cpu);
> - if (get_on_cpu_info(cpu)) {
> - if ((volatile void *)on_cpu_info[cpu].func == NULL)
> - break;
> - put_on_cpu_info(cpu);
> - }
> + spin_lock(&lock);
> + if (cpu_idle(cpu))
> + break;
> + spin_unlock(&lock);
> }
>
> on_cpu_info[cpu].func = func;
> on_cpu_info[cpu].data = data;
> + smp_wmb();
> set_cpu_idle(cpu, false);
> - put_on_cpu_info(cpu);
> + spin_unlock(&lock);
> smp_send_event();
> }
>
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [kvm-unit-tests PATCH v2 2/3] lib/on-cpus: Add barrier after func call
2024-10-31 12:39 ` [kvm-unit-tests PATCH v2 2/3] lib/on-cpus: Add barrier after func call Andrew Jones
2024-11-06 8:15 ` Andrew Jones
@ 2024-11-07 10:02 ` Eric Auger
1 sibling, 0 replies; 10+ messages in thread
From: Eric Auger @ 2024-11-07 10:02 UTC (permalink / raw)
To: Andrew Jones, kvm, kvm-riscv, kvmarm
Cc: atishp, jamestiotio, alexandru.elisei
On 10/31/24 13:39, Andrew Jones wrote:
> It's reasonable for users of on_cpu() and on_cpumask() to assume
> they can read data that 'func' has written when the call completes.
> Ensure the caller doesn't observe a completion (target cpus are again
> idle) without also being able to observe any writes which were made
> by func(). Do so by adding barriers to implement the following
>
> target-cpu calling-cpu
> ---------- -----------
> func() /* store something */ /* wait for target to be idle */
> smp_wmb(); smp_rmb();
> set_cpu_idle(smp_processor_id(), true); /* load what func() stored */
>
> Signed-off-by: Andrew Jones <andrew.jones@linux.dev>
Reviewed-by: Eric Auger <eric.auger@redhat.com>
Eric
> ---
> lib/on-cpus.c | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/lib/on-cpus.c b/lib/on-cpus.c
> index f6072117fa1b..356f284be61b 100644
> --- a/lib/on-cpus.c
> +++ b/lib/on-cpus.c
> @@ -79,6 +79,7 @@ void do_idle(void)
> smp_wait_for_event();
> smp_rmb();
> on_cpu_info[cpu].func(on_cpu_info[cpu].data);
> + smp_wmb(); /* pairs with the smp_rmb() in on_cpu() and on_cpumask() */
> }
> }
>
> @@ -145,12 +146,14 @@ void on_cpumask(const cpumask_t *mask, void (*func)(void *data), void *data)
> smp_wait_for_event();
> for_each_cpu(cpu, mask)
> cpumask_clear_cpu(me, &on_cpu_info[cpu].waiters);
> + smp_rmb(); /* pairs with the smp_wmb() in do_idle() */
> }
>
> void on_cpu(int cpu, void (*func)(void *data), void *data)
> {
> on_cpu_async(cpu, func, data);
> cpu_wait(cpu);
> + smp_rmb(); /* pairs with the smp_wmb() in do_idle() */
> }
>
> void on_cpus(void (*func)(void *data), void *data)
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [kvm-unit-tests PATCH v2 3/3] lib/on-cpus: Fix on_cpumask
2024-10-31 12:39 ` [kvm-unit-tests PATCH v2 3/3] lib/on-cpus: Fix on_cpumask Andrew Jones
@ 2024-11-07 17:55 ` Eric Auger
0 siblings, 0 replies; 10+ messages in thread
From: Eric Auger @ 2024-11-07 17:55 UTC (permalink / raw)
To: Andrew Jones, kvm, kvm-riscv, kvmarm
Cc: atishp, jamestiotio, alexandru.elisei
Hi Drew,
On 10/31/24 13:39, Andrew Jones wrote:
> on_cpumask should wait until the cpus in the mask, not including
> the calling cpu, are idle. Checking the weight against nr_cpus
> minus 1 only works when the mask is the same as the present mask.
>
> Fixes: d012cfd5d309 ("lib/on-cpus: Introduce on_cpumask and on_cpumask_async")
> Signed-off-by: Andrew Jones <andrew.jones@linux.dev>
looks good to me as well
Reviewed-by: Eric Auger <eric.auger@redhat.com>
Eric
> ---
> lib/cpumask.h | 14 ++++++++++++++
> lib/on-cpus.c | 17 ++++++++---------
> 2 files changed, 22 insertions(+), 9 deletions(-)
>
> diff --git a/lib/cpumask.h b/lib/cpumask.h
> index e1e92aacd1f1..37d360786573 100644
> --- a/lib/cpumask.h
> +++ b/lib/cpumask.h
> @@ -58,6 +58,20 @@ static inline void cpumask_clear(cpumask_t *mask)
> memset(mask, 0, sizeof(*mask));
> }
>
> +/* true if src1 is a subset of src2 */
> +static inline bool cpumask_subset(const struct cpumask *src1, const struct cpumask *src2)
> +{
> + unsigned long lastmask = BIT_MASK(nr_cpus) - 1;
> + int i;
> +
> + for (i = 0; i < BIT_WORD(nr_cpus); ++i) {
> + if (cpumask_bits(src1)[i] & ~cpumask_bits(src2)[i])
> + return false;
> + }
> +
> + return !lastmask || !((cpumask_bits(src1)[i] & ~cpumask_bits(src2)[i]) & lastmask);
> +}
> +
> static inline bool cpumask_empty(const cpumask_t *mask)
> {
> unsigned long lastmask = BIT_MASK(nr_cpus) - 1;
> diff --git a/lib/on-cpus.c b/lib/on-cpus.c
> index 356f284be61b..889b6bc8a186 100644
> --- a/lib/on-cpus.c
> +++ b/lib/on-cpus.c
> @@ -127,24 +127,23 @@ void on_cpumask_async(const cpumask_t *mask, void (*func)(void *data), void *dat
> void on_cpumask(const cpumask_t *mask, void (*func)(void *data), void *data)
> {
> int cpu, me = smp_processor_id();
> + cpumask_t tmp;
>
> - for_each_cpu(cpu, mask) {
> - if (cpu == me)
> - continue;
> + cpumask_copy(&tmp, mask);
> + cpumask_clear_cpu(me, &tmp);
> +
> + for_each_cpu(cpu, &tmp)
> on_cpu_async(cpu, func, data);
> - }
> if (cpumask_test_cpu(me, mask))
> func(data);
>
> - for_each_cpu(cpu, mask) {
> - if (cpu == me)
> - continue;
> + for_each_cpu(cpu, &tmp) {
> cpumask_set_cpu(me, &on_cpu_info[cpu].waiters);
> deadlock_check(me, cpu);
> }
> - while (cpumask_weight(&cpu_idle_mask) < nr_cpus - 1)
> + while (!cpumask_subset(&tmp, &cpu_idle_mask))
> smp_wait_for_event();
> - for_each_cpu(cpu, mask)
> + for_each_cpu(cpu, &tmp)
> cpumask_clear_cpu(me, &on_cpu_info[cpu].waiters);
> smp_rmb(); /* pairs with the smp_wmb() in do_idle() */
> }
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [kvm-unit-tests PATCH v2 0/3] lib/on-cpus: A couple of fixes
2024-10-31 12:39 [kvm-unit-tests PATCH v2 0/3] lib/on-cpus: A couple of fixes Andrew Jones
` (2 preceding siblings ...)
2024-10-31 12:39 ` [kvm-unit-tests PATCH v2 3/3] lib/on-cpus: Fix on_cpumask Andrew Jones
@ 2024-11-11 14:36 ` Andrew Jones
2024-12-03 11:43 ` Alexandru Elisei
3 siblings, 1 reply; 10+ messages in thread
From: Andrew Jones @ 2024-11-11 14:36 UTC (permalink / raw)
To: kvm, kvm-riscv, kvmarm; +Cc: atishp, jamestiotio, alexandru.elisei, eric.auger
On Thu, Oct 31, 2024 at 01:39:49PM +0100, Andrew Jones wrote:
> While creating riscv SBI HSM tests a couple strange on-cpus behaviors
> were observed. Fix 'em.
>
> v2:
> - Added patch for barrier after func() [Alex]
> - Improved commit message for patch1 [Alex]
>
> Andrew Jones (3):
> lib/on-cpus: Correct and simplify synchronization
> lib/on-cpus: Add barrier after func call
> lib/on-cpus: Fix on_cpumask
>
> lib/cpumask.h | 14 +++++++++++++
> lib/on-cpus.c | 56 ++++++++++++++++++++-------------------------------
> 2 files changed, 36 insertions(+), 34 deletions(-)
>
> --
> 2.47.0
>
Merged to master through riscv/queue.
Thanks,
drew
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [kvm-unit-tests PATCH v2 0/3] lib/on-cpus: A couple of fixes
2024-11-11 14:36 ` [kvm-unit-tests PATCH v2 0/3] lib/on-cpus: A couple of fixes Andrew Jones
@ 2024-12-03 11:43 ` Alexandru Elisei
0 siblings, 0 replies; 10+ messages in thread
From: Alexandru Elisei @ 2024-12-03 11:43 UTC (permalink / raw)
To: Andrew Jones; +Cc: kvm, kvm-riscv, kvmarm, atishp, jamestiotio, eric.auger
Hi Drew,
On Mon, Nov 11, 2024 at 03:36:30PM +0100, Andrew Jones wrote:
> On Thu, Oct 31, 2024 at 01:39:49PM +0100, Andrew Jones wrote:
> > While creating riscv SBI HSM tests a couple strange on-cpus behaviors
> > were observed. Fix 'em.
> >
> > v2:
> > - Added patch for barrier after func() [Alex]
> > - Improved commit message for patch1 [Alex]
> >
> > Andrew Jones (3):
> > lib/on-cpus: Correct and simplify synchronization
> > lib/on-cpus: Add barrier after func call
> > lib/on-cpus: Fix on_cpumask
> >
> > lib/cpumask.h | 14 +++++++++++++
> > lib/on-cpus.c | 56 ++++++++++++++++++++-------------------------------
> > 2 files changed, 36 insertions(+), 34 deletions(-)
> >
> > --
> > 2.47.0
> >
>
> Merged to master through riscv/queue.
Sorry, I was busy with something else and I didn't have the time to review
the series until now.
I had a look and it looks good to me.
Thanks,
Alex
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2024-12-03 11:43 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-10-31 12:39 [kvm-unit-tests PATCH v2 0/3] lib/on-cpus: A couple of fixes Andrew Jones
2024-10-31 12:39 ` [kvm-unit-tests PATCH v2 1/3] lib/on-cpus: Correct and simplify synchronization Andrew Jones
2024-11-07 10:01 ` Eric Auger
2024-10-31 12:39 ` [kvm-unit-tests PATCH v2 2/3] lib/on-cpus: Add barrier after func call Andrew Jones
2024-11-06 8:15 ` Andrew Jones
2024-11-07 10:02 ` Eric Auger
2024-10-31 12:39 ` [kvm-unit-tests PATCH v2 3/3] lib/on-cpus: Fix on_cpumask Andrew Jones
2024-11-07 17:55 ` Eric Auger
2024-11-11 14:36 ` [kvm-unit-tests PATCH v2 0/3] lib/on-cpus: A couple of fixes Andrew Jones
2024-12-03 11:43 ` Alexandru Elisei
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox