diff options
author | J. K. Cliburn <jcliburn@gmail.com> | 2011-01-01 05:02:12 +0000 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2011-02-17 14:46:37 -0800 |
commit | 4224f23c44f94e49eb0e01f38681c6a43112f93a (patch) | |
tree | 4516cd00b4e0e90e7a567b6fe3a976dc1a260a11 /drivers/net | |
parent | cdde102cd5271d9e3927667b2b1bee676b2ab125 (diff) |
atl1: fix oops when changing tx/rx ring params
commit 2f32c867219734b06abc980d4812f67b6d6fe517 upstream.
Commit 3f5a2a713aad28480d86b0add00c68484b54febc zeroes out the statistics
message block (SMB) and coalescing message block (CMB) when adapter ring
resources are freed. This is desirable behavior, but, as a side effect,
the commit leads to an oops when atl1_set_ringparam() attempts to alter
the number of rx or tx elements in the ring buffer (by using ethtool
-G, for example). We don't want SMB or CMB to change during this
operation.
Modify atl1_set_ringparam() to preserve SMB and CMB when changing ring
parameters.
Signed-off-by: Jay Cliburn <jcliburn@gmail.com>
Reported-by: Tõnu Raitviir <jussuf@linux.ee>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/atlx/atl1.c | 10 |
1 files changed, 10 insertions, 0 deletions
diff --git a/drivers/net/atlx/atl1.c b/drivers/net/atlx/atl1.c index c73be284831..67f75c17919 100644 --- a/drivers/net/atlx/atl1.c +++ b/drivers/net/atlx/atl1.c @@ -3503,6 +3503,8 @@ static int atl1_set_ringparam(struct net_device *netdev, struct atl1_rfd_ring rfd_old, rfd_new; struct atl1_rrd_ring rrd_old, rrd_new; struct atl1_ring_header rhdr_old, rhdr_new; + struct atl1_smb smb; + struct atl1_cmb cmb; int err; tpd_old = adapter->tpd_ring; @@ -3543,11 +3545,19 @@ static int atl1_set_ringparam(struct net_device *netdev, adapter->rrd_ring = rrd_old; adapter->tpd_ring = tpd_old; adapter->ring_header = rhdr_old; + /* + * Save SMB and CMB, since atl1_free_ring_resources + * will clear them. + */ + smb = adapter->smb; + cmb = adapter->cmb; atl1_free_ring_resources(adapter); adapter->rfd_ring = rfd_new; adapter->rrd_ring = rrd_new; adapter->tpd_ring = tpd_new; adapter->ring_header = rhdr_new; + adapter->smb = smb; + adapter->cmb = cmb; err = atl1_up(adapter); if (err) |