diff options
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/fcoe/libfcoe.c | 94 |
1 files changed, 43 insertions, 51 deletions
diff --git a/drivers/scsi/fcoe/libfcoe.c b/drivers/scsi/fcoe/libfcoe.c index 3865d936dee8..d22275bf57f8 100644 --- a/drivers/scsi/fcoe/libfcoe.c +++ b/drivers/scsi/fcoe/libfcoe.c | |||
@@ -65,7 +65,7 @@ MODULE_LICENSE("GPL"); | |||
65 | LIST_HEAD(fcoe_hostlist); | 65 | LIST_HEAD(fcoe_hostlist); |
66 | DEFINE_RWLOCK(fcoe_hostlist_lock); | 66 | DEFINE_RWLOCK(fcoe_hostlist_lock); |
67 | DEFINE_TIMER(fcoe_timer, NULL, 0, 0); | 67 | DEFINE_TIMER(fcoe_timer, NULL, 0, 0); |
68 | struct fcoe_percpu_s *fcoe_percpu[NR_CPUS]; | 68 | DEFINE_PER_CPU(struct fcoe_percpu_s, fcoe_percpu); |
69 | 69 | ||
70 | 70 | ||
71 | /* Function Prototyes */ | 71 | /* Function Prototyes */ |
@@ -226,6 +226,7 @@ int fcoe_rcv(struct sk_buff *skb, struct net_device *dev, | |||
226 | fr->fr_dev = lp; | 226 | fr->fr_dev = lp; |
227 | fr->ptype = ptype; | 227 | fr->ptype = ptype; |
228 | cpu_idx = 0; | 228 | cpu_idx = 0; |
229 | |||
229 | #ifdef CONFIG_SMP | 230 | #ifdef CONFIG_SMP |
230 | /* | 231 | /* |
231 | * The incoming frame exchange id(oxid) is ANDed with num of online | 232 | * The incoming frame exchange id(oxid) is ANDed with num of online |
@@ -235,10 +236,12 @@ int fcoe_rcv(struct sk_buff *skb, struct net_device *dev, | |||
235 | * initialize to first online cpu index. | 236 | * initialize to first online cpu index. |
236 | */ | 237 | */ |
237 | cpu_idx = oxid & (num_online_cpus() - 1); | 238 | cpu_idx = oxid & (num_online_cpus() - 1); |
238 | if (!fcoe_percpu[cpu_idx] || !cpu_online(cpu_idx)) | 239 | if (!cpu_online(cpu_idx)) |
239 | cpu_idx = first_cpu(cpu_online_map); | 240 | cpu_idx = first_cpu(cpu_online_map); |
241 | |||
240 | #endif | 242 | #endif |
241 | fps = fcoe_percpu[cpu_idx]; | 243 | |
244 | fps = &per_cpu(fcoe_percpu, cpu_idx); | ||
242 | 245 | ||
243 | spin_lock_bh(&fps->fcoe_rx_list.lock); | 246 | spin_lock_bh(&fps->fcoe_rx_list.lock); |
244 | __skb_queue_tail(&fps->fcoe_rx_list, skb); | 247 | __skb_queue_tail(&fps->fcoe_rx_list, skb); |
@@ -292,15 +295,13 @@ static int fcoe_get_paged_crc_eof(struct sk_buff *skb, int tlen) | |||
292 | { | 295 | { |
293 | struct fcoe_percpu_s *fps; | 296 | struct fcoe_percpu_s *fps; |
294 | struct page *page; | 297 | struct page *page; |
295 | unsigned int cpu_idx; | ||
296 | 298 | ||
297 | cpu_idx = get_cpu(); | 299 | fps = &get_cpu_var(fcoe_percpu); |
298 | fps = fcoe_percpu[cpu_idx]; | ||
299 | page = fps->crc_eof_page; | 300 | page = fps->crc_eof_page; |
300 | if (!page) { | 301 | if (!page) { |
301 | page = alloc_page(GFP_ATOMIC); | 302 | page = alloc_page(GFP_ATOMIC); |
302 | if (!page) { | 303 | if (!page) { |
303 | put_cpu(); | 304 | put_cpu_var(fcoe_percpu); |
304 | return -ENOMEM; | 305 | return -ENOMEM; |
305 | } | 306 | } |
306 | fps->crc_eof_page = page; | 307 | fps->crc_eof_page = page; |
@@ -320,7 +321,7 @@ static int fcoe_get_paged_crc_eof(struct sk_buff *skb, int tlen) | |||
320 | fps->crc_eof_offset = 0; | 321 | fps->crc_eof_offset = 0; |
321 | put_page(page); | 322 | put_page(page); |
322 | } | 323 | } |
323 | put_cpu(); | 324 | put_cpu_var(fcoe_percpu); |
324 | return 0; | 325 | return 0; |
325 | } | 326 | } |
326 | 327 | ||
@@ -1122,30 +1123,28 @@ EXPORT_SYMBOL_GPL(fcoe_link_ok); | |||
1122 | */ | 1123 | */ |
1123 | void fcoe_percpu_clean(struct fc_lport *lp) | 1124 | void fcoe_percpu_clean(struct fc_lport *lp) |
1124 | { | 1125 | { |
1125 | int idx; | ||
1126 | struct fcoe_percpu_s *pp; | 1126 | struct fcoe_percpu_s *pp; |
1127 | struct fcoe_rcv_info *fr; | 1127 | struct fcoe_rcv_info *fr; |
1128 | struct sk_buff_head *list; | 1128 | struct sk_buff_head *list; |
1129 | struct sk_buff *skb, *next; | 1129 | struct sk_buff *skb, *next; |
1130 | struct sk_buff *head; | 1130 | struct sk_buff *head; |
1131 | unsigned int cpu; | ||
1131 | 1132 | ||
1132 | for (idx = 0; idx < NR_CPUS; idx++) { | 1133 | for_each_possible_cpu(cpu) { |
1133 | if (fcoe_percpu[idx]) { | 1134 | pp = &per_cpu(fcoe_percpu, cpu); |
1134 | pp = fcoe_percpu[idx]; | 1135 | spin_lock_bh(&pp->fcoe_rx_list.lock); |
1135 | spin_lock_bh(&pp->fcoe_rx_list.lock); | 1136 | list = &pp->fcoe_rx_list; |
1136 | list = &pp->fcoe_rx_list; | 1137 | head = list->next; |
1137 | head = list->next; | 1138 | for (skb = head; skb != (struct sk_buff *)list; |
1138 | for (skb = head; skb != (struct sk_buff *)list; | 1139 | skb = next) { |
1139 | skb = next) { | 1140 | next = skb->next; |
1140 | next = skb->next; | 1141 | fr = fcoe_dev_from_skb(skb); |
1141 | fr = fcoe_dev_from_skb(skb); | 1142 | if (fr->fr_dev == lp) { |
1142 | if (fr->fr_dev == lp) { | 1143 | __skb_unlink(skb, list); |
1143 | __skb_unlink(skb, list); | 1144 | kfree_skb(skb); |
1144 | kfree_skb(skb); | ||
1145 | } | ||
1146 | } | 1145 | } |
1147 | spin_unlock_bh(&pp->fcoe_rx_list.lock); | ||
1148 | } | 1146 | } |
1147 | spin_unlock_bh(&pp->fcoe_rx_list.lock); | ||
1149 | } | 1148 | } |
1150 | } | 1149 | } |
1151 | EXPORT_SYMBOL_GPL(fcoe_percpu_clean); | 1150 | EXPORT_SYMBOL_GPL(fcoe_percpu_clean); |
@@ -1377,8 +1376,7 @@ static int __init fcoe_init(void) | |||
1377 | #endif /* CONFIG_HOTPLUG_CPU */ | 1376 | #endif /* CONFIG_HOTPLUG_CPU */ |
1378 | 1377 | ||
1379 | for_each_possible_cpu(cpu) { | 1378 | for_each_possible_cpu(cpu) { |
1380 | p = fcoe_percpu[cpu]; | 1379 | p = &per_cpu(fcoe_percpu, cpu); |
1381 | p->cpu = cpu; | ||
1382 | skb_queue_head_init(&p->fcoe_rx_list); | 1380 | skb_queue_head_init(&p->fcoe_rx_list); |
1383 | } | 1381 | } |
1384 | 1382 | ||
@@ -1386,24 +1384,19 @@ static int __init fcoe_init(void) | |||
1386 | * initialize per CPU interrupt thread | 1384 | * initialize per CPU interrupt thread |
1387 | */ | 1385 | */ |
1388 | for_each_online_cpu(cpu) { | 1386 | for_each_online_cpu(cpu) { |
1389 | p = kzalloc(sizeof(struct fcoe_percpu_s), GFP_KERNEL); | 1387 | p = &per_cpu(fcoe_percpu, cpu); |
1390 | if (p) { | 1388 | p->thread = kthread_create(fcoe_percpu_receive_thread, |
1391 | p->thread = kthread_create(fcoe_percpu_receive_thread, | 1389 | (void *)p, "fcoethread/%d", cpu); |
1392 | (void *)p, | ||
1393 | "fcoethread/%d", cpu); | ||
1394 | 1390 | ||
1395 | /* | 1391 | /* |
1396 | * if there is no error then bind the thread to the cpu | 1392 | * If there is no error then bind the thread to the CPU |
1397 | * initialize the semaphore and skb queue head | 1393 | * and wake it up. |
1398 | */ | 1394 | */ |
1399 | if (likely(!IS_ERR(p->thread))) { | 1395 | if (!IS_ERR(p->thread)) { |
1400 | fcoe_percpu[cpu] = p; | 1396 | kthread_bind(p->thread, cpu); |
1401 | kthread_bind(p->thread, cpu); | 1397 | wake_up_process(p->thread); |
1402 | wake_up_process(p->thread); | 1398 | } else { |
1403 | } else { | 1399 | p->thread = NULL; |
1404 | fcoe_percpu[cpu] = NULL; | ||
1405 | kfree(p); | ||
1406 | } | ||
1407 | } | 1400 | } |
1408 | } | 1401 | } |
1409 | 1402 | ||
@@ -1432,7 +1425,7 @@ module_init(fcoe_init); | |||
1432 | */ | 1425 | */ |
1433 | static void __exit fcoe_exit(void) | 1426 | static void __exit fcoe_exit(void) |
1434 | { | 1427 | { |
1435 | u32 idx; | 1428 | unsigned int cpu; |
1436 | struct fcoe_softc *fc, *tmp; | 1429 | struct fcoe_softc *fc, *tmp; |
1437 | struct fcoe_percpu_s *p; | 1430 | struct fcoe_percpu_s *p; |
1438 | struct sk_buff *skb; | 1431 | struct sk_buff *skb; |
@@ -1454,17 +1447,16 @@ static void __exit fcoe_exit(void) | |||
1454 | list_for_each_entry_safe(fc, tmp, &fcoe_hostlist, list) | 1447 | list_for_each_entry_safe(fc, tmp, &fcoe_hostlist, list) |
1455 | fcoe_transport_release(fc->real_dev); | 1448 | fcoe_transport_release(fc->real_dev); |
1456 | 1449 | ||
1457 | for (idx = 0; idx < NR_CPUS; idx++) { | 1450 | for_each_possible_cpu(cpu) { |
1458 | if (fcoe_percpu[idx]) { | 1451 | p = &per_cpu(fcoe_percpu, cpu); |
1459 | kthread_stop(fcoe_percpu[idx]->thread); | 1452 | if (p->thread) { |
1460 | p = fcoe_percpu[idx]; | 1453 | kthread_stop(p->thread); |
1461 | spin_lock_bh(&p->fcoe_rx_list.lock); | 1454 | spin_lock_bh(&p->fcoe_rx_list.lock); |
1462 | while ((skb = __skb_dequeue(&p->fcoe_rx_list)) != NULL) | 1455 | while ((skb = __skb_dequeue(&p->fcoe_rx_list)) != NULL) |
1463 | kfree_skb(skb); | 1456 | kfree_skb(skb); |
1464 | spin_unlock_bh(&p->fcoe_rx_list.lock); | 1457 | spin_unlock_bh(&p->fcoe_rx_list.lock); |
1465 | if (fcoe_percpu[idx]->crc_eof_page) | 1458 | if (p->crc_eof_page) |
1466 | put_page(fcoe_percpu[idx]->crc_eof_page); | 1459 | put_page(p->crc_eof_page); |
1467 | kfree(fcoe_percpu[idx]); | ||
1468 | } | 1460 | } |
1469 | } | 1461 | } |
1470 | 1462 | ||