Re: [PATCH v6 10/12] Handle async PF in non preemptable context

2010-10-10 Thread Gleb Natapov
On Wed, Oct 06, 2010 at 12:41:32PM +0200, Gleb Natapov wrote:
 On Tue, Oct 05, 2010 at 04:51:50PM -0300, Marcelo Tosatti wrote:
  On Mon, Oct 04, 2010 at 05:56:32PM +0200, Gleb Natapov wrote:
   If async page fault is received by idle task or when preemp_count is
   not zero guest cannot reschedule, so do sti; hlt and wait for page to be
   ready. vcpu can still process interrupts while it waits for the page to
   be ready.
   
   Acked-by: Rik van Riel r...@redhat.com
   Signed-off-by: Gleb Natapov g...@redhat.com
   ---
arch/x86/kernel/kvm.c |   40 ++--
1 files changed, 34 insertions(+), 6 deletions(-)
   
   diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c
   index 36fb3e4..f73946f 100644
   --- a/arch/x86/kernel/kvm.c
   +++ b/arch/x86/kernel/kvm.c
   @@ -37,6 +37,7 @@
#include asm/cpu.h
#include asm/traps.h
#include asm/desc.h
   +#include asm/tlbflush.h

#define MMU_QUEUE_SIZE 1024

   @@ -78,6 +79,8 @@ struct kvm_task_sleep_node {
 wait_queue_head_t wq;
 u32 token;
 int cpu;
   + bool halted;
   + struct mm_struct *mm;
};

static struct kvm_task_sleep_head {
   @@ -106,6 +109,11 @@ void kvm_async_pf_task_wait(u32 token)
 struct kvm_task_sleep_head *b = async_pf_sleepers[key];
 struct kvm_task_sleep_node n, *e;
 DEFINE_WAIT(wait);
   + int cpu, idle;
   +
   + cpu = get_cpu();
   + idle = idle_cpu(cpu);
   + put_cpu();

 spin_lock(b-lock);
 e = _find_apf_task(b, token);
   @@ -119,19 +127,33 @@ void kvm_async_pf_task_wait(u32 token)

 n.token = token;
 n.cpu = smp_processor_id();
   + n.mm = current-active_mm;
   + n.halted = idle || preempt_count()  1;
   + atomic_inc(n.mm-mm_count);
  
  Can't see why this reference is needed.
 I thought that if kernel thread does fault on behalf of some
 process mm can go away while kernel thread is sleeping. But it looks
 like kernel thread increase reference to mm it runs with by himself, so
 may be this is redundant (but not harmful).
 
Actually it is not redundant. Kernel thread will release reference to
active_mm on reschedule.

--
Gleb.
--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v6 10/12] Handle async PF in non preemptable context

2010-10-06 Thread Gleb Natapov
On Tue, Oct 05, 2010 at 04:51:50PM -0300, Marcelo Tosatti wrote:
 On Mon, Oct 04, 2010 at 05:56:32PM +0200, Gleb Natapov wrote:
  If async page fault is received by idle task or when preemp_count is
  not zero guest cannot reschedule, so do sti; hlt and wait for page to be
  ready. vcpu can still process interrupts while it waits for the page to
  be ready.
  
  Acked-by: Rik van Riel r...@redhat.com
  Signed-off-by: Gleb Natapov g...@redhat.com
  ---
   arch/x86/kernel/kvm.c |   40 ++--
   1 files changed, 34 insertions(+), 6 deletions(-)
  
  diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c
  index 36fb3e4..f73946f 100644
  --- a/arch/x86/kernel/kvm.c
  +++ b/arch/x86/kernel/kvm.c
  @@ -37,6 +37,7 @@
   #include asm/cpu.h
   #include asm/traps.h
   #include asm/desc.h
  +#include asm/tlbflush.h
   
   #define MMU_QUEUE_SIZE 1024
   
  @@ -78,6 +79,8 @@ struct kvm_task_sleep_node {
  wait_queue_head_t wq;
  u32 token;
  int cpu;
  +   bool halted;
  +   struct mm_struct *mm;
   };
   
   static struct kvm_task_sleep_head {
  @@ -106,6 +109,11 @@ void kvm_async_pf_task_wait(u32 token)
  struct kvm_task_sleep_head *b = async_pf_sleepers[key];
  struct kvm_task_sleep_node n, *e;
  DEFINE_WAIT(wait);
  +   int cpu, idle;
  +
  +   cpu = get_cpu();
  +   idle = idle_cpu(cpu);
  +   put_cpu();
   
  spin_lock(b-lock);
  e = _find_apf_task(b, token);
  @@ -119,19 +127,33 @@ void kvm_async_pf_task_wait(u32 token)
   
  n.token = token;
  n.cpu = smp_processor_id();
  +   n.mm = current-active_mm;
  +   n.halted = idle || preempt_count()  1;
  +   atomic_inc(n.mm-mm_count);
 
 Can't see why this reference is needed.
I thought that if kernel thread does fault on behalf of some
process mm can go away while kernel thread is sleeping. But it looks
like kernel thread increase reference to mm it runs with by himself, so
may be this is redundant (but not harmful).

--
Gleb.
--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v6 10/12] Handle async PF in non preemptable context

