aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-02-25 19:58:55 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2018-02-25 19:58:55 -0500
commitc23a75759191e84f4ba15b85ea4f97bd544b5362 (patch)
tree14028b69a8120aa6a525eabbc4d364d3c13978e4
parente912bf2cf7cd893915adf388fc2b79f5d9bdfd44 (diff)
parent4596749339e06dc7a424fc08a15eded850ed78b7 (diff)
Merge branch 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 fixes from Thomas Gleixner: "A small set of fixes: - UAPI data type correction for hyperv - correct the cpu cores field in /proc/cpuinfo on CPU hotplug - return proper error code in the resctrl file system failure path to avoid silent subsequent failures - correct a subtle accounting issue in the new vector allocation code which went unnoticed for a while and caused suspend/resume failures" * 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86/topology: Update the 'cpu cores' field in /proc/cpuinfo correctly across CPU hotplug operations x86/topology: Fix function name in documentation x86/intel_rdt: Fix incorrect returned value when creating rdgroup sub-directory in resctrl file system x86/apic/vector: Handle vector release on CPU unplug correctly genirq/matrix: Handle CPU offlining proper x86/headers/UAPI: Use __u64 instead of u64 in <uapi/asm/hyperv.h>
-rw-r--r--Documentation/x86/topology.txt2
-rw-r--r--arch/x86/include/uapi/asm/hyperv.h18
-rw-r--r--arch/x86/kernel/apic/vector.c25
-rw-r--r--arch/x86/kernel/cpu/intel_rdt_rdtgroup.c1
-rw-r--r--arch/x86/kernel/smpboot.c1
-rw-r--r--kernel/irq/matrix.c23
6 files changed, 48 insertions, 22 deletions
diff --git a/Documentation/x86/topology.txt b/Documentation/x86/topology.txt
index f3e9d7e9ed6c..2953e3ec9a02 100644
--- a/Documentation/x86/topology.txt
+++ b/Documentation/x86/topology.txt
@@ -108,7 +108,7 @@ The topology of a system is described in the units of:
108 108
109 The number of online threads is also printed in /proc/cpuinfo "siblings." 109 The number of online threads is also printed in /proc/cpuinfo "siblings."
110 110
111 - topology_sibling_mask(): 111 - topology_sibling_cpumask():
112 112
113 The cpumask contains all online threads in the core to which a thread 113 The cpumask contains all online threads in the core to which a thread
114 belongs. 114 belongs.
diff --git a/arch/x86/include/uapi/asm/hyperv.h b/arch/x86/include/uapi/asm/hyperv.h
index 197c2e6c7376..099414345865 100644
--- a/arch/x86/include/uapi/asm/hyperv.h
+++ b/arch/x86/include/uapi/asm/hyperv.h
@@ -241,24 +241,24 @@
241#define HV_X64_MSR_REENLIGHTENMENT_CONTROL 0x40000106 241#define HV_X64_MSR_REENLIGHTENMENT_CONTROL 0x40000106
242 242
243struct hv_reenlightenment_control { 243struct hv_reenlightenment_control {
244 u64 vector:8; 244 __u64 vector:8;
245 u64 reserved1:8; 245 __u64 reserved1:8;
246 u64 enabled:1; 246 __u64 enabled:1;
247 u64 reserved2:15; 247 __u64 reserved2:15;
248 u64 target_vp:32; 248 __u64 target_vp:32;
249}; 249};
250 250
251#define HV_X64_MSR_TSC_EMULATION_CONTROL 0x40000107 251#define HV_X64_MSR_TSC_EMULATION_CONTROL 0x40000107
252#define HV_X64_MSR_TSC_EMULATION_STATUS 0x40000108 252#define HV_X64_MSR_TSC_EMULATION_STATUS 0x40000108
253 253
254struct hv_tsc_emulation_control { 254struct hv_tsc_emulation_control {
255 u64 enabled:1; 255 __u64 enabled:1;
256 u64 reserved:63; 256 __u64 reserved:63;
257}; 257};
258 258
259struct hv_tsc_emulation_status { 259struct hv_tsc_emulation_status {
260 u64 inprogress:1; 260 __u64 inprogress:1;
261 u64 reserved:63; 261 __u64 reserved:63;
262}; 262};
263 263
264#define HV_X64_MSR_HYPERCALL_ENABLE 0x00000001 264#define HV_X64_MSR_HYPERCALL_ENABLE 0x00000001
diff --git a/arch/x86/kernel/apic/vector.c b/arch/x86/kernel/apic/vector.c
index 3cc471beb50b..bb6f7a2148d7 100644
--- a/arch/x86/kernel/apic/vector.c
+++ b/arch/x86/kernel/apic/vector.c
@@ -134,21 +134,40 @@ static void apic_update_vector(struct irq_data *irqd, unsigned int newvec,
134{ 134{
135 struct apic_chip_data *apicd = apic_chip_data(irqd); 135 struct apic_chip_data *apicd = apic_chip_data(irqd);
136 struct irq_desc *desc = irq_data_to_desc(irqd); 136 struct irq_desc *desc = irq_data_to_desc(irqd);
137 bool managed = irqd_affinity_is_managed(irqd);
137 138
138 lockdep_assert_held(&vector_lock); 139 lockdep_assert_held(&vector_lock);
139 140
140 trace_vector_update(irqd->irq, newvec, newcpu, apicd->vector, 141 trace_vector_update(irqd->irq, newvec, newcpu, apicd->vector,
141 apicd->cpu); 142 apicd->cpu);
142 143
143 /* Setup the vector move, if required */ 144 /*
144 if (apicd->vector && cpu_online(apicd->cpu)) { 145 * If there is no vector associated or if the associated vector is
146 * the shutdown vector, which is associated to make PCI/MSI
147 * shutdown mode work, then there is nothing to release. Clear out
148 * prev_vector for this and the offlined target case.
149 */
150 apicd->prev_vector = 0;
151 if (!apicd->vector || apicd->vector == MANAGED_IRQ_SHUTDOWN_VECTOR)
152 goto setnew;
153 /*
154 * If the target CPU of the previous vector is online, then mark
155 * the vector as move in progress and store it for cleanup when the
156 * first interrupt on the new vector arrives. If the target CPU is
157 * offline then the regular release mechanism via the cleanup
158 * vector is not possible and the vector can be immediately freed
159 * in the underlying matrix allocator.
160 */
161 if (cpu_online(apicd->cpu)) {
145 apicd->move_in_progress = true; 162 apicd->move_in_progress = true;
146 apicd->prev_vector = apicd->vector; 163 apicd->prev_vector = apicd->vector;
147 apicd->prev_cpu = apicd->cpu; 164 apicd->prev_cpu = apicd->cpu;
148 } else { 165 } else {
149 apicd->prev_vector = 0; 166 irq_matrix_free(vector_matrix, apicd->cpu, apicd->vector,
167 managed);
150 } 168 }
151 169
170setnew:
152 apicd->vector = newvec; 171 apicd->vector = newvec;
153 apicd->cpu = newcpu; 172 apicd->cpu = newcpu;
154 BUG_ON(!IS_ERR_OR_NULL(per_cpu(vector_irq, newcpu)[newvec])); 173 BUG_ON(!IS_ERR_OR_NULL(per_cpu(vector_irq, newcpu)[newvec]));
diff --git a/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c b/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c
index bdab7d2f51af..fca759d272a1 100644
--- a/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c
+++ b/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c
@@ -1804,6 +1804,7 @@ static int rdtgroup_mkdir_ctrl_mon(struct kernfs_node *parent_kn,
1804 goto out_common_fail; 1804 goto out_common_fail;
1805 } 1805 }
1806 closid = ret; 1806 closid = ret;
1807 ret = 0;
1807 1808
1808 rdtgrp->closid = closid; 1809 rdtgrp->closid = closid;
1809 list_add(&rdtgrp->rdtgroup_list, &rdt_all_groups); 1810 list_add(&rdtgrp->rdtgroup_list, &rdt_all_groups);
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index 9eee25d07586..ff99e2b6fc54 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -1437,6 +1437,7 @@ static void remove_siblinginfo(int cpu)
1437 cpumask_clear(topology_sibling_cpumask(cpu)); 1437 cpumask_clear(topology_sibling_cpumask(cpu));
1438 cpumask_clear(topology_core_cpumask(cpu)); 1438 cpumask_clear(topology_core_cpumask(cpu));
1439 c->cpu_core_id = 0; 1439 c->cpu_core_id = 0;
1440 c->booted_cores = 0;
1440 cpumask_clear_cpu(cpu, cpu_sibling_setup_mask); 1441 cpumask_clear_cpu(cpu, cpu_sibling_setup_mask);
1441 recompute_smt_state(); 1442 recompute_smt_state();
1442} 1443}
diff --git a/kernel/irq/matrix.c b/kernel/irq/matrix.c
index 5187dfe809ac..4c5770407031 100644
--- a/kernel/irq/matrix.c
+++ b/kernel/irq/matrix.c
@@ -16,6 +16,7 @@ struct cpumap {
16 unsigned int available; 16 unsigned int available;
17 unsigned int allocated; 17 unsigned int allocated;
18 unsigned int managed; 18 unsigned int managed;
19 bool initialized;
19 bool online; 20 bool online;
20 unsigned long alloc_map[IRQ_MATRIX_SIZE]; 21 unsigned long alloc_map[IRQ_MATRIX_SIZE];
21 unsigned long managed_map[IRQ_MATRIX_SIZE]; 22 unsigned long managed_map[IRQ_MATRIX_SIZE];
@@ -81,9 +82,11 @@ void irq_matrix_online(struct irq_matrix *m)
81 82
82 BUG_ON(cm->online); 83 BUG_ON(cm->online);
83 84
84 bitmap_zero(cm->alloc_map, m->matrix_bits); 85 if (!cm->initialized) {
85 cm->available = m->alloc_size - (cm->managed + m->systembits_inalloc); 86 cm->available = m->alloc_size;
86 cm->allocated = 0; 87 cm->available -= cm->managed + m->systembits_inalloc;
88 cm->initialized = true;
89 }
87 m->global_available += cm->available; 90 m->global_available += cm->available;
88 cm->online = true; 91 cm->online = true;
89 m->online_maps++; 92 m->online_maps++;
@@ -370,14 +373,16 @@ void irq_matrix_free(struct irq_matrix *m, unsigned int cpu,
370 if (WARN_ON_ONCE(bit < m->alloc_start || bit >= m->alloc_end)) 373 if (WARN_ON_ONCE(bit < m->alloc_start || bit >= m->alloc_end))
371 return; 374 return;
372 375
373 if (cm->online) { 376 clear_bit(bit, cm->alloc_map);
374 clear_bit(bit, cm->alloc_map); 377 cm->allocated--;
375 cm->allocated--; 378
379 if (cm->online)
376 m->total_allocated--; 380 m->total_allocated--;
377 if (!managed) { 381
378 cm->available++; 382 if (!managed) {
383 cm->available++;
384 if (cm->online)
379 m->global_available++; 385 m->global_available++;
380 }
381 } 386 }
382 trace_irq_matrix_free(bit, cpu, m, cm); 387 trace_irq_matrix_free(bit, cpu, m, cm);
383} 388}