aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjorn Helgaas <bhelgaas@google.com>2018-04-04 14:28:50 -0400
committerBjorn Helgaas <helgaas@kernel.org>2018-04-04 14:28:50 -0400
commit84d4d6f882175e02ab630fd444987e1e1b12e90a (patch)
tree2714371e6e49a1dbc97ac3fe0bbe9154e9522693
parent74716ff7abb483111eb44104b05799226e69b4b3 (diff)
parent948373b3ed1bcf05a237c24675b84804315aff14 (diff)
Merge branch 'lorenzo/pci/hv'
* lorenzo/pci/hv: PCI: hv: Only queue new work items in hv_pci_devices_present() if necessary PCI: hv: Remove the bogus test in hv_eject_device_work() PCI: hv: Fix a comment typo in _hv_pcifront_read_config() PCI: hv: Fix 2 hang issues in hv_compose_msi_msg() PCI: hv: Serialize the present and eject work items
-rw-r--r--drivers/pci/host/pci-hyperv.c112
1 files changed, 87 insertions, 25 deletions
diff --git a/drivers/pci/host/pci-hyperv.c b/drivers/pci/host/pci-hyperv.c
index 2faf38eab785..50cdefe3f6d3 100644
--- a/drivers/pci/host/pci-hyperv.c
+++ b/drivers/pci/host/pci-hyperv.c
@@ -447,7 +447,6 @@ struct hv_pcibus_device {
447 spinlock_t device_list_lock; /* Protect lists below */ 447 spinlock_t device_list_lock; /* Protect lists below */
448 void __iomem *cfg_addr; 448 void __iomem *cfg_addr;
449 449
450 struct semaphore enum_sem;
451 struct list_head resources_for_children; 450 struct list_head resources_for_children;
452 451
453 struct list_head children; 452 struct list_head children;
@@ -461,6 +460,8 @@ struct hv_pcibus_device {
461 struct retarget_msi_interrupt retarget_msi_interrupt_params; 460 struct retarget_msi_interrupt retarget_msi_interrupt_params;
462 461
463 spinlock_t retarget_msi_interrupt_lock; 462 spinlock_t retarget_msi_interrupt_lock;
463
464 struct workqueue_struct *wq;
464}; 465};
465 466
466/* 467/*
@@ -520,6 +521,8 @@ struct hv_pci_compl {
520 s32 completion_status; 521 s32 completion_status;
521}; 522};
522 523
524static void hv_pci_onchannelcallback(void *context);
525
523/** 526/**
524 * hv_pci_generic_compl() - Invoked for a completion packet 527 * hv_pci_generic_compl() - Invoked for a completion packet
525 * @context: Set up by the sender of the packet. 528 * @context: Set up by the sender of the packet.
@@ -653,7 +656,7 @@ static void _hv_pcifront_read_config(struct hv_pci_dev *hpdev, int where,
653 break; 656 break;
654 } 657 }
655 /* 658 /*
656 * Make sure the write was done before we release the spinlock 659 * Make sure the read was done before we release the spinlock
657 * allowing consecutive reads/writes. 660 * allowing consecutive reads/writes.
658 */ 661 */
659 mb(); 662 mb();
@@ -664,6 +667,31 @@ static void _hv_pcifront_read_config(struct hv_pci_dev *hpdev, int where,
664 } 667 }
665} 668}
666 669
670static u16 hv_pcifront_get_vendor_id(struct hv_pci_dev *hpdev)
671{
672 u16 ret;
673 unsigned long flags;
674 void __iomem *addr = hpdev->hbus->cfg_addr + CFG_PAGE_OFFSET +
675 PCI_VENDOR_ID;
676
677 spin_lock_irqsave(&hpdev->hbus->config_lock, flags);
678
679 /* Choose the function to be read. (See comment above) */
680 writel(hpdev->desc.win_slot.slot, hpdev->hbus->cfg_addr);
681 /* Make sure the function was chosen before we start reading. */
682 mb();
683 /* Read from that function's config space. */
684 ret = readw(addr);
685 /*
686 * mb() is not required here, because the spin_unlock_irqrestore()
687 * is a barrier.
688 */
689
690 spin_unlock_irqrestore(&hpdev->hbus->config_lock, flags);
691
692 return ret;
693}
694
667/** 695/**
668 * _hv_pcifront_write_config() - Internal PCI config write 696 * _hv_pcifront_write_config() - Internal PCI config write
669 * @hpdev: The PCI driver's representation of the device 697 * @hpdev: The PCI driver's representation of the device
@@ -1106,8 +1134,37 @@ static void hv_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
1106 * Since this function is called with IRQ locks held, can't 1134 * Since this function is called with IRQ locks held, can't
1107 * do normal wait for completion; instead poll. 1135 * do normal wait for completion; instead poll.
1108 */ 1136 */
1109 while (!try_wait_for_completion(&comp.comp_pkt.host_event)) 1137 while (!try_wait_for_completion(&comp.comp_pkt.host_event)) {
1138 /* 0xFFFF means an invalid PCI VENDOR ID. */
1139 if (hv_pcifront_get_vendor_id(hpdev) == 0xFFFF) {
1140 dev_err_once(&hbus->hdev->device,
1141 "the device has gone\n");
1142 goto free_int_desc;
1143 }
1144
1145 /*
1146 * When the higher level interrupt code calls us with
1147 * interrupt disabled, we must poll the channel by calling
1148 * the channel callback directly when channel->target_cpu is
1149 * the current CPU. When the higher level interrupt code
1150 * calls us with interrupt enabled, let's add the
1151 * local_bh_disable()/enable() to avoid race.
1152 */
1153 local_bh_disable();
1154
1155 if (hbus->hdev->channel->target_cpu == smp_processor_id())
1156 hv_pci_onchannelcallback(hbus);
1157
1158 local_bh_enable();
1159
1160 if (hpdev->state == hv_pcichild_ejecting) {
1161 dev_err_once(&hbus->hdev->device,
1162 "the device is being ejected\n");
1163 goto free_int_desc;
1164 }
1165
1110 udelay(100); 1166 udelay(100);
1167 }
1111 1168
1112 if (comp.comp_pkt.completion_status < 0) { 1169 if (comp.comp_pkt.completion_status < 0) {
1113 dev_err(&hbus->hdev->device, 1170 dev_err(&hbus->hdev->device,
@@ -1590,12 +1647,8 @@ static struct hv_pci_dev *get_pcichild_wslot(struct hv_pcibus_device *hbus,
1590 * It must also treat the omission of a previously observed device as 1647 * It must also treat the omission of a previously observed device as
1591 * notification that the device no longer exists. 1648 * notification that the device no longer exists.
1592 * 1649 *
1593 * Note that this function is a work item, and it may not be 1650 * Note that this function is serialized with hv_eject_device_work(),
1594 * invoked in the order that it was queued. Back to back 1651 * because both are pushed to the ordered workqueue hbus->wq.
1595 * updates of the list of present devices may involve queuing
1596 * multiple work items, and this one may run before ones that
1597 * were sent later. As such, this function only does something
1598 * if is the last one in the queue.
1599 */ 1652 */
1600static void pci_devices_present_work(struct work_struct *work) 1653static void pci_devices_present_work(struct work_struct *work)
1601{ 1654{
@@ -1616,11 +1669,6 @@ static void pci_devices_present_work(struct work_struct *work)
1616 1669
1617 INIT_LIST_HEAD(&removed); 1670 INIT_LIST_HEAD(&removed);
1618 1671
1619 if (down_interruptible(&hbus->enum_sem)) {
1620 put_hvpcibus(hbus);
1621 return;
1622 }
1623
1624 /* Pull this off the queue and process it if it was the last one. */ 1672 /* Pull this off the queue and process it if it was the last one. */
1625 spin_lock_irqsave(&hbus->device_list_lock, flags); 1673 spin_lock_irqsave(&hbus->device_list_lock, flags);
1626 while (!list_empty(&hbus->dr_list)) { 1674 while (!list_empty(&hbus->dr_list)) {
@@ -1637,7 +1685,6 @@ static void pci_devices_present_work(struct work_struct *work)
1637 spin_unlock_irqrestore(&hbus->device_list_lock, flags); 1685 spin_unlock_irqrestore(&hbus->device_list_lock, flags);
1638 1686
1639 if (!dr) { 1687 if (!dr) {
1640 up(&hbus->enum_sem);
1641 put_hvpcibus(hbus); 1688 put_hvpcibus(hbus);
1642 return; 1689 return;
1643 } 1690 }
@@ -1724,7 +1771,6 @@ static void pci_devices_present_work(struct work_struct *work)
1724 break; 1771 break;
1725 } 1772 }
1726 1773
1727 up(&hbus->enum_sem);
1728 put_hvpcibus(hbus); 1774 put_hvpcibus(hbus);
1729 kfree(dr); 1775 kfree(dr);
1730} 1776}
@@ -1743,6 +1789,7 @@ static void hv_pci_devices_present(struct hv_pcibus_device *hbus,
1743 struct hv_dr_state *dr; 1789 struct hv_dr_state *dr;
1744 struct hv_dr_work *dr_wrk; 1790 struct hv_dr_work *dr_wrk;
1745 unsigned long flags; 1791 unsigned long flags;
1792 bool pending_dr;
1746 1793
1747 dr_wrk = kzalloc(sizeof(*dr_wrk), GFP_NOWAIT); 1794 dr_wrk = kzalloc(sizeof(*dr_wrk), GFP_NOWAIT);
1748 if (!dr_wrk) 1795 if (!dr_wrk)
@@ -1766,11 +1813,21 @@ static void hv_pci_devices_present(struct hv_pcibus_device *hbus,
1766 } 1813 }
1767 1814
1768 spin_lock_irqsave(&hbus->device_list_lock, flags); 1815 spin_lock_irqsave(&hbus->device_list_lock, flags);
1816 /*
1817 * If pending_dr is true, we have already queued a work,
1818 * which will see the new dr. Otherwise, we need to
1819 * queue a new work.
1820 */
1821 pending_dr = !list_empty(&hbus->dr_list);
1769 list_add_tail(&dr->list_entry, &hbus->dr_list); 1822 list_add_tail(&dr->list_entry, &hbus->dr_list);
1770 spin_unlock_irqrestore(&hbus->device_list_lock, flags); 1823 spin_unlock_irqrestore(&hbus->device_list_lock, flags);
1771 1824
1772 get_hvpcibus(hbus); 1825 if (pending_dr) {
1773 schedule_work(&dr_wrk->wrk); 1826 kfree(dr_wrk);
1827 } else {
1828 get_hvpcibus(hbus);
1829 queue_work(hbus->wq, &dr_wrk->wrk);
1830 }
1774} 1831}
1775 1832
1776/** 1833/**
@@ -1796,10 +1853,7 @@ static void hv_eject_device_work(struct work_struct *work)
1796 1853
1797 hpdev = container_of(work, struct hv_pci_dev, wrk); 1854 hpdev = container_of(work, struct hv_pci_dev, wrk);
1798 1855
1799 if (hpdev->state != hv_pcichild_ejecting) { 1856 WARN_ON(hpdev->state != hv_pcichild_ejecting);
1800 put_pcichild(hpdev, hv_pcidev_ref_pnp);
1801 return;
1802 }
1803 1857
1804 /* 1858 /*
1805 * Ejection can come before or after the PCI bus has been set up, so 1859 * Ejection can come before or after the PCI bus has been set up, so
@@ -1848,7 +1902,7 @@ static void hv_pci_eject_device(struct hv_pci_dev *hpdev)
1848 get_pcichild(hpdev, hv_pcidev_ref_pnp); 1902 get_pcichild(hpdev, hv_pcidev_ref_pnp);
1849 INIT_WORK(&hpdev->wrk, hv_eject_device_work); 1903 INIT_WORK(&hpdev->wrk, hv_eject_device_work);
1850 get_hvpcibus(hpdev->hbus); 1904 get_hvpcibus(hpdev->hbus);
1851 schedule_work(&hpdev->wrk); 1905 queue_work(hpdev->hbus->wq, &hpdev->wrk);
1852} 1906}
1853 1907
1854/** 1908/**
@@ -2461,13 +2515,18 @@ static int hv_pci_probe(struct hv_device *hdev,
2461 spin_lock_init(&hbus->config_lock); 2515 spin_lock_init(&hbus->config_lock);
2462 spin_lock_init(&hbus->device_list_lock); 2516 spin_lock_init(&hbus->device_list_lock);
2463 spin_lock_init(&hbus->retarget_msi_interrupt_lock); 2517 spin_lock_init(&hbus->retarget_msi_interrupt_lock);
2464 sema_init(&hbus->enum_sem, 1);
2465 init_completion(&hbus->remove_event); 2518 init_completion(&hbus->remove_event);
2519 hbus->wq = alloc_ordered_workqueue("hv_pci_%x", 0,
2520 hbus->sysdata.domain);
2521 if (!hbus->wq) {
2522 ret = -ENOMEM;
2523 goto free_bus;
2524 }
2466 2525
2467 ret = vmbus_open(hdev->channel, pci_ring_size, pci_ring_size, NULL, 0, 2526 ret = vmbus_open(hdev->channel, pci_ring_size, pci_ring_size, NULL, 0,
2468 hv_pci_onchannelcallback, hbus); 2527 hv_pci_onchannelcallback, hbus);
2469 if (ret) 2528 if (ret)
2470 goto free_bus; 2529 goto destroy_wq;
2471 2530
2472 hv_set_drvdata(hdev, hbus); 2531 hv_set_drvdata(hdev, hbus);
2473 2532
@@ -2536,6 +2595,8 @@ free_config:
2536 hv_free_config_window(hbus); 2595 hv_free_config_window(hbus);
2537close: 2596close:
2538 vmbus_close(hdev->channel); 2597 vmbus_close(hdev->channel);
2598destroy_wq:
2599 destroy_workqueue(hbus->wq);
2539free_bus: 2600free_bus:
2540 free_page((unsigned long)hbus); 2601 free_page((unsigned long)hbus);
2541 return ret; 2602 return ret;
@@ -2615,6 +2676,7 @@ static int hv_pci_remove(struct hv_device *hdev)
2615 irq_domain_free_fwnode(hbus->sysdata.fwnode); 2676 irq_domain_free_fwnode(hbus->sysdata.fwnode);
2616 put_hvpcibus(hbus); 2677 put_hvpcibus(hbus);
2617 wait_for_completion(&hbus->remove_event); 2678 wait_for_completion(&hbus->remove_event);
2679 destroy_workqueue(hbus->wq);
2618 free_page((unsigned long)hbus); 2680 free_page((unsigned long)hbus);
2619 return 0; 2681 return 0;
2620} 2682}