2010-10-05 Thread Marcelo Tosatti
On Mon, Oct 04, 2010 at 05:56:32PM +0200, Gleb Natapov wrote:
 If async page fault is received by idle task or when preemp_count is
 not zero guest cannot reschedule, so do sti; hlt and wait for page to be
 ready. vcpu can still process interrupts while it waits for the page to
 be ready.
 
 Acked-by: Rik van Riel r...@redhat.com
 Signed-off-by: Gleb Natapov g...@redhat.com
 ---
  arch/x86/kernel/kvm.c |   40 ++--
  1 files changed, 34 insertions(+), 6 deletions(-)
 
 diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c
 index 36fb3e4..f73946f 100644
 --- a/arch/x86/kernel/kvm.c
 +++ b/arch/x86/kernel/kvm.c
 @@ -37,6 +37,7 @@
  #include asm/cpu.h
  #include asm/traps.h
  #include asm/desc.h
 +#include asm/tlbflush.h
  
  #define MMU_QUEUE_SIZE 1024
  
 @@ -78,6 +79,8 @@ struct kvm_task_sleep_node {
   wait_queue_head_t wq;
   u32 token;
   int cpu;
 + bool halted;
 + struct mm_struct *mm;
  };
  
  static struct kvm_task_sleep_head {
 @@ -106,6 +109,11 @@ void kvm_async_pf_task_wait(u32 token)
   struct kvm_task_sleep_head *b = async_pf_sleepers[key];
   struct kvm_task_sleep_node n, *e;
   DEFINE_WAIT(wait);
 + int cpu, idle;
 +
 + cpu = get_cpu();
 + idle = idle_cpu(cpu);
 + put_cpu();
  
   spin_lock(b-lock);
   e = _find_apf_task(b, token);
 @@ -119,19 +127,33 @@ void kvm_async_pf_task_wait(u32 token)
  
   n.token = token;
   n.cpu = smp_processor_id();
 + n.mm = current-active_mm;
 + n.halted = idle || preempt_count()  1;
 + atomic_inc(n.mm-mm_count);

Can't see why this reference is needed.

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v6 10/12] Handle async PF in non preemptable context

2010-10-04 Thread Gleb Natapov
If async page fault is received by idle task or when preemp_count is
not zero guest cannot reschedule, so do sti; hlt and wait for page to be
ready. vcpu can still process interrupts while it waits for the page to
be ready.

Acked-by: Rik van Riel r...@redhat.com
Signed-off-by: Gleb Natapov g...@redhat.com
---
 arch/x86/kernel/kvm.c |   40 ++--
 1 files changed, 34 insertions(+), 6 deletions(-)

diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c
index 36fb3e4..f73946f 100644
--- a/arch/x86/kernel/kvm.c
+++ b/arch/x86/kernel/kvm.c
@@ -37,6 +37,7 @@
 #include asm/cpu.h
 #include asm/traps.h
 #include asm/desc.h
+#include asm/tlbflush.h
 
 #define MMU_QUEUE_SIZE 1024
 
@@ -78,6 +79,8 @@ struct kvm_task_sleep_node {
wait_queue_head_t wq;
u32 token;
int cpu;
+   bool halted;
+   struct mm_struct *mm;
 };
 
 static struct kvm_task_sleep_head {
@@ -106,6 +109,11 @@ void kvm_async_pf_task_wait(u32 token)
struct kvm_task_sleep_head *b = async_pf_sleepers[key];
struct kvm_task_sleep_node n, *e;
DEFINE_WAIT(wait);
+   int cpu, idle;
+
+   cpu = get_cpu();
+   idle = idle_cpu(cpu);
+   put_cpu();
 
spin_lock(b-lock);
e = _find_apf_task(b, token);
@@ -119,19 +127,33 @@ void kvm_async_pf_task_wait(u32 token)
 
n.token = token;
n.cpu = smp_processor_id();
+   n.mm = current-active_mm;
+   n.halted = idle || preempt_count()  1;
+   atomic_inc(n.mm-mm_count);
init_waitqueue_head(n.wq);
hlist_add_head(n.link, b-list);
spin_unlock(b-lock);
 
for (;;) {
-   prepare_to_wait(n.wq, wait, TASK_UNINTERRUPTIBLE);
+   if (!n.halted)
+   prepare_to_wait(n.wq, wait, TASK_UNINTERRUPTIBLE);
if (hlist_unhashed(n.link))
break;
-   local_irq_enable();
-   schedule();
-   local_irq_disable();
+
+   if (!n.halted) {
+   local_irq_enable();
+   schedule();
+   local_irq_disable();
+   } else {
+   /*
+* We cannot reschedule. So halt.
+*/
+   native_safe_halt();
+   local_irq_disable();
+   }
}
-   finish_wait(n.wq, wait);
+   if (!n.halted)
+   finish_wait(n.wq, wait);
 
return;
 }
@@ -140,7 +162,12 @@ EXPORT_SYMBOL_GPL(kvm_async_pf_task_wait);
 static void apf_task_wake_one(struct kvm_task_sleep_node *n)
 {
hlist_del_init(n-link);
-   if (waitqueue_active(n-wq))
+   if (!n-mm)
+   return;
+   mmdrop(n-mm);
+   if (n-halted)
+   smp_send_reschedule(n-cpu);
+   else if (waitqueue_active(n-wq))
wake_up(n-wq);
 }
 
@@ -193,6 +220,7 @@ again:
}
n-token = token;
n-cpu = smp_processor_id();
+   n-mm = NULL;
init_waitqueue_head(n-wq);
hlist_add_head(n-link, b-list);
} else
-- 
1.7.1

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html