[Devel] [PATCH RHEL7 COMMIT] ve/mm/kstat: Port diff-ve-kstat-disable-interrupts-around-seqcount-write-lock

Konstantin Khorenko khorenko at virtuozzo.com
Wed Jun 24 03:42:27 PDT 2015


The commit is pushed to "branch-rh7-3.10.0-123.1.2-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-123.1.2.vz7.5.17
------>
commit 5f10333338ed762039a443a680b713748f18f660
Author: Vladimir Davydov <vdavydov at parallels.com>
Date:   Wed Jun 24 14:42:27 2015 +0400

    ve/mm/kstat: Port diff-ve-kstat-disable-interrupts-around-seqcount-write-lock
    
    Author: Konstantin Khlebnikov
    Email: khlebnikov at openvz.org
    Subject: vzstat: disable interrupts around seqcount write lock
    Date: Mon, 08 Oct 2012 15:26:09 +0400
    
    This fixes 3-way deadlock between vzstat seq-count, kstat_glb_lock and xtime_lock.
    
     timer interrupt:
    	write_seqlock(&xtime_lock);
    	 spin_lock_irqsave(&kstat_glb_lock);
    
     update_schedule_latency():
    	spin_lock_irq(&kstat_glb_lock);
    	 read_seqcount_begin(&cur->lock)
    
     some-interrupt during KSTAT_LAT_PCPU_ADD()
    	__alloc_collect_stats();
    	 KSTAT_LAT_PCPU_ADD();
    	  write_seqcount_begin(&cur->lock);
    	   <interrupt>
    	    ktime_get();
    	     read_seqcount_begin(&xtime_lock);
    
    https://jira.sw.ru/browse/PCLIN-31259
    
    Signed-off-by: Konstantin Khlebnikov <khlebnikov at openvz.org>
    
    =============================================================================
    
    Related to https://jira.sw.ru/browse/PSBM-33650
    
    Signed-off-by: Vladimir Davydov <vdavydov at parallels.com>
---
 mm/memory.c     | 4 ++--
 mm/page_alloc.c | 6 ++++--
 2 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/mm/memory.c b/mm/memory.c
index 618c36c..a2da7e5 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -3391,10 +3391,10 @@ static int __do_fault(struct mm_struct *mm, struct vm_area_struct *vma,
 	else
 		VM_BUG_ON(!PageLocked(vmf.page));
 
-	preempt_disable();
+	local_irq_disable();
 	KSTAT_LAT_PCPU_ADD(&kstat_glob.page_in, smp_processor_id(),
 			get_cycles() - start);
-	preempt_enable();
+	local_irq_enable();
 
 	/*
 	 * Should we do an early C-O-W break?
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 8fbe108..2c7a382 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -2646,6 +2646,7 @@ static void __alloc_collect_stats(gfp_t gfp_mask, unsigned int order,
 		struct page *page, u64 time)
 {
 #ifdef CONFIG_VE
+	unsigned long flags;
 	int ind, cpu;
 
 	time = jiffies_to_usecs(jiffies - time) * 1000;
@@ -2662,11 +2663,12 @@ static void __alloc_collect_stats(gfp_t gfp_mask, unsigned int order,
 		else
 			ind = KSTAT_ALLOCSTAT_HIGH;
 
-	cpu = get_cpu();
+	local_irq_save(flags);
+	cpu = smp_processor_id();
 	KSTAT_LAT_PCPU_ADD(&kstat_glob.alloc_lat[ind], cpu, time);
 	if (!page)
 		kstat_glob.alloc_fails[cpu][ind]++;
-	put_cpu();
+	local_irq_restore(flags);
 #endif
 }
 



More information about the Devel mailing list