aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDexuan Cui <decui@microsoft.com>2017-11-01 16:30:53 -0400
committerBjorn Helgaas <bhelgaas@google.com>2017-11-07 19:06:39 -0500
commit79aa801e899417a56863d6713f76c4e108856000 (patch)
tree81d0d0c303ed08d1c7976e943e94f3de55c35824
parent9e66317d3c92ddaab330c125dfe9d06eee268aff (diff)
PCI: hv: Use effective affinity mask
The effective_affinity_mask is always set when an interrupt is assigned in __assign_irq_vector() -> apic->cpu_mask_to_apicid(), e.g. for struct apic apic_physflat: -> default_cpu_mask_to_apicid() -> irq_data_update_effective_affinity(), but it looks d->common->affinity remains all-1's before the user space or the kernel changes it later. In the early allocation/initialization phase of an IRQ, we should use the effective_affinity_mask, otherwise Hyper-V may not deliver the interrupt to the expected CPU. Without the patch, if we assign 7 Mellanox ConnectX-3 VFs to a 32-vCPU VM, one of the VFs may fail to receive interrupts. Tested-by: Adrian Suhov <v-adsuho@microsoft.com> Signed-off-by: Dexuan Cui <decui@microsoft.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Reviewed-by: Jake Oshins <jakeo@microsoft.com> Cc: stable@vger.kernel.org Cc: Jork Loeser <jloeser@microsoft.com> Cc: Stephen Hemminger <sthemmin@microsoft.com> Cc: K. Y. Srinivasan <kys@microsoft.com>
-rw-r--r--drivers/pci/host/pci-hyperv.c8
1 files changed, 5 insertions, 3 deletions
diff --git a/drivers/pci/host/pci-hyperv.c b/drivers/pci/host/pci-hyperv.c
index 0fe3ea164ee5..04dac6a42c9f 100644
--- a/drivers/pci/host/pci-hyperv.c
+++ b/drivers/pci/host/pci-hyperv.c
@@ -879,7 +879,7 @@ static void hv_irq_unmask(struct irq_data *data)
879 int cpu; 879 int cpu;
880 u64 res; 880 u64 res;
881 881
882 dest = irq_data_get_affinity_mask(data); 882 dest = irq_data_get_effective_affinity_mask(data);
883 pdev = msi_desc_to_pci_dev(msi_desc); 883 pdev = msi_desc_to_pci_dev(msi_desc);
884 pbus = pdev->bus; 884 pbus = pdev->bus;
885 hbus = container_of(pbus->sysdata, struct hv_pcibus_device, sysdata); 885 hbus = container_of(pbus->sysdata, struct hv_pcibus_device, sysdata);
@@ -1042,6 +1042,7 @@ static void hv_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
1042 struct hv_pci_dev *hpdev; 1042 struct hv_pci_dev *hpdev;
1043 struct pci_bus *pbus; 1043 struct pci_bus *pbus;
1044 struct pci_dev *pdev; 1044 struct pci_dev *pdev;
1045 struct cpumask *dest;
1045 struct compose_comp_ctxt comp; 1046 struct compose_comp_ctxt comp;
1046 struct tran_int_desc *int_desc; 1047 struct tran_int_desc *int_desc;
1047 struct { 1048 struct {
@@ -1056,6 +1057,7 @@ static void hv_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
1056 int ret; 1057 int ret;
1057 1058
1058 pdev = msi_desc_to_pci_dev(irq_data_get_msi_desc(data)); 1059 pdev = msi_desc_to_pci_dev(irq_data_get_msi_desc(data));
1060 dest = irq_data_get_effective_affinity_mask(data);
1059 pbus = pdev->bus; 1061 pbus = pdev->bus;
1060 hbus = container_of(pbus->sysdata, struct hv_pcibus_device, sysdata); 1062 hbus = container_of(pbus->sysdata, struct hv_pcibus_device, sysdata);
1061 hpdev = get_pcichild_wslot(hbus, devfn_to_wslot(pdev->devfn)); 1063 hpdev = get_pcichild_wslot(hbus, devfn_to_wslot(pdev->devfn));
@@ -1081,14 +1083,14 @@ static void hv_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
1081 switch (pci_protocol_version) { 1083 switch (pci_protocol_version) {
1082 case PCI_PROTOCOL_VERSION_1_1: 1084 case PCI_PROTOCOL_VERSION_1_1:
1083 size = hv_compose_msi_req_v1(&ctxt.int_pkts.v1, 1085 size = hv_compose_msi_req_v1(&ctxt.int_pkts.v1,
1084 irq_data_get_affinity_mask(data), 1086 dest,
1085 hpdev->desc.win_slot.slot, 1087 hpdev->desc.win_slot.slot,
1086 cfg->vector); 1088 cfg->vector);
1087 break; 1089 break;
1088 1090
1089 case PCI_PROTOCOL_VERSION_1_2: 1091 case PCI_PROTOCOL_VERSION_1_2:
1090 size = hv_compose_msi_req_v2(&ctxt.int_pkts.v2, 1092 size = hv_compose_msi_req_v2(&ctxt.int_pkts.v2,
1091 irq_data_get_affinity_mask(data), 1093 dest,
1092 hpdev->desc.win_slot.slot, 1094 hpdev->desc.win_slot.slot,
1093 cfg->vector); 1095 cfg->vector);
1094 break; 1096 break;