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>
This commit is contained in:
Linus Torvalds 2018-02-25 16:58:55 -08:00
commit c23a757591
6 changed files with 48 additions and 22 deletions

View File

@ -108,7 +108,7 @@ The topology of a system is described in the units of:
The number of online threads is also printed in /proc/cpuinfo "siblings." The number of online threads is also printed in /proc/cpuinfo "siblings."
- topology_sibling_mask(): - topology_sibling_cpumask():
The cpumask contains all online threads in the core to which a thread The cpumask contains all online threads in the core to which a thread
belongs. belongs.

View File

@ -241,24 +241,24 @@
#define HV_X64_MSR_REENLIGHTENMENT_CONTROL 0x40000106 #define HV_X64_MSR_REENLIGHTENMENT_CONTROL 0x40000106
struct hv_reenlightenment_control { struct hv_reenlightenment_control {
u64 vector:8; __u64 vector:8;
u64 reserved1:8; __u64 reserved1:8;
u64 enabled:1; __u64 enabled:1;
u64 reserved2:15; __u64 reserved2:15;
u64 target_vp:32; __u64 target_vp:32;
}; };
#define HV_X64_MSR_TSC_EMULATION_CONTROL 0x40000107 #define HV_X64_MSR_TSC_EMULATION_CONTROL 0x40000107
#define HV_X64_MSR_TSC_EMULATION_STATUS 0x40000108 #define HV_X64_MSR_TSC_EMULATION_STATUS 0x40000108
struct hv_tsc_emulation_control { struct hv_tsc_emulation_control {
u64 enabled:1; __u64 enabled:1;
u64 reserved:63; __u64 reserved:63;
}; };
struct hv_tsc_emulation_status { struct hv_tsc_emulation_status {
u64 inprogress:1; __u64 inprogress:1;
u64 reserved:63; __u64 reserved:63;
}; };
#define HV_X64_MSR_HYPERCALL_ENABLE 0x00000001 #define HV_X64_MSR_HYPERCALL_ENABLE 0x00000001

View File

@ -134,21 +134,40 @@ static void apic_update_vector(struct irq_data *irqd, unsigned int newvec,
{ {
struct apic_chip_data *apicd = apic_chip_data(irqd); struct apic_chip_data *apicd = apic_chip_data(irqd);
struct irq_desc *desc = irq_data_to_desc(irqd); struct irq_desc *desc = irq_data_to_desc(irqd);
bool managed = irqd_affinity_is_managed(irqd);
lockdep_assert_held(&vector_lock); lockdep_assert_held(&vector_lock);
trace_vector_update(irqd->irq, newvec, newcpu, apicd->vector, trace_vector_update(irqd->irq, newvec, newcpu, apicd->vector,
apicd->cpu); apicd->cpu);
/* Setup the vector move, if required */ /*
if (apicd->vector && cpu_online(apicd->cpu)) { * If there is no vector associated or if the associated vector is
* the shutdown vector, which is associated to make PCI/MSI
* shutdown mode work, then there is nothing to release. Clear out
* prev_vector for this and the offlined target case.
*/
apicd->prev_vector = 0;
if (!apicd->vector || apicd->vector == MANAGED_IRQ_SHUTDOWN_VECTOR)
goto setnew;
/*
* If the target CPU of the previous vector is online, then mark
* the vector as move in progress and store it for cleanup when the
* first interrupt on the new vector arrives. If the target CPU is
* offline then the regular release mechanism via the cleanup
* vector is not possible and the vector can be immediately freed
* in the underlying matrix allocator.
*/
if (cpu_online(apicd->cpu)) {
apicd->move_in_progress = true; apicd->move_in_progress = true;
apicd->prev_vector = apicd->vector; apicd->prev_vector = apicd->vector;
apicd->prev_cpu = apicd->cpu; apicd->prev_cpu = apicd->cpu;
} else { } else {
apicd->prev_vector = 0; irq_matrix_free(vector_matrix, apicd->cpu, apicd->vector,
managed);
} }
setnew:
apicd->vector = newvec; apicd->vector = newvec;
apicd->cpu = newcpu; apicd->cpu = newcpu;
BUG_ON(!IS_ERR_OR_NULL(per_cpu(vector_irq, newcpu)[newvec])); BUG_ON(!IS_ERR_OR_NULL(per_cpu(vector_irq, newcpu)[newvec]));

View File

@ -1804,6 +1804,7 @@ static int rdtgroup_mkdir_ctrl_mon(struct kernfs_node *parent_kn,
goto out_common_fail; goto out_common_fail;
} }
closid = ret; closid = ret;
ret = 0;
rdtgrp->closid = closid; rdtgrp->closid = closid;
list_add(&rdtgrp->rdtgroup_list, &rdt_all_groups); list_add(&rdtgrp->rdtgroup_list, &rdt_all_groups);

View File

@ -1437,6 +1437,7 @@ static void remove_siblinginfo(int cpu)
cpumask_clear(topology_sibling_cpumask(cpu)); cpumask_clear(topology_sibling_cpumask(cpu));
cpumask_clear(topology_core_cpumask(cpu)); cpumask_clear(topology_core_cpumask(cpu));
c->cpu_core_id = 0; c->cpu_core_id = 0;
c->booted_cores = 0;
cpumask_clear_cpu(cpu, cpu_sibling_setup_mask); cpumask_clear_cpu(cpu, cpu_sibling_setup_mask);
recompute_smt_state(); recompute_smt_state();
} }

View File

@ -16,6 +16,7 @@ struct cpumap {
unsigned int available; unsigned int available;
unsigned int allocated; unsigned int allocated;
unsigned int managed; unsigned int managed;
bool initialized;
bool online; bool online;
unsigned long alloc_map[IRQ_MATRIX_SIZE]; unsigned long alloc_map[IRQ_MATRIX_SIZE];
unsigned long managed_map[IRQ_MATRIX_SIZE]; unsigned long managed_map[IRQ_MATRIX_SIZE];
@ -81,9 +82,11 @@ void irq_matrix_online(struct irq_matrix *m)
BUG_ON(cm->online); BUG_ON(cm->online);
bitmap_zero(cm->alloc_map, m->matrix_bits); if (!cm->initialized) {
cm->available = m->alloc_size - (cm->managed + m->systembits_inalloc); cm->available = m->alloc_size;
cm->allocated = 0; cm->available -= cm->managed + m->systembits_inalloc;
cm->initialized = true;
}
m->global_available += cm->available; m->global_available += cm->available;
cm->online = true; cm->online = true;
m->online_maps++; m->online_maps++;
@ -370,14 +373,16 @@ void irq_matrix_free(struct irq_matrix *m, unsigned int cpu,
if (WARN_ON_ONCE(bit < m->alloc_start || bit >= m->alloc_end)) if (WARN_ON_ONCE(bit < m->alloc_start || bit >= m->alloc_end))
return; return;
if (cm->online) { clear_bit(bit, cm->alloc_map);
clear_bit(bit, cm->alloc_map); cm->allocated--;
cm->allocated--;
if (cm->online)
m->total_allocated--; m->total_allocated--;
if (!managed) {
cm->available++; if (!managed) {
cm->available++;
if (cm->online)
m->global_available++; m->global_available++;
}
} }
trace_irq_matrix_free(bit, cpu, m, cm); trace_irq_matrix_free(bit, cpu, m, cm);
} }