diff options
author | Roland Dreier <roland@purestorage.com> | 2012-04-30 03:15:47 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-04-30 22:08:44 -0400 |
commit | 60158e64641fd8c780a6d14de2bf42aabc419916 (patch) | |
tree | f05b7418b2d9df38f65aa39169b88d9fe57e13b7 /drivers/net/ethernet | |
parent | 787cb2a9ebc6148e95b164a2821bb4045de1c7f5 (diff) |
cxgb3: Don't call cxgb_vlan_mode until q locks are initialized
The driver calls cxgb_vlan_mode() from init_one(). This calls into
synchronize_rx(), which locks all the q locks, but the q locks are not
initialized until cxgb_up() -> setup_sge_qsets(). So move the call to
cxgb_vlan_mode() into cxgb_up(), after the call to setup_sge_qsets().
We also move the body of these functions up higher to avoid having to
a forward declaration.
This was found because of the lockdep warning:
INFO: trying to register non-static key.
the code is fine but needs lockdep annotation.
turning off the locking correctness validator.
Pid: 323, comm: work_for_cpu Not tainted 3.4.0-rc5 #28
Call Trace:
[<ffffffff8106e767>] register_lock_class+0x108/0x2d0
[<ffffffff8106ff42>] __lock_acquire+0xd3/0xd06
[<ffffffff81070fd0>] lock_acquire+0xbf/0xfe
[<ffffffff813862a6>] _raw_spin_lock_irq+0x36/0x45
[<ffffffffa01e71aa>] cxgb_vlan_mode+0x96/0xcb [cxgb3]
[<ffffffffa01f90eb>] init_one+0x8c4/0x980 [cxgb3]
[<ffffffff811fcbf0>] local_pci_probe+0x3f/0x70
[<ffffffff81042206>] do_work_for_cpu+0x10/0x22
[<ffffffff810482de>] kthread+0xa1/0xa9
[<ffffffff8138e234>] kernel_thread_helper+0x4/0x10
Contrary to what lockdep says, the code is not fine: we are locking an
uninitialized spinlock.
Signed-off-by: Roland Dreier <roland@purestorage.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet')
-rw-r--r-- | drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c | 92 |
1 files changed, 46 insertions, 46 deletions
diff --git a/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c b/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c index 63bfdd10bd6..abb6ce7c1b7 100644 --- a/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c +++ b/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c | |||
@@ -1150,6 +1150,48 @@ release_tpsram: | |||
1150 | } | 1150 | } |
1151 | 1151 | ||
1152 | /** | 1152 | /** |
1153 | * t3_synchronize_rx - wait for current Rx processing on a port to complete | ||
1154 | * @adap: the adapter | ||
1155 | * @p: the port | ||
1156 | * | ||
1157 | * Ensures that current Rx processing on any of the queues associated with | ||
1158 | * the given port completes before returning. We do this by acquiring and | ||
1159 | * releasing the locks of the response queues associated with the port. | ||
1160 | */ | ||
1161 | static void t3_synchronize_rx(struct adapter *adap, const struct port_info *p) | ||
1162 | { | ||
1163 | int i; | ||
1164 | |||
1165 | for (i = p->first_qset; i < p->first_qset + p->nqsets; i++) { | ||
1166 | struct sge_rspq *q = &adap->sge.qs[i].rspq; | ||
1167 | |||
1168 | spin_lock_irq(&q->lock); | ||
1169 | spin_unlock_irq(&q->lock); | ||
1170 | } | ||
1171 | } | ||
1172 | |||
1173 | static void cxgb_vlan_mode(struct net_device *dev, netdev_features_t features) | ||
1174 | { | ||
1175 | struct port_info *pi = netdev_priv(dev); | ||
1176 | struct adapter *adapter = pi->adapter; | ||
1177 | |||
1178 | if (adapter->params.rev > 0) { | ||
1179 | t3_set_vlan_accel(adapter, 1 << pi->port_id, | ||
1180 | features & NETIF_F_HW_VLAN_RX); | ||
1181 | } else { | ||
1182 | /* single control for all ports */ | ||
1183 | unsigned int i, have_vlans = features & NETIF_F_HW_VLAN_RX; | ||
1184 | |||
1185 | for_each_port(adapter, i) | ||
1186 | have_vlans |= | ||
1187 | adapter->port[i]->features & NETIF_F_HW_VLAN_RX; | ||
1188 | |||
1189 | t3_set_vlan_accel(adapter, 1, have_vlans); | ||
1190 | } | ||
1191 | t3_synchronize_rx(adapter, pi); | ||
1192 | } | ||
1193 | |||
1194 | /** | ||
1153 | * cxgb_up - enable the adapter | 1195 | * cxgb_up - enable the adapter |
1154 | * @adapter: adapter being enabled | 1196 | * @adapter: adapter being enabled |
1155 | * | 1197 | * |
@@ -1161,7 +1203,7 @@ release_tpsram: | |||
1161 | */ | 1203 | */ |
1162 | static int cxgb_up(struct adapter *adap) | 1204 | static int cxgb_up(struct adapter *adap) |
1163 | { | 1205 | { |
1164 | int err; | 1206 | int i, err; |
1165 | 1207 | ||
1166 | if (!(adap->flags & FULL_INIT_DONE)) { | 1208 | if (!(adap->flags & FULL_INIT_DONE)) { |
1167 | err = t3_check_fw_version(adap); | 1209 | err = t3_check_fw_version(adap); |
@@ -1198,6 +1240,9 @@ static int cxgb_up(struct adapter *adap) | |||
1198 | if (err) | 1240 | if (err) |
1199 | goto out; | 1241 | goto out; |
1200 | 1242 | ||
1243 | for_each_port(adap, i) | ||
1244 | cxgb_vlan_mode(adap->port[i], adap->port[i]->features); | ||
1245 | |||
1201 | setup_rss(adap); | 1246 | setup_rss(adap); |
1202 | if (!(adap->flags & NAPI_INIT)) | 1247 | if (!(adap->flags & NAPI_INIT)) |
1203 | init_napi(adap); | 1248 | init_napi(adap); |
@@ -2508,48 +2553,6 @@ static int cxgb_set_mac_addr(struct net_device *dev, void *p) | |||
2508 | return 0; | 2553 | return 0; |
2509 | } | 2554 | } |
2510 | 2555 | ||
2511 | /** | ||
2512 | * t3_synchronize_rx - wait for current Rx processing on a port to complete | ||
2513 | * @adap: the adapter | ||
2514 | * @p: the port | ||
2515 | * | ||
2516 | * Ensures that current Rx processing on any of the queues associated with | ||
2517 | * the given port completes before returning. We do this by acquiring and | ||
2518 | * releasing the locks of the response queues associated with the port. | ||
2519 | */ | ||
2520 | static void t3_synchronize_rx(struct adapter *adap, const struct port_info *p) | ||
2521 | { | ||
2522 | int i; | ||
2523 | |||
2524 | for (i = p->first_qset; i < p->first_qset + p->nqsets; i++) { | ||
2525 | struct sge_rspq *q = &adap->sge.qs[i].rspq; | ||
2526 | |||
2527 | spin_lock_irq(&q->lock); | ||
2528 | spin_unlock_irq(&q->lock); | ||
2529 | } | ||
2530 | } | ||
2531 | |||
2532 | static void cxgb_vlan_mode(struct net_device *dev, netdev_features_t features) | ||
2533 | { | ||
2534 | struct port_info *pi = netdev_priv(dev); | ||
2535 | struct adapter *adapter = pi->adapter; | ||
2536 | |||
2537 | if (adapter->params.rev > 0) { | ||
2538 | t3_set_vlan_accel(adapter, 1 << pi->port_id, | ||
2539 | features & NETIF_F_HW_VLAN_RX); | ||
2540 | } else { | ||
2541 | /* single control for all ports */ | ||
2542 | unsigned int i, have_vlans = features & NETIF_F_HW_VLAN_RX; | ||
2543 | |||
2544 | for_each_port(adapter, i) | ||
2545 | have_vlans |= | ||
2546 | adapter->port[i]->features & NETIF_F_HW_VLAN_RX; | ||
2547 | |||
2548 | t3_set_vlan_accel(adapter, 1, have_vlans); | ||
2549 | } | ||
2550 | t3_synchronize_rx(adapter, pi); | ||
2551 | } | ||
2552 | |||
2553 | static netdev_features_t cxgb_fix_features(struct net_device *dev, | 2556 | static netdev_features_t cxgb_fix_features(struct net_device *dev, |
2554 | netdev_features_t features) | 2557 | netdev_features_t features) |
2555 | { | 2558 | { |
@@ -3353,9 +3356,6 @@ static int __devinit init_one(struct pci_dev *pdev, | |||
3353 | err = sysfs_create_group(&adapter->port[0]->dev.kobj, | 3356 | err = sysfs_create_group(&adapter->port[0]->dev.kobj, |
3354 | &cxgb3_attr_group); | 3357 | &cxgb3_attr_group); |
3355 | 3358 | ||
3356 | for_each_port(adapter, i) | ||
3357 | cxgb_vlan_mode(adapter->port[i], adapter->port[i]->features); | ||
3358 | |||
3359 | print_port_info(adapter, ai); | 3359 | print_port_info(adapter, ai); |
3360 | return 0; | 3360 | return 0; |
3361 | 3361 | ||