* Re: [PATCH 1/2] kvm: use modern cpumask primitives, no cpumask_t on stack
[not found] <200812072125.14416.rusty@rustcorp.com.au>
@ 2008-12-07 15:52 ` Avi Kivity
2008-12-07 16:14 ` Avi Kivity
` (2 more replies)
0 siblings, 3 replies; 10+ messages in thread
From: Avi Kivity @ 2008-12-07 15:52 UTC (permalink / raw)
To: Rusty Russell; +Cc: kvm-devel, linux-kernel, Mike Travis, Avi Kivity
Rusty Russell wrote:
> We're getting rid on on-stack cpumasks for large NR_CPUS.
>
> 1) Use cpumask_var_t and alloc_cpumask_var (a noop normally). Fallback
> code is inefficient but never happens in practice.
> 2) smp_call_function_mask -> smp_call_function_many
> 3) cpus_clear, cpus_empty, cpu_set -> cpumask_clear, cpumask_empty,
> cpumask_set_cpu.
>
> --- linux-2.6.orig/virt/kvm/kvm_main.c
> +++ linux-2.6/virt/kvm/kvm_main.c
> @@ -358,11 +358,23 @@ static void ack_flush(void *_completed)
> void kvm_flush_remote_tlbs(struct kvm *kvm)
> {
> int i, cpu, me;
> - cpumask_t cpus;
> + cpumask_var_t cpus;
> struct kvm_vcpu *vcpu;
>
> me = get_cpu();
> - cpus_clear(cpus);
> + if (!alloc_cpumask_var(&cpus, GFP_ATOMIC)) {
> + /* Slow path on failure. Call everyone. */
> + for (i = 0; i < KVM_MAX_VCPUS; ++i) {
> + vcpu = kvm->vcpus[i];
> + if (vcpu)
> + set_bit(KVM_REQ_TLB_FLUSH, &vcpu->requests);
> + }
> + ++kvm->stat.remote_tlb_flush;
> + smp_call_function_many(cpu_online_mask, ack_flush, NULL, 1);
> + put_cpu();
> + return;
> + }
> +
>
Wow, code duplication from Rusty. Things must be bad.
Since we're in a get_cpu() here, how about a per_cpu static cpumask
instead? I don't mind the inefficient fallback, just the duplication.
--
error compiling committee.c: too many arguments to function
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 1/2] kvm: use modern cpumask primitives, no cpumask_t on stack
2008-12-07 15:52 ` [PATCH 1/2] kvm: use modern cpumask primitives, no cpumask_t on stack Avi Kivity
@ 2008-12-07 16:14 ` Avi Kivity
2008-12-08 6:08 ` Rusty Russell
2008-12-08 9:56 ` [PATCH] kvm: Extract core of kvm_flush_remote_tlbs/kvm_reload_remote_mmus Rusty Russell
2008-12-08 14:32 ` [PATCH 1/2] kvm: use modern cpumask primitives, no cpumask_t on stack Mike Travis
2 siblings, 1 reply; 10+ messages in thread
From: Avi Kivity @ 2008-12-07 16:14 UTC (permalink / raw)
To: Rusty Russell; +Cc: kvm-devel, linux-kernel, Mike Travis
Avi Kivity wrote:
> Rusty Russell wrote:
>> We're getting rid on on-stack cpumasks for large NR_CPUS.
>>
>> 1) Use cpumask_var_t and alloc_cpumask_var (a noop normally). Fallback
>> code is inefficient but never happens in practice.
>
> Wow, code duplication from Rusty. Things must be bad.
>
> Since we're in a get_cpu() here, how about a per_cpu static cpumask
> instead? I don't mind the inefficient fallback, just the duplication.
>
Btw, for the general case, instead of forcing everyone to duplicate, how
about:
cpumask_var_t cpus;
with_cpumask(cpus) {
... code to populate cpus
smp_call_function_some(...);
} end_with_cpumask(cpus);
Where with_cpumask() allocates cpus, and uses a mutex + static fallback
on failure.
May need a couple of variants (spinlock + GFP_NOWAIT, mutex with
sleeping allocation).
--
error compiling committee.c: too many arguments to function
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 1/2] kvm: use modern cpumask primitives, no cpumask_t on stack
2008-12-07 16:14 ` Avi Kivity
@ 2008-12-08 6:08 ` Rusty Russell
2008-12-08 9:49 ` Avi Kivity
0 siblings, 1 reply; 10+ messages in thread
From: Rusty Russell @ 2008-12-08 6:08 UTC (permalink / raw)
To: Avi Kivity; +Cc: kvm-devel, linux-kernel, Mike Travis
On Monday 08 December 2008 02:44:00 Avi Kivity wrote:
> Avi Kivity wrote:
> > Rusty Russell wrote:
> >> We're getting rid on on-stack cpumasks for large NR_CPUS.
> >>
> >> 1) Use cpumask_var_t and alloc_cpumask_var (a noop normally). Fallback
> >> code is inefficient but never happens in practice.
> >
> > Wow, code duplication from Rusty. Things must be bad.
> >
> > Since we're in a get_cpu() here, how about a per_cpu static cpumask
> > instead? I don't mind the inefficient fallback, just the duplication.
> >
>
> Btw, for the general case, instead of forcing everyone to duplicate, how
> about:
>
> cpumask_var_t cpus;
>
> with_cpumask(cpus) {
> ... code to populate cpus
> smp_call_function_some(...);
> } end_with_cpumask(cpus);
>
> Where with_cpumask() allocates cpus, and uses a mutex + static fallback
> on failure.
I'd prefer not to hide deadlocks that way :(
I'll re-battle with that code to neaten it. There are only a few places
which have these kind of issues.
Thanks,
Rusty.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 1/2] kvm: use modern cpumask primitives, no cpumask_t on stack
2008-12-08 6:08 ` Rusty Russell
@ 2008-12-08 9:49 ` Avi Kivity
2008-12-08 11:55 ` Rusty Russell
0 siblings, 1 reply; 10+ messages in thread
From: Avi Kivity @ 2008-12-08 9:49 UTC (permalink / raw)
To: Rusty Russell; +Cc: kvm-devel, linux-kernel, Mike Travis
Rusty Russell wrote:
>> Btw, for the general case, instead of forcing everyone to duplicate, how
>> about:
>>
>> cpumask_var_t cpus;
>>
>> with_cpumask(cpus) {
>> ... code to populate cpus
>> smp_call_function_some(...);
>> } end_with_cpumask(cpus);
>>
>> Where with_cpumask() allocates cpus, and uses a mutex + static fallback
>> on failure.
>>
>
> I'd prefer not to hide deadlocks that way :(
>
> I'll re-battle with that code to neaten it. There are only a few places
> which have these kind of issues.
>
>
cpuvar_get_maybe_mutex_lock(...);
...
cpuvar_put_maybe_mutex_unlock(...);
?
--
I have a truly marvellous patch that fixes the bug which this
signature is too narrow to contain.
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH] kvm: Extract core of kvm_flush_remote_tlbs/kvm_reload_remote_mmus.
2008-12-07 15:52 ` [PATCH 1/2] kvm: use modern cpumask primitives, no cpumask_t on stack Avi Kivity
2008-12-07 16:14 ` Avi Kivity
@ 2008-12-08 9:56 ` Rusty Russell
2008-12-08 9:58 ` kvm: use modern cpumask primitives, no cpumask_t on stack Rusty Russell
2008-12-08 12:00 ` [PATCH] kvm: Extract core of kvm_flush_remote_tlbs/kvm_reload_remote_mmus Avi Kivity
2008-12-08 14:32 ` [PATCH 1/2] kvm: use modern cpumask primitives, no cpumask_t on stack Mike Travis
2 siblings, 2 replies; 10+ messages in thread
From: Rusty Russell @ 2008-12-08 9:56 UTC (permalink / raw)
To: Avi Kivity; +Cc: kvm-devel, linux-kernel, Mike Travis
Avi said:
> Wow, code duplication from Rusty. Things must be bad.
Something about glass houses comes to mind. But instead, a patch.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
---
virt/kvm/kvm_main.c | 44 +++++++++++++++-----------------------------
1 file changed, 15 insertions(+), 29 deletions(-)
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -355,10 +355,11 @@ static void ack_flush(void *_completed)
{
}
-void kvm_flush_remote_tlbs(struct kvm *kvm)
+static bool make_all_cpus_request(struct kvm *kvm, unsigned int req)
{
int i, cpu, me;
cpumask_t cpus;
+ bool called = false;
struct kvm_vcpu *vcpu;
me = get_cpu();
@@ -367,45 +368,30 @@ void kvm_flush_remote_tlbs(struct kvm *k
vcpu = kvm->vcpus[i];
if (!vcpu)
continue;
- if (test_and_set_bit(KVM_REQ_TLB_FLUSH, &vcpu->requests))
+ if (test_and_set_bit(req, &vcpu->requests))
continue;
cpu = vcpu->cpu;
if (cpu != -1 && cpu != me)
cpu_set(cpu, cpus);
}
- if (cpus_empty(cpus))
- goto out;
- ++kvm->stat.remote_tlb_flush;
- smp_call_function_mask(cpus, ack_flush, NULL, 1);
-out:
+ if (!cpus_empty(cpus)) {
+ smp_call_function_mask(cpus, ack_flush, NULL, 1);
+ called = true;
+ }
put_cpu();
+ return called;
+}
+
+void kvm_flush_remote_tlbs(struct kvm *kvm)
+{
+ if (make_all_cpus_request(kvm, KVM_REQ_TLB_FLUSH))
+ ++kvm->stat.remote_tlb_flush;
}
void kvm_reload_remote_mmus(struct kvm *kvm)
{
- int i, cpu, me;
- cpumask_t cpus;
- struct kvm_vcpu *vcpu;
-
- me = get_cpu();
- cpus_clear(cpus);
- for (i = 0; i < KVM_MAX_VCPUS; ++i) {
- vcpu = kvm->vcpus[i];
- if (!vcpu)
- continue;
- if (test_and_set_bit(KVM_REQ_MMU_RELOAD, &vcpu->requests))
- continue;
- cpu = vcpu->cpu;
- if (cpu != -1 && cpu != me)
- cpu_set(cpu, cpus);
- }
- if (cpus_empty(cpus))
- goto out;
- smp_call_function_mask(cpus, ack_flush, NULL, 1);
-out:
- put_cpu();
+ make_all_cpus_request(kvm, KVM_REQ_MMU_RELOAD);
}
-
int kvm_vcpu_init(struct kvm_vcpu *vcpu, struct kvm *kvm, unsigned id)
{
^ permalink raw reply [flat|nested] 10+ messages in thread
* kvm: use modern cpumask primitives, no cpumask_t on stack
2008-12-08 9:56 ` [PATCH] kvm: Extract core of kvm_flush_remote_tlbs/kvm_reload_remote_mmus Rusty Russell
@ 2008-12-08 9:58 ` Rusty Russell
2008-12-08 12:00 ` [PATCH] kvm: Extract core of kvm_flush_remote_tlbs/kvm_reload_remote_mmus Avi Kivity
1 sibling, 0 replies; 10+ messages in thread
From: Rusty Russell @ 2008-12-08 9:58 UTC (permalink / raw)
To: Avi Kivity; +Cc: kvm-devel, linux-kernel, Mike Travis
We're getting rid on on-stack cpumasks for large NR_CPUS.
1) Use cpumask_var_t/alloc_cpumask_var.
2) smp_call_function_mask -> smp_call_function_many
3) cpus_clear, cpus_empty, cpu_set -> cpumask_clear, cpumask_empty,
cpumask_set_cpu.
This actually generates slightly smaller code than the old one with
CONFIG_CPUMASKS_OFFSTACK=n. (gcc knows that cpus cannot be NULL in
that case, where cpumask_var_t is cpumask_t[1]).
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
---
virt/kvm/kvm_main.c | 23 ++++++++++++++---------
1 file changed, 14 insertions(+), 9 deletions(-)
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -358,12 +358,14 @@ static bool make_all_cpus_request(struct
static bool make_all_cpus_request(struct kvm *kvm, unsigned int req)
{
int i, cpu, me;
- cpumask_t cpus;
- bool called = false;
+ cpumask_var_t cpus;
+ bool called = true;
struct kvm_vcpu *vcpu;
+ if (alloc_cpumask_var(&cpus, GFP_ATOMIC))
+ cpumask_clear(cpus);
+
me = get_cpu();
- cpus_clear(cpus);
for (i = 0; i < KVM_MAX_VCPUS; ++i) {
vcpu = kvm->vcpus[i];
if (!vcpu)
@@ -371,14 +373,17 @@ static bool make_all_cpus_request(struct
if (test_and_set_bit(req, &vcpu->requests))
continue;
cpu = vcpu->cpu;
- if (cpu != -1 && cpu != me)
- cpu_set(cpu, cpus);
+ if (cpus != NULL && cpu != -1 && cpu != me)
+ cpumask_set_cpu(cpu, cpus);
}
- if (!cpus_empty(cpus)) {
- smp_call_function_mask(cpus, ack_flush, NULL, 1);
- called = true;
- }
+ if (unlikely(cpus == NULL))
+ smp_call_function_many(cpu_online_mask, ack_flush, NULL, 1);
+ else if (!cpumask_empty(cpus))
+ smp_call_function_many(cpus, ack_flush, NULL, 1);
+ else
+ called = false;
put_cpu();
+ free_cpumask_var(cpus);
return called;
}
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 1/2] kvm: use modern cpumask primitives, no cpumask_t on stack
2008-12-08 9:49 ` Avi Kivity
@ 2008-12-08 11:55 ` Rusty Russell
0 siblings, 0 replies; 10+ messages in thread
From: Rusty Russell @ 2008-12-08 11:55 UTC (permalink / raw)
To: Avi Kivity; +Cc: kvm-devel, linux-kernel, Mike Travis
On Monday 08 December 2008 20:19:57 Avi Kivity wrote:
> Rusty Russell wrote:
> >> Btw, for the general case, instead of forcing everyone to duplicate, how
> >> about:
> >>
> >> cpumask_var_t cpus;
> >>
> >> with_cpumask(cpus) {
> >> ... code to populate cpus
> >> smp_call_function_some(...);
> >> } end_with_cpumask(cpus);
> >>
> >> Where with_cpumask() allocates cpus, and uses a mutex + static fallback
> >> on failure.
> >>
> >
> > I'd prefer not to hide deadlocks that way :(
> >
> > I'll re-battle with that code to neaten it. There are only a few places
> > which have these kind of issues.
> >
> >
>
> cpuvar_get_maybe_mutex_lock(...);
> ...
> cpuvar_put_maybe_mutex_unlock(...);
My thought was something like:
/* This is an empty struct for !CONFIG_CPUMASK_OFFSTACK. */
static struct cpuvar_with_mutex_fallback fallback;
...
cpumask_var_t tmp;
cpuvar_alloc_fallback(&tmp, &fallback);
...
cpuvar_free_fallback(tmp, &fallback);
We may get there eventually, but so far I've managed to produce
less horrendous code in every case.
Cheers,
Rusty.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] kvm: Extract core of kvm_flush_remote_tlbs/kvm_reload_remote_mmus.
2008-12-08 9:56 ` [PATCH] kvm: Extract core of kvm_flush_remote_tlbs/kvm_reload_remote_mmus Rusty Russell
2008-12-08 9:58 ` kvm: use modern cpumask primitives, no cpumask_t on stack Rusty Russell
@ 2008-12-08 12:00 ` Avi Kivity
1 sibling, 0 replies; 10+ messages in thread
From: Avi Kivity @ 2008-12-08 12:00 UTC (permalink / raw)
To: Rusty Russell; +Cc: kvm-devel, linux-kernel, Mike Travis
Rusty Russell wrote:
> Avi said:
>
>> Wow, code duplication from Rusty. Things must be bad.
>>
>
> Something about glass houses comes to mind. But instead, a patch.
>
Er, right, eek.
I've applied all three patches, thanks.
--
error compiling committee.c: too many arguments to function
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 1/2] kvm: use modern cpumask primitives, no cpumask_t on stack
2008-12-07 15:52 ` [PATCH 1/2] kvm: use modern cpumask primitives, no cpumask_t on stack Avi Kivity
2008-12-07 16:14 ` Avi Kivity
2008-12-08 9:56 ` [PATCH] kvm: Extract core of kvm_flush_remote_tlbs/kvm_reload_remote_mmus Rusty Russell
@ 2008-12-08 14:32 ` Mike Travis
2008-12-08 14:55 ` Avi Kivity
2 siblings, 1 reply; 10+ messages in thread
From: Mike Travis @ 2008-12-08 14:32 UTC (permalink / raw)
To: Avi Kivity; +Cc: Rusty Russell, kvm-devel, linux-kernel
Avi Kivity wrote:
> Rusty Russell wrote:
>> We're getting rid on on-stack cpumasks for large NR_CPUS.
>>
>> 1) Use cpumask_var_t and alloc_cpumask_var (a noop normally). Fallback
>> code is inefficient but never happens in practice.
>> 2) smp_call_function_mask -> smp_call_function_many
>> 3) cpus_clear, cpus_empty, cpu_set -> cpumask_clear, cpumask_empty,
>> cpumask_set_cpu.
>>
>> --- linux-2.6.orig/virt/kvm/kvm_main.c
>> +++ linux-2.6/virt/kvm/kvm_main.c
>> @@ -358,11 +358,23 @@ static void ack_flush(void *_completed)
>> void kvm_flush_remote_tlbs(struct kvm *kvm)
>> {
>> int i, cpu, me;
>> - cpumask_t cpus;
>> + cpumask_var_t cpus;
>> struct kvm_vcpu *vcpu;
>>
>> me = get_cpu();
>> - cpus_clear(cpus);
>> + if (!alloc_cpumask_var(&cpus, GFP_ATOMIC)) {
>> + /* Slow path on failure. Call everyone. */
>> + for (i = 0; i < KVM_MAX_VCPUS; ++i) {
>> + vcpu = kvm->vcpus[i];
>> + if (vcpu)
>> + set_bit(KVM_REQ_TLB_FLUSH, &vcpu->requests);
>> + }
>> + ++kvm->stat.remote_tlb_flush;
>> + smp_call_function_many(cpu_online_mask, ack_flush, NULL, 1);
>> + put_cpu();
>> + return;
>> + }
>> +
>>
>
> Wow, code duplication from Rusty. Things must be bad.
>
> Since we're in a get_cpu() here, how about a per_cpu static cpumask
> instead? I don't mind the inefficient fallback, just the duplication.
>
One thing to note is that when CPUMASK_OFFSTACK=n, then alloc_cpumask_var
returns a constant 1 and the duplicate code is not even compiled.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 1/2] kvm: use modern cpumask primitives, no cpumask_t on stack
2008-12-08 14:32 ` [PATCH 1/2] kvm: use modern cpumask primitives, no cpumask_t on stack Mike Travis
@ 2008-12-08 14:55 ` Avi Kivity
0 siblings, 0 replies; 10+ messages in thread
From: Avi Kivity @ 2008-12-08 14:55 UTC (permalink / raw)
To: Mike Travis; +Cc: Rusty Russell, kvm-devel, linux-kernel
Mike Travis wrote:
>> Since we're in a get_cpu() here, how about a per_cpu static cpumask
>> instead? I don't mind the inefficient fallback, just the duplication.
>>
>
> One thing to note is that when CPUMASK_OFFSTACK=n, then alloc_cpumask_var
> returns a constant 1 and the duplicate code is not even compiled.
>
I'm a lot more concerned about source duplication than binary
duplication. Rusty's patches resulted in a net reduction in
duplication, so perhaps I should keep quiet about it.
--
error compiling committee.c: too many arguments to function
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2008-12-08 14:56 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <200812072125.14416.rusty@rustcorp.com.au>
2008-12-07 15:52 ` [PATCH 1/2] kvm: use modern cpumask primitives, no cpumask_t on stack Avi Kivity
2008-12-07 16:14 ` Avi Kivity
2008-12-08 6:08 ` Rusty Russell
2008-12-08 9:49 ` Avi Kivity
2008-12-08 11:55 ` Rusty Russell
2008-12-08 9:56 ` [PATCH] kvm: Extract core of kvm_flush_remote_tlbs/kvm_reload_remote_mmus Rusty Russell
2008-12-08 9:58 ` kvm: use modern cpumask primitives, no cpumask_t on stack Rusty Russell
2008-12-08 12:00 ` [PATCH] kvm: Extract core of kvm_flush_remote_tlbs/kvm_reload_remote_mmus Avi Kivity
2008-12-08 14:32 ` [PATCH 1/2] kvm: use modern cpumask primitives, no cpumask_t on stack Mike Travis
2008-12-08 14:55 ` Avi Kivity
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).