x86/resctrl: Fix to restore to original value when re-enabling hardware prefetch...
authorKohei Tarumizu <tarumizu.kohei@fujitsu.com>
Wed, 24 Aug 2022 16:44:10 +0000 (09:44 -0700)
committerDave Hansen <dave.hansen@linux.intel.com>
Wed, 31 Aug 2022 18:42:17 +0000 (11:42 -0700)
The current pseudo_lock.c code overwrites the value of the
MSR_MISC_FEATURE_CONTROL to 0 even if the original value is not 0.
Therefore, modify it to save and restore the original values.

Fixes: 018961ae5579 ("x86/intel_rdt: Pseudo-lock region creation/removal core")
Fixes: 443810fe6160 ("x86/intel_rdt: Create debugfs files for pseudo-locking testing")
Fixes: 8a2fc0e1bc0c ("x86/intel_rdt: More precise L2 hit/miss measurements")
Signed-off-by: Kohei Tarumizu <tarumizu.kohei@fujitsu.com>
Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
Acked-by: Reinette Chatre <reinette.chatre@intel.com>
Link: https://lkml.kernel.org/r/eb660f3c2010b79a792c573c02d01e8e841206ad.1661358182.git.reinette.chatre@intel.com
arch/x86/kernel/cpu/resctrl/pseudo_lock.c

index db813f819ad6cb071290eac33dc3c6ff4bcc2059..4d8398986f78481edd10148fb0b820e0687ed1b2 100644 (file)
@@ -420,6 +420,7 @@ static int pseudo_lock_fn(void *_rdtgrp)
        struct pseudo_lock_region *plr = rdtgrp->plr;
        u32 rmid_p, closid_p;
        unsigned long i;
+       u64 saved_msr;
 #ifdef CONFIG_KASAN
        /*
         * The registers used for local register variables are also used
@@ -463,6 +464,7 @@ static int pseudo_lock_fn(void *_rdtgrp)
         * the buffer and evict pseudo-locked memory read earlier from the
         * cache.
         */
+       saved_msr = __rdmsr(MSR_MISC_FEATURE_CONTROL);
        __wrmsr(MSR_MISC_FEATURE_CONTROL, prefetch_disable_bits, 0x0);
        closid_p = this_cpu_read(pqr_state.cur_closid);
        rmid_p = this_cpu_read(pqr_state.cur_rmid);
@@ -514,7 +516,7 @@ static int pseudo_lock_fn(void *_rdtgrp)
        __wrmsr(IA32_PQR_ASSOC, rmid_p, closid_p);
 
        /* Re-enable the hardware prefetcher(s) */
-       wrmsr(MSR_MISC_FEATURE_CONTROL, 0x0, 0x0);
+       wrmsrl(MSR_MISC_FEATURE_CONTROL, saved_msr);
        local_irq_enable();
 
        plr->thread_done = 1;
@@ -871,6 +873,7 @@ bool rdtgroup_pseudo_locked_in_hierarchy(struct rdt_domain *d)
 static int measure_cycles_lat_fn(void *_plr)
 {
        struct pseudo_lock_region *plr = _plr;
+       u32 saved_low, saved_high;
        unsigned long i;
        u64 start, end;
        void *mem_r;
@@ -879,6 +882,7 @@ static int measure_cycles_lat_fn(void *_plr)
        /*
         * Disable hardware prefetchers.
         */
+       rdmsr(MSR_MISC_FEATURE_CONTROL, saved_low, saved_high);
        wrmsr(MSR_MISC_FEATURE_CONTROL, prefetch_disable_bits, 0x0);
        mem_r = READ_ONCE(plr->kmem);
        /*
@@ -895,7 +899,7 @@ static int measure_cycles_lat_fn(void *_plr)
                end = rdtsc_ordered();
                trace_pseudo_lock_mem_latency((u32)(end - start));
        }
-       wrmsr(MSR_MISC_FEATURE_CONTROL, 0x0, 0x0);
+       wrmsr(MSR_MISC_FEATURE_CONTROL, saved_low, saved_high);
        local_irq_enable();
        plr->thread_done = 1;
        wake_up_interruptible(&plr->lock_thread_wq);
@@ -940,6 +944,7 @@ static int measure_residency_fn(struct perf_event_attr *miss_attr,
        u64 hits_before = 0, hits_after = 0, miss_before = 0, miss_after = 0;
        struct perf_event *miss_event, *hit_event;
        int hit_pmcnum, miss_pmcnum;
+       u32 saved_low, saved_high;
        unsigned int line_size;
        unsigned int size;
        unsigned long i;
@@ -973,6 +978,7 @@ static int measure_residency_fn(struct perf_event_attr *miss_attr,
        /*
         * Disable hardware prefetchers.
         */
+       rdmsr(MSR_MISC_FEATURE_CONTROL, saved_low, saved_high);
        wrmsr(MSR_MISC_FEATURE_CONTROL, prefetch_disable_bits, 0x0);
 
        /* Initialize rest of local variables */
@@ -1031,7 +1037,7 @@ static int measure_residency_fn(struct perf_event_attr *miss_attr,
         */
        rmb();
        /* Re-enable hardware prefetchers */
-       wrmsr(MSR_MISC_FEATURE_CONTROL, 0x0, 0x0);
+       wrmsr(MSR_MISC_FEATURE_CONTROL, saved_low, saved_high);
        local_irq_enable();
 out_hit:
        perf_event_release_kernel(hit_event);