aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/libfc/fc_exch.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/libfc/fc_exch.c')
-rw-r--r--drivers/scsi/libfc/fc_exch.c515
1 files changed, 321 insertions, 194 deletions
diff --git a/drivers/scsi/libfc/fc_exch.c b/drivers/scsi/libfc/fc_exch.c
index 145ab9ba55ea..c1c15748220c 100644
--- a/drivers/scsi/libfc/fc_exch.c
+++ b/drivers/scsi/libfc/fc_exch.c
@@ -32,6 +32,9 @@
32#include <scsi/libfc.h> 32#include <scsi/libfc.h>
33#include <scsi/fc_encode.h> 33#include <scsi/fc_encode.h>
34 34
35u16 fc_cpu_mask; /* cpu mask for possible cpus */
36EXPORT_SYMBOL(fc_cpu_mask);
37static u16 fc_cpu_order; /* 2's power to represent total possible cpus */
35static struct kmem_cache *fc_em_cachep; /* cache for exchanges */ 38static struct kmem_cache *fc_em_cachep; /* cache for exchanges */
36 39
37/* 40/*
@@ -48,6 +51,20 @@ static struct kmem_cache *fc_em_cachep; /* cache for exchanges */
48 */ 51 */
49 52
50/* 53/*
54 * Per cpu exchange pool
55 *
56 * This structure manages per cpu exchanges in array of exchange pointers.
57 * This array is allocated followed by struct fc_exch_pool memory for
58 * assigned range of exchanges to per cpu pool.
59 */
60struct fc_exch_pool {
61 u16 next_index; /* next possible free exchange index */
62 u16 total_exches; /* total allocated exchanges */
63 spinlock_t lock; /* exch pool lock */
64 struct list_head ex_list; /* allocated exchanges list */
65};
66
67/*
51 * Exchange manager. 68 * Exchange manager.
52 * 69 *
53 * This structure is the center for creating exchanges and sequences. 70 * This structure is the center for creating exchanges and sequences.
@@ -55,17 +72,13 @@ static struct kmem_cache *fc_em_cachep; /* cache for exchanges */
55 */ 72 */
56struct fc_exch_mgr { 73struct fc_exch_mgr {
57 enum fc_class class; /* default class for sequences */ 74 enum fc_class class; /* default class for sequences */
58 spinlock_t em_lock; /* exchange manager lock, 75 struct kref kref; /* exchange mgr reference count */
59 must be taken before ex_lock */
60 u16 last_xid; /* last allocated exchange ID */
61 u16 min_xid; /* min exchange ID */ 76 u16 min_xid; /* min exchange ID */
62 u16 max_xid; /* max exchange ID */ 77 u16 max_xid; /* max exchange ID */
63 u16 max_read; /* max exchange ID for read */
64 u16 last_read; /* last xid allocated for read */
65 u32 total_exches; /* total allocated exchanges */
66 struct list_head ex_list; /* allocated exchanges list */ 78 struct list_head ex_list; /* allocated exchanges list */
67 struct fc_lport *lp; /* fc device instance */
68 mempool_t *ep_pool; /* reserve ep's */ 79 mempool_t *ep_pool; /* reserve ep's */
80 u16 pool_max_index; /* max exch array index in exch pool */
81 struct fc_exch_pool *pool; /* per cpu exch pool */
69 82
70 /* 83 /*
71 * currently exchange mgr stats are updated but not used. 84 * currently exchange mgr stats are updated but not used.
@@ -80,10 +93,15 @@ struct fc_exch_mgr {
80 atomic_t seq_not_found; 93 atomic_t seq_not_found;
81 atomic_t non_bls_resp; 94 atomic_t non_bls_resp;
82 } stats; 95 } stats;
83 struct fc_exch **exches; /* for exch pointers indexed by xid */
84}; 96};
85#define fc_seq_exch(sp) container_of(sp, struct fc_exch, seq) 97#define fc_seq_exch(sp) container_of(sp, struct fc_exch, seq)
86 98
99struct fc_exch_mgr_anchor {
100 struct list_head ema_list;
101 struct fc_exch_mgr *mp;
102 bool (*match)(struct fc_frame *);
103};
104
87static void fc_exch_rrq(struct fc_exch *); 105static void fc_exch_rrq(struct fc_exch *);
88static void fc_seq_ls_acc(struct fc_seq *); 106static void fc_seq_ls_acc(struct fc_seq *);
89static void fc_seq_ls_rjt(struct fc_seq *, enum fc_els_rjt_reason, 107static void fc_seq_ls_rjt(struct fc_seq *, enum fc_els_rjt_reason,
@@ -167,8 +185,8 @@ static struct fc_seq *fc_seq_start_next_locked(struct fc_seq *sp);
167 * sequence allocation and deallocation must be locked. 185 * sequence allocation and deallocation must be locked.
168 * - exchange refcnt can be done atomicly without locks. 186 * - exchange refcnt can be done atomicly without locks.
169 * - sequence allocation must be locked by exch lock. 187 * - sequence allocation must be locked by exch lock.
170 * - If the em_lock and ex_lock must be taken at the same time, then the 188 * - If the EM pool lock and ex_lock must be taken at the same time, then the
171 * em_lock must be taken before the ex_lock. 189 * EM pool lock must be taken before the ex_lock.
172 */ 190 */
173 191
174/* 192/*
@@ -268,8 +286,6 @@ static void fc_exch_release(struct fc_exch *ep)
268 mp = ep->em; 286 mp = ep->em;
269 if (ep->destructor) 287 if (ep->destructor)
270 ep->destructor(&ep->seq, ep->arg); 288 ep->destructor(&ep->seq, ep->arg);
271 if (ep->lp->tt.exch_put)
272 ep->lp->tt.exch_put(ep->lp, mp, ep->xid);
273 WARN_ON(!(ep->esb_stat & ESB_ST_COMPLETE)); 289 WARN_ON(!(ep->esb_stat & ESB_ST_COMPLETE));
274 mempool_free(ep, mp->ep_pool); 290 mempool_free(ep, mp->ep_pool);
275 } 291 }
@@ -299,17 +315,31 @@ static int fc_exch_done_locked(struct fc_exch *ep)
299 return rc; 315 return rc;
300} 316}
301 317
302static void fc_exch_mgr_delete_ep(struct fc_exch *ep) 318static inline struct fc_exch *fc_exch_ptr_get(struct fc_exch_pool *pool,
319 u16 index)
303{ 320{
304 struct fc_exch_mgr *mp; 321 struct fc_exch **exches = (struct fc_exch **)(pool + 1);
322 return exches[index];
323}
305 324
306 mp = ep->em; 325static inline void fc_exch_ptr_set(struct fc_exch_pool *pool, u16 index,
307 spin_lock_bh(&mp->em_lock); 326 struct fc_exch *ep)
308 WARN_ON(mp->total_exches <= 0); 327{
309 mp->total_exches--; 328 ((struct fc_exch **)(pool + 1))[index] = ep;
310 mp->exches[ep->xid - mp->min_xid] = NULL; 329}
330
331static void fc_exch_delete(struct fc_exch *ep)
332{
333 struct fc_exch_pool *pool;
334
335 pool = ep->pool;
336 spin_lock_bh(&pool->lock);
337 WARN_ON(pool->total_exches <= 0);
338 pool->total_exches--;
339 fc_exch_ptr_set(pool, (ep->xid - ep->em->min_xid) >> fc_cpu_order,
340 NULL);
311 list_del(&ep->ex_list); 341 list_del(&ep->ex_list);
312 spin_unlock_bh(&mp->em_lock); 342 spin_unlock_bh(&pool->lock);
313 fc_exch_release(ep); /* drop hold for exch in mp */ 343 fc_exch_release(ep); /* drop hold for exch in mp */
314} 344}
315 345
@@ -322,7 +352,7 @@ static inline void fc_exch_timer_set_locked(struct fc_exch *ep,
322 if (ep->state & (FC_EX_RST_CLEANUP | FC_EX_DONE)) 352 if (ep->state & (FC_EX_RST_CLEANUP | FC_EX_DONE))
323 return; 353 return;
324 354
325 FC_EXCH_DBG(ep, "Exchange timed out, notifying the upper layer\n"); 355 FC_EXCH_DBG(ep, "Exchange timer armed\n");
326 356
327 if (schedule_delayed_work(&ep->timeout_work, 357 if (schedule_delayed_work(&ep->timeout_work,
328 msecs_to_jiffies(timer_msec))) 358 msecs_to_jiffies(timer_msec)))
@@ -408,6 +438,8 @@ static void fc_exch_timeout(struct work_struct *work)
408 u32 e_stat; 438 u32 e_stat;
409 int rc = 1; 439 int rc = 1;
410 440
441 FC_EXCH_DBG(ep, "Exchange timed out\n");
442
411 spin_lock_bh(&ep->ex_lock); 443 spin_lock_bh(&ep->ex_lock);
412 if (ep->state & (FC_EX_RST_CLEANUP | FC_EX_DONE)) 444 if (ep->state & (FC_EX_RST_CLEANUP | FC_EX_DONE))
413 goto unlock; 445 goto unlock;
@@ -427,7 +459,7 @@ static void fc_exch_timeout(struct work_struct *work)
427 rc = fc_exch_done_locked(ep); 459 rc = fc_exch_done_locked(ep);
428 spin_unlock_bh(&ep->ex_lock); 460 spin_unlock_bh(&ep->ex_lock);
429 if (!rc) 461 if (!rc)
430 fc_exch_mgr_delete_ep(ep); 462 fc_exch_delete(ep);
431 if (resp) 463 if (resp)
432 resp(sp, ERR_PTR(-FC_EX_TIMEOUT), arg); 464 resp(sp, ERR_PTR(-FC_EX_TIMEOUT), arg);
433 fc_seq_exch_abort(sp, 2 * ep->r_a_tov); 465 fc_seq_exch_abort(sp, 2 * ep->r_a_tov);
@@ -460,65 +492,20 @@ static struct fc_seq *fc_seq_alloc(struct fc_exch *ep, u8 seq_id)
460 return sp; 492 return sp;
461} 493}
462 494
463/* 495/**
464 * fc_em_alloc_xid - returns an xid based on request type 496 * fc_exch_em_alloc() - allocate an exchange from a specified EM.
465 * @lp : ptr to associated lport 497 * @lport: ptr to the local port
466 * @fp : ptr to the assocated frame 498 * @mp: ptr to the exchange manager
467 * 499 *
468 * check the associated fc_fsp_pkt to get scsi command type and 500 * Returns pointer to allocated fc_exch with exch lock held.
469 * command direction to decide from which range this exch id
470 * will be allocated from.
471 *
472 * Returns : 0 or an valid xid
473 */ 501 */
474static u16 fc_em_alloc_xid(struct fc_exch_mgr *mp, const struct fc_frame *fp) 502static struct fc_exch *fc_exch_em_alloc(struct fc_lport *lport,
475{ 503 struct fc_exch_mgr *mp)
476 u16 xid, min, max;
477 u16 *plast;
478 struct fc_exch *ep = NULL;
479
480 if (mp->max_read) {
481 if (fc_fcp_is_read(fr_fsp(fp))) {
482 min = mp->min_xid;
483 max = mp->max_read;
484 plast = &mp->last_read;
485 } else {
486 min = mp->max_read + 1;
487 max = mp->max_xid;
488 plast = &mp->last_xid;
489 }
490 } else {
491 min = mp->min_xid;
492 max = mp->max_xid;
493 plast = &mp->last_xid;
494 }
495 xid = *plast;
496 do {
497 xid = (xid == max) ? min : xid + 1;
498 ep = mp->exches[xid - mp->min_xid];
499 } while ((ep != NULL) && (xid != *plast));
500
501 if (unlikely(ep))
502 xid = 0;
503 else
504 *plast = xid;
505
506 return xid;
507}
508
509/*
510 * fc_exch_alloc - allocate an exchange.
511 * @mp : ptr to the exchange manager
512 * @xid: input xid
513 *
514 * if xid is supplied zero then assign next free exchange ID
515 * from exchange manager, otherwise use supplied xid.
516 * Returns with exch lock held.
517 */
518struct fc_exch *fc_exch_alloc(struct fc_exch_mgr *mp,
519 struct fc_frame *fp, u16 xid)
520{ 504{
521 struct fc_exch *ep; 505 struct fc_exch *ep;
506 unsigned int cpu;
507 u16 index;
508 struct fc_exch_pool *pool;
522 509
523 /* allocate memory for exchange */ 510 /* allocate memory for exchange */
524 ep = mempool_alloc(mp->ep_pool, GFP_ATOMIC); 511 ep = mempool_alloc(mp->ep_pool, GFP_ATOMIC);
@@ -528,16 +515,17 @@ struct fc_exch *fc_exch_alloc(struct fc_exch_mgr *mp,
528 } 515 }
529 memset(ep, 0, sizeof(*ep)); 516 memset(ep, 0, sizeof(*ep));
530 517
531 spin_lock_bh(&mp->em_lock); 518 cpu = smp_processor_id();
532 /* alloc xid if input xid 0 */ 519 pool = per_cpu_ptr(mp->pool, cpu);
533 if (!xid) { 520 spin_lock_bh(&pool->lock);
534 /* alloc a new xid */ 521 index = pool->next_index;
535 xid = fc_em_alloc_xid(mp, fp); 522 /* allocate new exch from pool */
536 if (!xid) { 523 while (fc_exch_ptr_get(pool, index)) {
537 printk(KERN_WARNING "libfc: Failed to allocate an exhange\n"); 524 index = index == mp->pool_max_index ? 0 : index + 1;
525 if (index == pool->next_index)
538 goto err; 526 goto err;
539 }
540 } 527 }
528 pool->next_index = index == mp->pool_max_index ? 0 : index + 1;
541 529
542 fc_exch_hold(ep); /* hold for exch in mp */ 530 fc_exch_hold(ep); /* hold for exch in mp */
543 spin_lock_init(&ep->ex_lock); 531 spin_lock_init(&ep->ex_lock);
@@ -548,18 +536,19 @@ struct fc_exch *fc_exch_alloc(struct fc_exch_mgr *mp,
548 */ 536 */
549 spin_lock_bh(&ep->ex_lock); 537 spin_lock_bh(&ep->ex_lock);
550 538
551 mp->exches[xid - mp->min_xid] = ep; 539 fc_exch_ptr_set(pool, index, ep);
552 list_add_tail(&ep->ex_list, &mp->ex_list); 540 list_add_tail(&ep->ex_list, &pool->ex_list);
553 fc_seq_alloc(ep, ep->seq_id++); 541 fc_seq_alloc(ep, ep->seq_id++);
554 mp->total_exches++; 542 pool->total_exches++;
555 spin_unlock_bh(&mp->em_lock); 543 spin_unlock_bh(&pool->lock);
556 544
557 /* 545 /*
558 * update exchange 546 * update exchange
559 */ 547 */
560 ep->oxid = ep->xid = xid; 548 ep->oxid = ep->xid = (index << fc_cpu_order | cpu) + mp->min_xid;
561 ep->em = mp; 549 ep->em = mp;
562 ep->lp = mp->lp; 550 ep->pool = pool;
551 ep->lp = lport;
563 ep->f_ctl = FC_FC_FIRST_SEQ; /* next seq is first seq */ 552 ep->f_ctl = FC_FC_FIRST_SEQ; /* next seq is first seq */
564 ep->rxid = FC_XID_UNKNOWN; 553 ep->rxid = FC_XID_UNKNOWN;
565 ep->class = mp->class; 554 ep->class = mp->class;
@@ -567,11 +556,36 @@ struct fc_exch *fc_exch_alloc(struct fc_exch_mgr *mp,
567out: 556out:
568 return ep; 557 return ep;
569err: 558err:
570 spin_unlock_bh(&mp->em_lock); 559 spin_unlock_bh(&pool->lock);
571 atomic_inc(&mp->stats.no_free_exch_xid); 560 atomic_inc(&mp->stats.no_free_exch_xid);
572 mempool_free(ep, mp->ep_pool); 561 mempool_free(ep, mp->ep_pool);
573 return NULL; 562 return NULL;
574} 563}
564
565/**
566 * fc_exch_alloc() - allocate an exchange.
567 * @lport: ptr to the local port
568 * @fp: ptr to the FC frame
569 *
570 * This function walks the list of the exchange manager(EM)
571 * anchors to select a EM for new exchange allocation. The
572 * EM is selected having either a NULL match function pointer
573 * or call to match function returning true.
574 */
575struct fc_exch *fc_exch_alloc(struct fc_lport *lport, struct fc_frame *fp)
576{
577 struct fc_exch_mgr_anchor *ema;
578 struct fc_exch *ep;
579
580 list_for_each_entry(ema, &lport->ema_list, ema_list) {
581 if (!ema->match || ema->match(fp)) {
582 ep = fc_exch_em_alloc(lport, ema->mp);
583 if (ep)
584 return ep;
585 }
586 }
587 return NULL;
588}
575EXPORT_SYMBOL(fc_exch_alloc); 589EXPORT_SYMBOL(fc_exch_alloc);
576 590
577/* 591/*
@@ -579,16 +593,18 @@ EXPORT_SYMBOL(fc_exch_alloc);
579 */ 593 */
580static struct fc_exch *fc_exch_find(struct fc_exch_mgr *mp, u16 xid) 594static struct fc_exch *fc_exch_find(struct fc_exch_mgr *mp, u16 xid)
581{ 595{
596 struct fc_exch_pool *pool;
582 struct fc_exch *ep = NULL; 597 struct fc_exch *ep = NULL;
583 598
584 if ((xid >= mp->min_xid) && (xid <= mp->max_xid)) { 599 if ((xid >= mp->min_xid) && (xid <= mp->max_xid)) {
585 spin_lock_bh(&mp->em_lock); 600 pool = per_cpu_ptr(mp->pool, xid & fc_cpu_mask);
586 ep = mp->exches[xid - mp->min_xid]; 601 spin_lock_bh(&pool->lock);
602 ep = fc_exch_ptr_get(pool, (xid - mp->min_xid) >> fc_cpu_order);
587 if (ep) { 603 if (ep) {
588 fc_exch_hold(ep); 604 fc_exch_hold(ep);
589 WARN_ON(ep->xid != xid); 605 WARN_ON(ep->xid != xid);
590 } 606 }
591 spin_unlock_bh(&mp->em_lock); 607 spin_unlock_bh(&pool->lock);
592 } 608 }
593 return ep; 609 return ep;
594} 610}
@@ -602,7 +618,7 @@ void fc_exch_done(struct fc_seq *sp)
602 rc = fc_exch_done_locked(ep); 618 rc = fc_exch_done_locked(ep);
603 spin_unlock_bh(&ep->ex_lock); 619 spin_unlock_bh(&ep->ex_lock);
604 if (!rc) 620 if (!rc)
605 fc_exch_mgr_delete_ep(ep); 621 fc_exch_delete(ep);
606} 622}
607EXPORT_SYMBOL(fc_exch_done); 623EXPORT_SYMBOL(fc_exch_done);
608 624
@@ -610,12 +626,14 @@ EXPORT_SYMBOL(fc_exch_done);
610 * Allocate a new exchange as responder. 626 * Allocate a new exchange as responder.
611 * Sets the responder ID in the frame header. 627 * Sets the responder ID in the frame header.
612 */ 628 */
613static struct fc_exch *fc_exch_resp(struct fc_exch_mgr *mp, struct fc_frame *fp) 629static struct fc_exch *fc_exch_resp(struct fc_lport *lport,
630 struct fc_exch_mgr *mp,
631 struct fc_frame *fp)
614{ 632{
615 struct fc_exch *ep; 633 struct fc_exch *ep;
616 struct fc_frame_header *fh; 634 struct fc_frame_header *fh;
617 635
618 ep = mp->lp->tt.exch_get(mp->lp, fp); 636 ep = fc_exch_alloc(lport, fp);
619 if (ep) { 637 if (ep) {
620 ep->class = fc_frame_class(fp); 638 ep->class = fc_frame_class(fp);
621 639
@@ -641,7 +659,7 @@ static struct fc_exch *fc_exch_resp(struct fc_exch_mgr *mp, struct fc_frame *fp)
641 ep->esb_stat &= ~ESB_ST_SEQ_INIT; 659 ep->esb_stat &= ~ESB_ST_SEQ_INIT;
642 660
643 fc_exch_hold(ep); /* hold for caller */ 661 fc_exch_hold(ep); /* hold for caller */
644 spin_unlock_bh(&ep->ex_lock); /* lock from exch_get */ 662 spin_unlock_bh(&ep->ex_lock); /* lock from fc_exch_alloc */
645 } 663 }
646 return ep; 664 return ep;
647} 665}
@@ -651,7 +669,8 @@ static struct fc_exch *fc_exch_resp(struct fc_exch_mgr *mp, struct fc_frame *fp)
651 * If fc_pf_rjt_reason is FC_RJT_NONE then this function will have a hold 669 * If fc_pf_rjt_reason is FC_RJT_NONE then this function will have a hold
652 * on the ep that should be released by the caller. 670 * on the ep that should be released by the caller.
653 */ 671 */
654static enum fc_pf_rjt_reason fc_seq_lookup_recip(struct fc_exch_mgr *mp, 672static enum fc_pf_rjt_reason fc_seq_lookup_recip(struct fc_lport *lport,
673 struct fc_exch_mgr *mp,
655 struct fc_frame *fp) 674 struct fc_frame *fp)
656{ 675{
657 struct fc_frame_header *fh = fc_frame_header_get(fp); 676 struct fc_frame_header *fh = fc_frame_header_get(fp);
@@ -705,7 +724,7 @@ static enum fc_pf_rjt_reason fc_seq_lookup_recip(struct fc_exch_mgr *mp,
705 reject = FC_RJT_RX_ID; 724 reject = FC_RJT_RX_ID;
706 goto rel; 725 goto rel;
707 } 726 }
708 ep = fc_exch_resp(mp, fp); 727 ep = fc_exch_resp(lport, mp, fp);
709 if (!ep) { 728 if (!ep) {
710 reject = FC_RJT_EXCH_EST; /* XXX */ 729 reject = FC_RJT_EXCH_EST; /* XXX */
711 goto out; 730 goto out;
@@ -822,7 +841,6 @@ struct fc_seq *fc_seq_start_next(struct fc_seq *sp)
822 struct fc_exch *ep = fc_seq_exch(sp); 841 struct fc_exch *ep = fc_seq_exch(sp);
823 842
824 spin_lock_bh(&ep->ex_lock); 843 spin_lock_bh(&ep->ex_lock);
825 WARN_ON((ep->esb_stat & ESB_ST_COMPLETE) != 0);
826 sp = fc_seq_start_next_locked(sp); 844 sp = fc_seq_start_next_locked(sp);
827 spin_unlock_bh(&ep->ex_lock); 845 spin_unlock_bh(&ep->ex_lock);
828 846
@@ -999,8 +1017,8 @@ static void fc_exch_send_ba_rjt(struct fc_frame *rx_fp,
999 */ 1017 */
1000 memcpy(fh->fh_s_id, rx_fh->fh_d_id, 3); 1018 memcpy(fh->fh_s_id, rx_fh->fh_d_id, 3);
1001 memcpy(fh->fh_d_id, rx_fh->fh_s_id, 3); 1019 memcpy(fh->fh_d_id, rx_fh->fh_s_id, 3);
1002 fh->fh_ox_id = rx_fh->fh_rx_id; 1020 fh->fh_ox_id = rx_fh->fh_ox_id;
1003 fh->fh_rx_id = rx_fh->fh_ox_id; 1021 fh->fh_rx_id = rx_fh->fh_rx_id;
1004 fh->fh_seq_cnt = rx_fh->fh_seq_cnt; 1022 fh->fh_seq_cnt = rx_fh->fh_seq_cnt;
1005 fh->fh_r_ctl = FC_RCTL_BA_RJT; 1023 fh->fh_r_ctl = FC_RCTL_BA_RJT;
1006 fh->fh_type = FC_TYPE_BLS; 1024 fh->fh_type = FC_TYPE_BLS;
@@ -1097,7 +1115,7 @@ static void fc_exch_recv_req(struct fc_lport *lp, struct fc_exch_mgr *mp,
1097 enum fc_pf_rjt_reason reject; 1115 enum fc_pf_rjt_reason reject;
1098 1116
1099 fr_seq(fp) = NULL; 1117 fr_seq(fp) = NULL;
1100 reject = fc_seq_lookup_recip(mp, fp); 1118 reject = fc_seq_lookup_recip(lp, mp, fp);
1101 if (reject == FC_RJT_NONE) { 1119 if (reject == FC_RJT_NONE) {
1102 sp = fr_seq(fp); /* sequence will be held */ 1120 sp = fr_seq(fp); /* sequence will be held */
1103 ep = fc_seq_exch(sp); 1121 ep = fc_seq_exch(sp);
@@ -1123,7 +1141,7 @@ static void fc_exch_recv_req(struct fc_lport *lp, struct fc_exch_mgr *mp,
1123 lp->tt.lport_recv(lp, sp, fp); 1141 lp->tt.lport_recv(lp, sp, fp);
1124 fc_exch_release(ep); /* release from lookup */ 1142 fc_exch_release(ep); /* release from lookup */
1125 } else { 1143 } else {
1126 FC_EM_DBG(mp, "exch/seq lookup failed: reject %x\n", reject); 1144 FC_LPORT_DBG(lp, "exch/seq lookup failed: reject %x\n", reject);
1127 fc_frame_free(fp); 1145 fc_frame_free(fp);
1128 } 1146 }
1129} 1147}
@@ -1193,7 +1211,7 @@ static void fc_exch_recv_seq_resp(struct fc_exch_mgr *mp, struct fc_frame *fp)
1193 WARN_ON(fc_seq_exch(sp) != ep); 1211 WARN_ON(fc_seq_exch(sp) != ep);
1194 spin_unlock_bh(&ep->ex_lock); 1212 spin_unlock_bh(&ep->ex_lock);
1195 if (!rc) 1213 if (!rc)
1196 fc_exch_mgr_delete_ep(ep); 1214 fc_exch_delete(ep);
1197 } 1215 }
1198 1216
1199 /* 1217 /*
@@ -1229,13 +1247,12 @@ static void fc_exch_recv_resp(struct fc_exch_mgr *mp, struct fc_frame *fp)
1229 struct fc_seq *sp; 1247 struct fc_seq *sp;
1230 1248
1231 sp = fc_seq_lookup_orig(mp, fp); /* doesn't hold sequence */ 1249 sp = fc_seq_lookup_orig(mp, fp); /* doesn't hold sequence */
1232 if (!sp) { 1250
1251 if (!sp)
1233 atomic_inc(&mp->stats.xid_not_found); 1252 atomic_inc(&mp->stats.xid_not_found);
1234 FC_EM_DBG(mp, "seq lookup failed\n"); 1253 else
1235 } else {
1236 atomic_inc(&mp->stats.non_bls_resp); 1254 atomic_inc(&mp->stats.non_bls_resp);
1237 FC_EM_DBG(mp, "non-BLS response to sequence"); 1255
1238 }
1239 fc_frame_free(fp); 1256 fc_frame_free(fp);
1240} 1257}
1241 1258
@@ -1304,7 +1321,7 @@ static void fc_exch_abts_resp(struct fc_exch *ep, struct fc_frame *fp)
1304 rc = fc_exch_done_locked(ep); 1321 rc = fc_exch_done_locked(ep);
1305 spin_unlock_bh(&ep->ex_lock); 1322 spin_unlock_bh(&ep->ex_lock);
1306 if (!rc) 1323 if (!rc)
1307 fc_exch_mgr_delete_ep(ep); 1324 fc_exch_delete(ep);
1308 1325
1309 if (resp) 1326 if (resp)
1310 resp(sp, fp, ex_resp_arg); 1327 resp(sp, fp, ex_resp_arg);
@@ -1447,44 +1464,77 @@ static void fc_exch_reset(struct fc_exch *ep)
1447 rc = fc_exch_done_locked(ep); 1464 rc = fc_exch_done_locked(ep);
1448 spin_unlock_bh(&ep->ex_lock); 1465 spin_unlock_bh(&ep->ex_lock);
1449 if (!rc) 1466 if (!rc)
1450 fc_exch_mgr_delete_ep(ep); 1467 fc_exch_delete(ep);
1451 1468
1452 if (resp) 1469 if (resp)
1453 resp(sp, ERR_PTR(-FC_EX_CLOSED), arg); 1470 resp(sp, ERR_PTR(-FC_EX_CLOSED), arg);
1454} 1471}
1455 1472
1456/* 1473/**
1457 * Reset an exchange manager, releasing all sequences and exchanges. 1474 * fc_exch_pool_reset() - Resets an per cpu exches pool.
1458 * If sid is non-zero, reset only exchanges we source from that FID. 1475 * @lport: ptr to the local port
1459 * If did is non-zero, reset only exchanges destined to that FID. 1476 * @pool: ptr to the per cpu exches pool
1477 * @sid: source FC ID
1478 * @did: destination FC ID
1479 *
1480 * Resets an per cpu exches pool, releasing its all sequences
1481 * and exchanges. If sid is non-zero, then reset only exchanges
1482 * we sourced from that FID. If did is non-zero, reset only
1483 * exchanges destined to that FID.
1460 */ 1484 */
1461void fc_exch_mgr_reset(struct fc_lport *lp, u32 sid, u32 did) 1485static void fc_exch_pool_reset(struct fc_lport *lport,
1486 struct fc_exch_pool *pool,
1487 u32 sid, u32 did)
1462{ 1488{
1463 struct fc_exch *ep; 1489 struct fc_exch *ep;
1464 struct fc_exch *next; 1490 struct fc_exch *next;
1465 struct fc_exch_mgr *mp = lp->emp;
1466 1491
1467 spin_lock_bh(&mp->em_lock); 1492 spin_lock_bh(&pool->lock);
1468restart: 1493restart:
1469 list_for_each_entry_safe(ep, next, &mp->ex_list, ex_list) { 1494 list_for_each_entry_safe(ep, next, &pool->ex_list, ex_list) {
1470 if ((sid == 0 || sid == ep->sid) && 1495 if ((lport == ep->lp) &&
1496 (sid == 0 || sid == ep->sid) &&
1471 (did == 0 || did == ep->did)) { 1497 (did == 0 || did == ep->did)) {
1472 fc_exch_hold(ep); 1498 fc_exch_hold(ep);
1473 spin_unlock_bh(&mp->em_lock); 1499 spin_unlock_bh(&pool->lock);
1474 1500
1475 fc_exch_reset(ep); 1501 fc_exch_reset(ep);
1476 1502
1477 fc_exch_release(ep); 1503 fc_exch_release(ep);
1478 spin_lock_bh(&mp->em_lock); 1504 spin_lock_bh(&pool->lock);
1479 1505
1480 /* 1506 /*
1481 * must restart loop incase while lock was down 1507 * must restart loop incase while lock
1482 * multiple eps were released. 1508 * was down multiple eps were released.
1483 */ 1509 */
1484 goto restart; 1510 goto restart;
1485 } 1511 }
1486 } 1512 }
1487 spin_unlock_bh(&mp->em_lock); 1513 spin_unlock_bh(&pool->lock);
1514}
1515
1516/**
1517 * fc_exch_mgr_reset() - Resets all EMs of a lport
1518 * @lport: ptr to the local port
1519 * @sid: source FC ID
1520 * @did: destination FC ID
1521 *
1522 * Reset all EMs of a lport, releasing its all sequences and
1523 * exchanges. If sid is non-zero, then reset only exchanges
1524 * we sourced from that FID. If did is non-zero, reset only
1525 * exchanges destined to that FID.
1526 */
1527void fc_exch_mgr_reset(struct fc_lport *lport, u32 sid, u32 did)
1528{
1529 struct fc_exch_mgr_anchor *ema;
1530 unsigned int cpu;
1531
1532 list_for_each_entry(ema, &lport->ema_list, ema_list) {
1533 for_each_possible_cpu(cpu)
1534 fc_exch_pool_reset(lport,
1535 per_cpu_ptr(ema->mp->pool, cpu),
1536 sid, did);
1537 }
1488} 1538}
1489EXPORT_SYMBOL(fc_exch_mgr_reset); 1539EXPORT_SYMBOL(fc_exch_mgr_reset);
1490 1540
@@ -1730,85 +1780,129 @@ reject:
1730 fc_frame_free(fp); 1780 fc_frame_free(fp);
1731} 1781}
1732 1782
1783struct fc_exch_mgr_anchor *fc_exch_mgr_add(struct fc_lport *lport,
1784 struct fc_exch_mgr *mp,
1785 bool (*match)(struct fc_frame *))
1786{
1787 struct fc_exch_mgr_anchor *ema;
1788
1789 ema = kmalloc(sizeof(*ema), GFP_ATOMIC);
1790 if (!ema)
1791 return ema;
1792
1793 ema->mp = mp;
1794 ema->match = match;
1795 /* add EM anchor to EM anchors list */
1796 list_add_tail(&ema->ema_list, &lport->ema_list);
1797 kref_get(&mp->kref);
1798 return ema;
1799}
1800EXPORT_SYMBOL(fc_exch_mgr_add);
1801
1802static void fc_exch_mgr_destroy(struct kref *kref)
1803{
1804 struct fc_exch_mgr *mp = container_of(kref, struct fc_exch_mgr, kref);
1805
1806 mempool_destroy(mp->ep_pool);
1807 free_percpu(mp->pool);
1808 kfree(mp);
1809}
1810
1811void fc_exch_mgr_del(struct fc_exch_mgr_anchor *ema)
1812{
1813 /* remove EM anchor from EM anchors list */
1814 list_del(&ema->ema_list);
1815 kref_put(&ema->mp->kref, fc_exch_mgr_destroy);
1816 kfree(ema);
1817}
1818EXPORT_SYMBOL(fc_exch_mgr_del);
1819
1733struct fc_exch_mgr *fc_exch_mgr_alloc(struct fc_lport *lp, 1820struct fc_exch_mgr *fc_exch_mgr_alloc(struct fc_lport *lp,
1734 enum fc_class class, 1821 enum fc_class class,
1735 u16 min_xid, u16 max_xid) 1822 u16 min_xid, u16 max_xid,
1823 bool (*match)(struct fc_frame *))
1736{ 1824{
1737 struct fc_exch_mgr *mp; 1825 struct fc_exch_mgr *mp;
1738 size_t len; 1826 u16 pool_exch_range;
1827 size_t pool_size;
1828 unsigned int cpu;
1829 struct fc_exch_pool *pool;
1739 1830
1740 if (max_xid <= min_xid || min_xid == 0 || max_xid == FC_XID_UNKNOWN) { 1831 if (max_xid <= min_xid || max_xid == FC_XID_UNKNOWN ||
1832 (min_xid & fc_cpu_mask) != 0) {
1741 FC_LPORT_DBG(lp, "Invalid min_xid 0x:%x and max_xid 0x:%x\n", 1833 FC_LPORT_DBG(lp, "Invalid min_xid 0x:%x and max_xid 0x:%x\n",
1742 min_xid, max_xid); 1834 min_xid, max_xid);
1743 return NULL; 1835 return NULL;
1744 } 1836 }
1745 1837
1746 /* 1838 /*
1747 * Memory need for EM 1839 * allocate memory for EM
1748 */ 1840 */
1749#define xid_ok(i, m1, m2) (((i) >= (m1)) && ((i) <= (m2))) 1841 mp = kzalloc(sizeof(struct fc_exch_mgr), GFP_ATOMIC);
1750 len = (max_xid - min_xid + 1) * (sizeof(struct fc_exch *));
1751 len += sizeof(struct fc_exch_mgr);
1752
1753 mp = kzalloc(len, GFP_ATOMIC);
1754 if (!mp) 1842 if (!mp)
1755 return NULL; 1843 return NULL;
1756 1844
1757 mp->class = class; 1845 mp->class = class;
1758 mp->total_exches = 0;
1759 mp->exches = (struct fc_exch **)(mp + 1);
1760 mp->lp = lp;
1761 /* adjust em exch xid range for offload */ 1846 /* adjust em exch xid range for offload */
1762 mp->min_xid = min_xid; 1847 mp->min_xid = min_xid;
1763 mp->max_xid = max_xid; 1848 mp->max_xid = max_xid;
1764 mp->last_xid = min_xid - 1;
1765 mp->max_read = 0;
1766 mp->last_read = 0;
1767 if (lp->lro_enabled && xid_ok(lp->lro_xid, min_xid, max_xid)) {
1768 mp->max_read = lp->lro_xid;
1769 mp->last_read = min_xid - 1;
1770 mp->last_xid = mp->max_read;
1771 } else {
1772 /* disable lro if no xid control over read */
1773 lp->lro_enabled = 0;
1774 }
1775
1776 INIT_LIST_HEAD(&mp->ex_list);
1777 spin_lock_init(&mp->em_lock);
1778 1849
1779 mp->ep_pool = mempool_create_slab_pool(2, fc_em_cachep); 1850 mp->ep_pool = mempool_create_slab_pool(2, fc_em_cachep);
1780 if (!mp->ep_pool) 1851 if (!mp->ep_pool)
1781 goto free_mp; 1852 goto free_mp;
1782 1853
1854 /*
1855 * Setup per cpu exch pool with entire exchange id range equally
1856 * divided across all cpus. The exch pointers array memory is
1857 * allocated for exch range per pool.
1858 */
1859 pool_exch_range = (mp->max_xid - mp->min_xid + 1) / (fc_cpu_mask + 1);
1860 mp->pool_max_index = pool_exch_range - 1;
1861
1862 /*
1863 * Allocate and initialize per cpu exch pool
1864 */
1865 pool_size = sizeof(*pool) + pool_exch_range * sizeof(struct fc_exch *);
1866 mp->pool = __alloc_percpu(pool_size, __alignof__(struct fc_exch_pool));
1867 if (!mp->pool)
1868 goto free_mempool;
1869 for_each_possible_cpu(cpu) {
1870 pool = per_cpu_ptr(mp->pool, cpu);
1871 spin_lock_init(&pool->lock);
1872 INIT_LIST_HEAD(&pool->ex_list);
1873 }
1874
1875 kref_init(&mp->kref);
1876 if (!fc_exch_mgr_add(lp, mp, match)) {
1877 free_percpu(mp->pool);
1878 goto free_mempool;
1879 }
1880
1881 /*
1882 * Above kref_init() sets mp->kref to 1 and then
1883 * call to fc_exch_mgr_add incremented mp->kref again,
1884 * so adjust that extra increment.
1885 */
1886 kref_put(&mp->kref, fc_exch_mgr_destroy);
1783 return mp; 1887 return mp;
1784 1888
1889free_mempool:
1890 mempool_destroy(mp->ep_pool);
1785free_mp: 1891free_mp:
1786 kfree(mp); 1892 kfree(mp);
1787 return NULL; 1893 return NULL;
1788} 1894}
1789EXPORT_SYMBOL(fc_exch_mgr_alloc); 1895EXPORT_SYMBOL(fc_exch_mgr_alloc);
1790 1896
1791void fc_exch_mgr_free(struct fc_exch_mgr *mp) 1897void fc_exch_mgr_free(struct fc_lport *lport)
1792{ 1898{
1793 WARN_ON(!mp); 1899 struct fc_exch_mgr_anchor *ema, *next;
1794 /* 1900
1795 * The total exch count must be zero 1901 list_for_each_entry_safe(ema, next, &lport->ema_list, ema_list)
1796 * before freeing exchange manager. 1902 fc_exch_mgr_del(ema);
1797 */
1798 WARN_ON(mp->total_exches != 0);
1799 mempool_destroy(mp->ep_pool);
1800 kfree(mp);
1801} 1903}
1802EXPORT_SYMBOL(fc_exch_mgr_free); 1904EXPORT_SYMBOL(fc_exch_mgr_free);
1803 1905
1804struct fc_exch *fc_exch_get(struct fc_lport *lp, struct fc_frame *fp)
1805{
1806 if (!lp || !lp->emp)
1807 return NULL;
1808
1809 return fc_exch_alloc(lp->emp, fp, 0);
1810}
1811EXPORT_SYMBOL(fc_exch_get);
1812 1906
1813struct fc_seq *fc_exch_seq_send(struct fc_lport *lp, 1907struct fc_seq *fc_exch_seq_send(struct fc_lport *lp,
1814 struct fc_frame *fp, 1908 struct fc_frame *fp,
@@ -1823,7 +1917,7 @@ struct fc_seq *fc_exch_seq_send(struct fc_lport *lp,
1823 struct fc_frame_header *fh; 1917 struct fc_frame_header *fh;
1824 int rc = 1; 1918 int rc = 1;
1825 1919
1826 ep = lp->tt.exch_get(lp, fp); 1920 ep = fc_exch_alloc(lp, fp);
1827 if (!ep) { 1921 if (!ep) {
1828 fc_frame_free(fp); 1922 fc_frame_free(fp);
1829 return NULL; 1923 return NULL;
@@ -1843,7 +1937,8 @@ struct fc_seq *fc_exch_seq_send(struct fc_lport *lp,
1843 fc_exch_setup_hdr(ep, fp, ep->f_ctl); 1937 fc_exch_setup_hdr(ep, fp, ep->f_ctl);
1844 sp->cnt++; 1938 sp->cnt++;
1845 1939
1846 fc_fcp_ddp_setup(fr_fsp(fp), ep->xid); 1940 if (ep->xid <= lp->lro_xid)
1941 fc_fcp_ddp_setup(fr_fsp(fp), ep->xid);
1847 1942
1848 if (unlikely(lp->tt.frame_send(lp, fp))) 1943 if (unlikely(lp->tt.frame_send(lp, fp)))
1849 goto err; 1944 goto err;
@@ -1860,7 +1955,7 @@ err:
1860 rc = fc_exch_done_locked(ep); 1955 rc = fc_exch_done_locked(ep);
1861 spin_unlock_bh(&ep->ex_lock); 1956 spin_unlock_bh(&ep->ex_lock);
1862 if (!rc) 1957 if (!rc)
1863 fc_exch_mgr_delete_ep(ep); 1958 fc_exch_delete(ep);
1864 return NULL; 1959 return NULL;
1865} 1960}
1866EXPORT_SYMBOL(fc_exch_seq_send); 1961EXPORT_SYMBOL(fc_exch_seq_send);
@@ -1868,24 +1963,44 @@ EXPORT_SYMBOL(fc_exch_seq_send);
1868/* 1963/*
1869 * Receive a frame 1964 * Receive a frame
1870 */ 1965 */
1871void fc_exch_recv(struct fc_lport *lp, struct fc_exch_mgr *mp, 1966void fc_exch_recv(struct fc_lport *lp, struct fc_frame *fp)
1872 struct fc_frame *fp)
1873{ 1967{
1874 struct fc_frame_header *fh = fc_frame_header_get(fp); 1968 struct fc_frame_header *fh = fc_frame_header_get(fp);
1875 u32 f_ctl; 1969 struct fc_exch_mgr_anchor *ema;
1970 u32 f_ctl, found = 0;
1971 u16 oxid;
1876 1972
1877 /* lport lock ? */ 1973 /* lport lock ? */
1878 if (!lp || !mp || (lp->state == LPORT_ST_NONE)) { 1974 if (!lp || lp->state == LPORT_ST_DISABLED) {
1879 FC_LPORT_DBG(lp, "Receiving frames for an lport that " 1975 FC_LPORT_DBG(lp, "Receiving frames for an lport that "
1880 "has not been initialized correctly\n"); 1976 "has not been initialized correctly\n");
1881 fc_frame_free(fp); 1977 fc_frame_free(fp);
1882 return; 1978 return;
1883 } 1979 }
1884 1980
1981 f_ctl = ntoh24(fh->fh_f_ctl);
1982 oxid = ntohs(fh->fh_ox_id);
1983 if (f_ctl & FC_FC_EX_CTX) {
1984 list_for_each_entry(ema, &lp->ema_list, ema_list) {
1985 if ((oxid >= ema->mp->min_xid) &&
1986 (oxid <= ema->mp->max_xid)) {
1987 found = 1;
1988 break;
1989 }
1990 }
1991
1992 if (!found) {
1993 FC_LPORT_DBG(lp, "Received response for out "
1994 "of range oxid:%hx\n", oxid);
1995 fc_frame_free(fp);
1996 return;
1997 }
1998 } else
1999 ema = list_entry(lp->ema_list.prev, typeof(*ema), ema_list);
2000
1885 /* 2001 /*
1886 * If frame is marked invalid, just drop it. 2002 * If frame is marked invalid, just drop it.
1887 */ 2003 */
1888 f_ctl = ntoh24(fh->fh_f_ctl);
1889 switch (fr_eof(fp)) { 2004 switch (fr_eof(fp)) {
1890 case FC_EOF_T: 2005 case FC_EOF_T:
1891 if (f_ctl & FC_FC_END_SEQ) 2006 if (f_ctl & FC_FC_END_SEQ)
@@ -1893,34 +2008,24 @@ void fc_exch_recv(struct fc_lport *lp, struct fc_exch_mgr *mp,
1893 /* fall through */ 2008 /* fall through */
1894 case FC_EOF_N: 2009 case FC_EOF_N:
1895 if (fh->fh_type == FC_TYPE_BLS) 2010 if (fh->fh_type == FC_TYPE_BLS)
1896 fc_exch_recv_bls(mp, fp); 2011 fc_exch_recv_bls(ema->mp, fp);
1897 else if ((f_ctl & (FC_FC_EX_CTX | FC_FC_SEQ_CTX)) == 2012 else if ((f_ctl & (FC_FC_EX_CTX | FC_FC_SEQ_CTX)) ==
1898 FC_FC_EX_CTX) 2013 FC_FC_EX_CTX)
1899 fc_exch_recv_seq_resp(mp, fp); 2014 fc_exch_recv_seq_resp(ema->mp, fp);
1900 else if (f_ctl & FC_FC_SEQ_CTX) 2015 else if (f_ctl & FC_FC_SEQ_CTX)
1901 fc_exch_recv_resp(mp, fp); 2016 fc_exch_recv_resp(ema->mp, fp);
1902 else 2017 else
1903 fc_exch_recv_req(lp, mp, fp); 2018 fc_exch_recv_req(lp, ema->mp, fp);
1904 break; 2019 break;
1905 default: 2020 default:
1906 FC_EM_DBG(mp, "dropping invalid frame (eof %x)", fr_eof(fp)); 2021 FC_LPORT_DBG(lp, "dropping invalid frame (eof %x)", fr_eof(fp));
1907 fc_frame_free(fp); 2022 fc_frame_free(fp);
1908 break;
1909 } 2023 }
1910} 2024}
1911EXPORT_SYMBOL(fc_exch_recv); 2025EXPORT_SYMBOL(fc_exch_recv);
1912 2026
1913int fc_exch_init(struct fc_lport *lp) 2027int fc_exch_init(struct fc_lport *lp)
1914{ 2028{
1915 if (!lp->tt.exch_get) {
1916 /*
1917 * exch_put() should be NULL if
1918 * exch_get() is NULL
1919 */
1920 WARN_ON(lp->tt.exch_put);
1921 lp->tt.exch_get = fc_exch_get;
1922 }
1923
1924 if (!lp->tt.seq_start_next) 2029 if (!lp->tt.seq_start_next)
1925 lp->tt.seq_start_next = fc_seq_start_next; 2030 lp->tt.seq_start_next = fc_seq_start_next;
1926 2031
@@ -1942,6 +2047,28 @@ int fc_exch_init(struct fc_lport *lp)
1942 if (!lp->tt.seq_exch_abort) 2047 if (!lp->tt.seq_exch_abort)
1943 lp->tt.seq_exch_abort = fc_seq_exch_abort; 2048 lp->tt.seq_exch_abort = fc_seq_exch_abort;
1944 2049
2050 /*
2051 * Initialize fc_cpu_mask and fc_cpu_order. The
2052 * fc_cpu_mask is set for nr_cpu_ids rounded up
2053 * to order of 2's * power and order is stored
2054 * in fc_cpu_order as this is later required in
2055 * mapping between an exch id and exch array index
2056 * in per cpu exch pool.
2057 *
2058 * This round up is required to align fc_cpu_mask
2059 * to exchange id's lower bits such that all incoming
2060 * frames of an exchange gets delivered to the same
2061 * cpu on which exchange originated by simple bitwise
2062 * AND operation between fc_cpu_mask and exchange id.
2063 */
2064 fc_cpu_mask = 1;
2065 fc_cpu_order = 0;
2066 while (fc_cpu_mask < nr_cpu_ids) {
2067 fc_cpu_mask <<= 1;
2068 fc_cpu_order++;
2069 }
2070 fc_cpu_mask--;
2071
1945 return 0; 2072 return 0;
1946} 2073}
1947EXPORT_SYMBOL(fc_exch_init); 2074EXPORT_SYMBOL(fc_exch_init);