[Devel] [PATCH rh7 07/14] Port diff-ve-kstat-disable-interrupts-around-seqcount-write-lock

Vladimir Davydov vdavydov at parallels.com
Tue Jun 23 09:29:43 PDT 2015


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 618c36c5fb73..a2da7e5c2377 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 627677c585cb..012a4e89e19a 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
 }
 
-- 
2.1.4




More information about the Devel mailing list