diff options
author | Jesse Brandeburg <jesse.brandeburg@intel.com> | 2009-09-25 08:19:02 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-09-26 23:15:47 -0400 |
commit | 3d6114e71dffb9fb9dedc8569103310c5bbf0296 (patch) | |
tree | 7fc265f766ef35cb6330e73680d83e6140fae30f /drivers/net/e1000 | |
parent | 8fce47317fc96b222ea7e28fb6d153b1855e91cd (diff) |
e1000: remove races when changing mtu
this patch fixes a bug that occurs when routing packets and simultaneously
changing the mtu. the rx_buffer_len variable is used during the rx cleanup
and if that changes on the fly without stopping traffic bad things happen
Signed-off-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
Signed-off-by: Don Skidmore <donald.c.skidmore@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/e1000')
-rw-r--r-- | drivers/net/e1000/e1000_main.c | 16 |
1 files changed, 14 insertions, 2 deletions
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index cdbf4fb8150d..2178e0d39c01 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c | |||
@@ -3141,6 +3141,13 @@ static int e1000_change_mtu(struct net_device *netdev, int new_mtu) | |||
3141 | break; | 3141 | break; |
3142 | } | 3142 | } |
3143 | 3143 | ||
3144 | while (test_and_set_bit(__E1000_RESETTING, &adapter->flags)) | ||
3145 | msleep(1); | ||
3146 | /* e1000_down has a dependency on max_frame_size */ | ||
3147 | hw->max_frame_size = max_frame; | ||
3148 | if (netif_running(netdev)) | ||
3149 | e1000_down(adapter); | ||
3150 | |||
3144 | /* NOTE: netdev_alloc_skb reserves 16 bytes, and typically NET_IP_ALIGN | 3151 | /* NOTE: netdev_alloc_skb reserves 16 bytes, and typically NET_IP_ALIGN |
3145 | * means we reserve 2 more, this pushes us to allocate from the next | 3152 | * means we reserve 2 more, this pushes us to allocate from the next |
3146 | * larger slab size. | 3153 | * larger slab size. |
@@ -3169,11 +3176,16 @@ static int e1000_change_mtu(struct net_device *netdev, int new_mtu) | |||
3169 | (max_frame == MAXIMUM_ETHERNET_VLAN_SIZE))) | 3176 | (max_frame == MAXIMUM_ETHERNET_VLAN_SIZE))) |
3170 | adapter->rx_buffer_len = MAXIMUM_ETHERNET_VLAN_SIZE; | 3177 | adapter->rx_buffer_len = MAXIMUM_ETHERNET_VLAN_SIZE; |
3171 | 3178 | ||
3179 | printk(KERN_INFO "e1000: %s changing MTU from %d to %d\n", | ||
3180 | netdev->name, netdev->mtu, new_mtu); | ||
3172 | netdev->mtu = new_mtu; | 3181 | netdev->mtu = new_mtu; |
3173 | hw->max_frame_size = max_frame; | ||
3174 | 3182 | ||
3175 | if (netif_running(netdev)) | 3183 | if (netif_running(netdev)) |
3176 | e1000_reinit_locked(adapter); | 3184 | e1000_up(adapter); |
3185 | else | ||
3186 | e1000_reset(adapter); | ||
3187 | |||
3188 | clear_bit(__E1000_RESETTING, &adapter->flags); | ||
3177 | 3189 | ||
3178 | return 0; | 3190 | return 0; |
3179 | } | 3191 | } |