aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorPeter P Waskiewicz Jr <peter.p.waskiewicz.jr@intel.com>2008-12-26 04:36:33 -0500
committerDavid S. Miller <davem@davemloft.net>2008-12-26 04:36:33 -0500
commitd3fa4721456226d77475181a4bfbe5b3d899d65c (patch)
treea602610942cadbe5e44aa7549d0622bdb47730bf /drivers/net
parent7adf1525befb5606462431eb1a4ea40ded5baef4 (diff)
ixgbe: Fix set_ringparam in ixgbe to use the same memory pools.
The adapter rings are kcalloc()'d, but in set_ringparam() in ixgbe_ethtool, we replace that memory from the vmalloc() pool. This can result in a NULL pointer reference when trying to modify the rings at a later time, or on device removal. Signed-off-by: Peter P Waskiewicz Jr <peter.p.waskiewicz.jr@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/ixgbe/ixgbe_ethtool.c64
1 files changed, 30 insertions, 34 deletions
diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c
index 849c1fe28207..67f87a79154d 100644
--- a/drivers/net/ixgbe/ixgbe_ethtool.c
+++ b/drivers/net/ixgbe/ixgbe_ethtool.c
@@ -712,30 +712,15 @@ static int ixgbe_set_ringparam(struct net_device *netdev,
712 return 0; 712 return 0;
713 } 713 }
714 714
715 if (adapter->num_tx_queues > adapter->num_rx_queues) 715 temp_ring = kcalloc(adapter->num_tx_queues,
716 temp_ring = vmalloc(adapter->num_tx_queues * 716 sizeof(struct ixgbe_ring), GFP_KERNEL);
717 sizeof(struct ixgbe_ring));
718 else
719 temp_ring = vmalloc(adapter->num_rx_queues *
720 sizeof(struct ixgbe_ring));
721 if (!temp_ring) 717 if (!temp_ring)
722 return -ENOMEM; 718 return -ENOMEM;
723 719
724 while (test_and_set_bit(__IXGBE_RESETTING, &adapter->state)) 720 while (test_and_set_bit(__IXGBE_RESETTING, &adapter->state))
725 msleep(1); 721 msleep(1);
726 722
727 if (netif_running(netdev))
728 ixgbe_down(adapter);
729
730 /*
731 * We can't just free everything and then setup again,
732 * because the ISRs in MSI-X mode get passed pointers
733 * to the tx and rx ring structs.
734 */
735 if (new_tx_count != adapter->tx_ring->count) { 723 if (new_tx_count != adapter->tx_ring->count) {
736 memcpy(temp_ring, adapter->tx_ring,
737 adapter->num_tx_queues * sizeof(struct ixgbe_ring));
738
739 for (i = 0; i < adapter->num_tx_queues; i++) { 724 for (i = 0; i < adapter->num_tx_queues; i++) {
740 temp_ring[i].count = new_tx_count; 725 temp_ring[i].count = new_tx_count;
741 err = ixgbe_setup_tx_resources(adapter, &temp_ring[i]); 726 err = ixgbe_setup_tx_resources(adapter, &temp_ring[i]);
@@ -747,21 +732,28 @@ static int ixgbe_set_ringparam(struct net_device *netdev,
747 } 732 }
748 goto err_setup; 733 goto err_setup;
749 } 734 }
735 temp_ring[i].v_idx = adapter->tx_ring[i].v_idx;
750 } 736 }
751 737 if (netif_running(netdev))
752 for (i = 0; i < adapter->num_tx_queues; i++) 738 netdev->netdev_ops->ndo_stop(netdev);
753 ixgbe_free_tx_resources(adapter, &adapter->tx_ring[i]); 739 ixgbe_reset_interrupt_capability(adapter);
754 740 ixgbe_napi_del_all(adapter);
755 memcpy(adapter->tx_ring, temp_ring, 741 INIT_LIST_HEAD(&netdev->napi_list);
756 adapter->num_tx_queues * sizeof(struct ixgbe_ring)); 742 kfree(adapter->tx_ring);
757 743 adapter->tx_ring = temp_ring;
744 temp_ring = NULL;
758 adapter->tx_ring_count = new_tx_count; 745 adapter->tx_ring_count = new_tx_count;
759 } 746 }
760 747
761 if (new_rx_count != adapter->rx_ring->count) { 748 temp_ring = kcalloc(adapter->num_rx_queues,
762 memcpy(temp_ring, adapter->rx_ring, 749 sizeof(struct ixgbe_ring), GFP_KERNEL);
763 adapter->num_rx_queues * sizeof(struct ixgbe_ring)); 750 if (!temp_ring) {
751 if (netif_running(netdev))
752 netdev->netdev_ops->ndo_open(netdev);
753 return -ENOMEM;
754 }
764 755
756 if (new_rx_count != adapter->rx_ring->count) {
765 for (i = 0; i < adapter->num_rx_queues; i++) { 757 for (i = 0; i < adapter->num_rx_queues; i++) {
766 temp_ring[i].count = new_rx_count; 758 temp_ring[i].count = new_rx_count;
767 err = ixgbe_setup_rx_resources(adapter, &temp_ring[i]); 759 err = ixgbe_setup_rx_resources(adapter, &temp_ring[i]);
@@ -773,13 +765,16 @@ static int ixgbe_set_ringparam(struct net_device *netdev,
773 } 765 }
774 goto err_setup; 766 goto err_setup;
775 } 767 }
768 temp_ring[i].v_idx = adapter->rx_ring[i].v_idx;
776 } 769 }
777 770 if (netif_running(netdev))
778 for (i = 0; i < adapter->num_rx_queues; i++) 771 netdev->netdev_ops->ndo_stop(netdev);
779 ixgbe_free_rx_resources(adapter, &adapter->rx_ring[i]); 772 ixgbe_reset_interrupt_capability(adapter);
780 773 ixgbe_napi_del_all(adapter);
781 memcpy(adapter->rx_ring, temp_ring, 774 INIT_LIST_HEAD(&netdev->napi_list);
782 adapter->num_rx_queues * sizeof(struct ixgbe_ring)); 775 kfree(adapter->rx_ring);
776 adapter->rx_ring = temp_ring;
777 temp_ring = NULL;
783 778
784 adapter->rx_ring_count = new_rx_count; 779 adapter->rx_ring_count = new_rx_count;
785 } 780 }
@@ -787,8 +782,9 @@ static int ixgbe_set_ringparam(struct net_device *netdev,
787 /* success! */ 782 /* success! */
788 err = 0; 783 err = 0;
789err_setup: 784err_setup:
785 ixgbe_init_interrupt_scheme(adapter);
790 if (netif_running(netdev)) 786 if (netif_running(netdev))
791 ixgbe_up(adapter); 787 netdev->netdev_ops->ndo_open(netdev);
792 788
793 clear_bit(__IXGBE_RESETTING, &adapter->state); 789 clear_bit(__IXGBE_RESETTING, &adapter->state);
794 return err; 790 return err;