diff options
author | Jiri Kosina <jkosina@suse.cz> | 2011-09-15 09:08:05 -0400 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2011-09-15 09:08:18 -0400 |
commit | e060c38434b2caa78efe7cedaff4191040b65a15 (patch) | |
tree | 407361230bf6733f63d8e788e4b5e6566ee04818 /drivers/scsi/fcoe | |
parent | 10e4ac572eeffe5317019bd7330b6058a400dfc2 (diff) | |
parent | cc39c6a9bbdebfcf1a7dee64d83bf302bc38d941 (diff) |
Merge branch 'master' into for-next
Fast-forward merge with Linus to be able to merge patches
based on more recent version of the tree.
Diffstat (limited to 'drivers/scsi/fcoe')
-rw-r--r-- | drivers/scsi/fcoe/fcoe.c | 82 |
1 files changed, 40 insertions, 42 deletions
diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c index 563c25c4b2b5..34c8d82b7423 100644 --- a/drivers/scsi/fcoe/fcoe.c +++ b/drivers/scsi/fcoe/fcoe.c | |||
@@ -431,6 +431,8 @@ void fcoe_interface_cleanup(struct fcoe_interface *fcoe) | |||
431 | u8 flogi_maddr[ETH_ALEN]; | 431 | u8 flogi_maddr[ETH_ALEN]; |
432 | const struct net_device_ops *ops; | 432 | const struct net_device_ops *ops; |
433 | 433 | ||
434 | rtnl_lock(); | ||
435 | |||
434 | /* | 436 | /* |
435 | * Don't listen for Ethernet packets anymore. | 437 | * Don't listen for Ethernet packets anymore. |
436 | * synchronize_net() ensures that the packet handlers are not running | 438 | * synchronize_net() ensures that the packet handlers are not running |
@@ -460,6 +462,8 @@ void fcoe_interface_cleanup(struct fcoe_interface *fcoe) | |||
460 | " specific feature for LLD.\n"); | 462 | " specific feature for LLD.\n"); |
461 | } | 463 | } |
462 | 464 | ||
465 | rtnl_unlock(); | ||
466 | |||
463 | /* Release the self-reference taken during fcoe_interface_create() */ | 467 | /* Release the self-reference taken during fcoe_interface_create() */ |
464 | fcoe_interface_put(fcoe); | 468 | fcoe_interface_put(fcoe); |
465 | } | 469 | } |
@@ -486,6 +490,19 @@ static int fcoe_fip_recv(struct sk_buff *skb, struct net_device *netdev, | |||
486 | } | 490 | } |
487 | 491 | ||
488 | /** | 492 | /** |
493 | * fcoe_port_send() - Send an Ethernet-encapsulated FIP/FCoE frame | ||
494 | * @port: The FCoE port | ||
495 | * @skb: The FIP/FCoE packet to be sent | ||
496 | */ | ||
497 | static void fcoe_port_send(struct fcoe_port *port, struct sk_buff *skb) | ||
498 | { | ||
499 | if (port->fcoe_pending_queue.qlen) | ||
500 | fcoe_check_wait_queue(port->lport, skb); | ||
501 | else if (fcoe_start_io(skb)) | ||
502 | fcoe_check_wait_queue(port->lport, skb); | ||
503 | } | ||
504 | |||
505 | /** | ||
489 | * fcoe_fip_send() - Send an Ethernet-encapsulated FIP frame | 506 | * fcoe_fip_send() - Send an Ethernet-encapsulated FIP frame |
490 | * @fip: The FCoE controller | 507 | * @fip: The FCoE controller |
491 | * @skb: The FIP packet to be sent | 508 | * @skb: The FIP packet to be sent |
@@ -493,7 +510,7 @@ static int fcoe_fip_recv(struct sk_buff *skb, struct net_device *netdev, | |||
493 | static void fcoe_fip_send(struct fcoe_ctlr *fip, struct sk_buff *skb) | 510 | static void fcoe_fip_send(struct fcoe_ctlr *fip, struct sk_buff *skb) |
494 | { | 511 | { |
495 | skb->dev = fcoe_from_ctlr(fip)->netdev; | 512 | skb->dev = fcoe_from_ctlr(fip)->netdev; |
496 | dev_queue_xmit(skb); | 513 | fcoe_port_send(lport_priv(fip->lp), skb); |
497 | } | 514 | } |
498 | 515 | ||
499 | /** | 516 | /** |
@@ -1256,30 +1273,20 @@ static int fcoe_cpu_callback(struct notifier_block *nfb, | |||
1256 | /** | 1273 | /** |
1257 | * fcoe_select_cpu() - Selects CPU to handle post-processing of incoming | 1274 | * fcoe_select_cpu() - Selects CPU to handle post-processing of incoming |
1258 | * command. | 1275 | * command. |
1259 | * @curr_cpu: CPU which received request | ||
1260 | * | 1276 | * |
1261 | * This routine selects next CPU based on cpumask. | 1277 | * This routine selects next CPU based on cpumask to distribute |
1278 | * incoming requests in round robin. | ||
1262 | * | 1279 | * |
1263 | * Returns: int (CPU number). Caller to verify if returned CPU is online or not. | 1280 | * Returns: int CPU number |
1264 | */ | 1281 | */ |
1265 | static unsigned int fcoe_select_cpu(unsigned int curr_cpu) | 1282 | static inline unsigned int fcoe_select_cpu(void) |
1266 | { | 1283 | { |
1267 | static unsigned int selected_cpu; | 1284 | static unsigned int selected_cpu; |
1268 | 1285 | ||
1269 | if (num_online_cpus() == 1) | 1286 | selected_cpu = cpumask_next(selected_cpu, cpu_online_mask); |
1270 | return curr_cpu; | 1287 | if (selected_cpu >= nr_cpu_ids) |
1271 | /* | 1288 | selected_cpu = cpumask_first(cpu_online_mask); |
1272 | * Doing following check, to skip "curr_cpu (smp_processor_id)" | 1289 | |
1273 | * from selection of CPU is intentional. This is to avoid same CPU | ||
1274 | * doing post-processing of command. "curr_cpu" to just receive | ||
1275 | * incoming request in case where rx_id is UNKNOWN and all other | ||
1276 | * CPU to actually process the command(s) | ||
1277 | */ | ||
1278 | do { | ||
1279 | selected_cpu = cpumask_next(selected_cpu, cpu_online_mask); | ||
1280 | if (selected_cpu >= nr_cpu_ids) | ||
1281 | selected_cpu = cpumask_first(cpu_online_mask); | ||
1282 | } while (selected_cpu == curr_cpu); | ||
1283 | return selected_cpu; | 1290 | return selected_cpu; |
1284 | } | 1291 | } |
1285 | 1292 | ||
@@ -1349,30 +1356,26 @@ int fcoe_rcv(struct sk_buff *skb, struct net_device *netdev, | |||
1349 | 1356 | ||
1350 | fr = fcoe_dev_from_skb(skb); | 1357 | fr = fcoe_dev_from_skb(skb); |
1351 | fr->fr_dev = lport; | 1358 | fr->fr_dev = lport; |
1352 | fr->ptype = ptype; | ||
1353 | 1359 | ||
1354 | /* | 1360 | /* |
1355 | * In case the incoming frame's exchange is originated from | 1361 | * In case the incoming frame's exchange is originated from |
1356 | * the initiator, then received frame's exchange id is ANDed | 1362 | * the initiator, then received frame's exchange id is ANDed |
1357 | * with fc_cpu_mask bits to get the same cpu on which exchange | 1363 | * with fc_cpu_mask bits to get the same cpu on which exchange |
1358 | * was originated, otherwise just use the current cpu. | 1364 | * was originated, otherwise select cpu using rx exchange id |
1365 | * or fcoe_select_cpu(). | ||
1359 | */ | 1366 | */ |
1360 | if (ntoh24(fh->fh_f_ctl) & FC_FC_EX_CTX) | 1367 | if (ntoh24(fh->fh_f_ctl) & FC_FC_EX_CTX) |
1361 | cpu = ntohs(fh->fh_ox_id) & fc_cpu_mask; | 1368 | cpu = ntohs(fh->fh_ox_id) & fc_cpu_mask; |
1362 | else { | 1369 | else { |
1363 | cpu = smp_processor_id(); | 1370 | if (ntohs(fh->fh_rx_id) == FC_XID_UNKNOWN) |
1364 | 1371 | cpu = fcoe_select_cpu(); | |
1365 | if ((fh->fh_type == FC_TYPE_FCP) && | 1372 | else |
1366 | (ntohs(fh->fh_rx_id) == FC_XID_UNKNOWN)) { | ||
1367 | do { | ||
1368 | cpu = fcoe_select_cpu(cpu); | ||
1369 | } while (!cpu_online(cpu)); | ||
1370 | } else if ((fh->fh_type == FC_TYPE_FCP) && | ||
1371 | (ntohs(fh->fh_rx_id) != FC_XID_UNKNOWN)) { | ||
1372 | cpu = ntohs(fh->fh_rx_id) & fc_cpu_mask; | 1373 | cpu = ntohs(fh->fh_rx_id) & fc_cpu_mask; |
1373 | } else | ||
1374 | cpu = smp_processor_id(); | ||
1375 | } | 1374 | } |
1375 | |||
1376 | if (cpu >= nr_cpu_ids) | ||
1377 | goto err; | ||
1378 | |||
1376 | fps = &per_cpu(fcoe_percpu, cpu); | 1379 | fps = &per_cpu(fcoe_percpu, cpu); |
1377 | spin_lock_bh(&fps->fcoe_rx_list.lock); | 1380 | spin_lock_bh(&fps->fcoe_rx_list.lock); |
1378 | if (unlikely(!fps->thread)) { | 1381 | if (unlikely(!fps->thread)) { |
@@ -1571,11 +1574,7 @@ int fcoe_xmit(struct fc_lport *lport, struct fc_frame *fp) | |||
1571 | 1574 | ||
1572 | /* send down to lld */ | 1575 | /* send down to lld */ |
1573 | fr_dev(fp) = lport; | 1576 | fr_dev(fp) = lport; |
1574 | if (port->fcoe_pending_queue.qlen) | 1577 | fcoe_port_send(port, skb); |
1575 | fcoe_check_wait_queue(lport, skb); | ||
1576 | else if (fcoe_start_io(skb)) | ||
1577 | fcoe_check_wait_queue(lport, skb); | ||
1578 | |||
1579 | return 0; | 1578 | return 0; |
1580 | } | 1579 | } |
1581 | 1580 | ||
@@ -1955,11 +1954,8 @@ static void fcoe_destroy_work(struct work_struct *work) | |||
1955 | fcoe_if_destroy(port->lport); | 1954 | fcoe_if_destroy(port->lport); |
1956 | 1955 | ||
1957 | /* Do not tear down the fcoe interface for NPIV port */ | 1956 | /* Do not tear down the fcoe interface for NPIV port */ |
1958 | if (!npiv) { | 1957 | if (!npiv) |
1959 | rtnl_lock(); | ||
1960 | fcoe_interface_cleanup(fcoe); | 1958 | fcoe_interface_cleanup(fcoe); |
1961 | rtnl_unlock(); | ||
1962 | } | ||
1963 | 1959 | ||
1964 | mutex_unlock(&fcoe_config_mutex); | 1960 | mutex_unlock(&fcoe_config_mutex); |
1965 | } | 1961 | } |
@@ -2013,8 +2009,9 @@ static int fcoe_create(struct net_device *netdev, enum fip_state fip_mode) | |||
2013 | printk(KERN_ERR "fcoe: Failed to create interface (%s)\n", | 2009 | printk(KERN_ERR "fcoe: Failed to create interface (%s)\n", |
2014 | netdev->name); | 2010 | netdev->name); |
2015 | rc = -EIO; | 2011 | rc = -EIO; |
2012 | rtnl_unlock(); | ||
2016 | fcoe_interface_cleanup(fcoe); | 2013 | fcoe_interface_cleanup(fcoe); |
2017 | goto out_nodev; | 2014 | goto out_nortnl; |
2018 | } | 2015 | } |
2019 | 2016 | ||
2020 | /* Make this the "master" N_Port */ | 2017 | /* Make this the "master" N_Port */ |
@@ -2031,6 +2028,7 @@ static int fcoe_create(struct net_device *netdev, enum fip_state fip_mode) | |||
2031 | 2028 | ||
2032 | out_nodev: | 2029 | out_nodev: |
2033 | rtnl_unlock(); | 2030 | rtnl_unlock(); |
2031 | out_nortnl: | ||
2034 | mutex_unlock(&fcoe_config_mutex); | 2032 | mutex_unlock(&fcoe_config_mutex); |
2035 | return rc; | 2033 | return rc; |
2036 | } | 2034 | } |