Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7e9c2629 authored by Casey Leedom's avatar Casey Leedom Committed by David S. Miller
Browse files

cxgb4vf: Quiesce Virtual Interfaces on shutdown ...



When a Virtual Machine is rebooted, KVM currently fails to issue a Function
Level Reset against any "Attached PCI Devices" (AKA "PCI Passthrough").  In
addition to leaving the attached device in a random state in the next booted
kernel (which sort of violates the entire idea of a reboot reseting hardware
state), this leaves our peer thinking that the link is still up.  (Note that
a bug has been filed with the KVM folks, #25332, but there's been no
response on that as of yet.)  So, we add a "->shutdown()" method for the
Virtual Function PCI Device to handle administrative shutdowns like a
reboot.

Signed-off-by: default avatarCasey Leedom <leedom@chelsio.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 843635e0
Loading
Loading
Loading
Loading
+41 −0
Original line number Diff line number Diff line
@@ -2861,6 +2861,46 @@ static void __devexit cxgb4vf_pci_remove(struct pci_dev *pdev)
	pci_release_regions(pdev);
}

/*
 * "Shutdown" quiesce the device, stopping Ingress Packet and Interrupt
 * delivery.
 */
static void __devexit cxgb4vf_pci_shutdown(struct pci_dev *pdev)
{
	struct adapter *adapter;
	int pidx;

	adapter = pci_get_drvdata(pdev);
	if (!adapter)
		return;

	/*
	 * Disable all Virtual Interfaces.  This will shut down the
	 * delivery of all ingress packets into the chip for these
	 * Virtual Interfaces.
	 */
	for_each_port(adapter, pidx) {
		struct net_device *netdev;
		struct port_info *pi;

		if (!test_bit(pidx, &adapter->registered_device_map))
			continue;

		netdev = adapter->port[pidx];
		if (!netdev)
			continue;

		pi = netdev_priv(netdev);
		t4vf_enable_vi(adapter, pi->viid, false, false);
	}

	/*
	 * Free up all Queues which will prevent further DMA and
	 * Interrupts allowing various internal pathways to drain.
	 */
	t4vf_free_sge_resources(adapter);
}

/*
 * PCI Device registration data structures.
 */
@@ -2894,6 +2934,7 @@ static struct pci_driver cxgb4vf_driver = {
	.id_table	= cxgb4vf_pci_tbl,
	.probe		= cxgb4vf_pci_probe,
	.remove		= __devexit_p(cxgb4vf_pci_remove),
	.shutdown	= __devexit_p(cxgb4vf_pci_shutdown),
};

/*