aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband
diff options
context:
space:
mode:
authorMike Marciniszyn <mike.marciniszyn@qlogic.com>2011-01-10 20:42:21 -0500
committerRoland Dreier <rolandd@cisco.com>2011-01-10 20:42:21 -0500
commit2528ea60f94ef9e1e1cd82066d55f62a1d19fde1 (patch)
treef2e3494c3b1ac698efb1ba3ba5675d1f21d03d06 /drivers/infiniband
parent19ede2e422496b2a064b9b22823c6afb66ff927b (diff)
IB/qib: Change receive queue/QPN selection
The basic idea is that on SusieQ, the difficult part of mapping QPN to context is handled by the mapping registers so the generic QPN allocation doesn't need to worry about chip specifics. For Monty and Linda, there is no mapping table so the qpt->mask (same as dd->qpn_mask), is used to see if the QPN to context falls within [zero..dd->n_krcv_queues). Signed-off-by: Mike Marciniszyn <mike.marciniszyn@qlogic.com> Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband')
-rw-r--r--drivers/infiniband/hw/qib/qib_iba7220.c2
-rw-r--r--drivers/infiniband/hw/qib/qib_iba7322.c8
-rw-r--r--drivers/infiniband/hw/qib/qib_qp.c26
-rw-r--r--drivers/infiniband/hw/qib/qib_verbs.h10
4 files changed, 15 insertions, 31 deletions
diff --git a/drivers/infiniband/hw/qib/qib_iba7220.c b/drivers/infiniband/hw/qib/qib_iba7220.c
index df49e8e7cc2a..127a0d5069f0 100644
--- a/drivers/infiniband/hw/qib/qib_iba7220.c
+++ b/drivers/infiniband/hw/qib/qib_iba7220.c
@@ -2297,7 +2297,7 @@ static void qib_7220_config_ctxts(struct qib_devdata *dd)
2297 nchipctxts = qib_read_kreg32(dd, kr_portcnt); 2297 nchipctxts = qib_read_kreg32(dd, kr_portcnt);
2298 dd->cspec->numctxts = nchipctxts; 2298 dd->cspec->numctxts = nchipctxts;
2299 if (qib_n_krcv_queues > 1) { 2299 if (qib_n_krcv_queues > 1) {
2300 dd->qpn_mask = 0x3f; 2300 dd->qpn_mask = 0x3e;
2301 dd->first_user_ctxt = qib_n_krcv_queues * dd->num_pports; 2301 dd->first_user_ctxt = qib_n_krcv_queues * dd->num_pports;
2302 if (dd->first_user_ctxt > nchipctxts) 2302 if (dd->first_user_ctxt > nchipctxts)
2303 dd->first_user_ctxt = nchipctxts; 2303 dd->first_user_ctxt = nchipctxts;
diff --git a/drivers/infiniband/hw/qib/qib_iba7322.c b/drivers/infiniband/hw/qib/qib_iba7322.c
index 9bc6d0835e30..d3b493824cdc 100644
--- a/drivers/infiniband/hw/qib/qib_iba7322.c
+++ b/drivers/infiniband/hw/qib/qib_iba7322.c
@@ -3515,11 +3515,6 @@ static void qib_7322_config_ctxts(struct qib_devdata *dd)
3515 nchipctxts = qib_read_kreg32(dd, kr_contextcnt); 3515 nchipctxts = qib_read_kreg32(dd, kr_contextcnt);
3516 dd->cspec->numctxts = nchipctxts; 3516 dd->cspec->numctxts = nchipctxts;
3517 if (qib_n_krcv_queues > 1 && dd->num_pports) { 3517 if (qib_n_krcv_queues > 1 && dd->num_pports) {
3518 /*
3519 * Set the mask for which bits from the QPN are used
3520 * to select a context number.
3521 */
3522 dd->qpn_mask = 0x3f;
3523 dd->first_user_ctxt = NUM_IB_PORTS + 3518 dd->first_user_ctxt = NUM_IB_PORTS +
3524 (qib_n_krcv_queues - 1) * dd->num_pports; 3519 (qib_n_krcv_queues - 1) * dd->num_pports;
3525 if (dd->first_user_ctxt > nchipctxts) 3520 if (dd->first_user_ctxt > nchipctxts)
@@ -5865,7 +5860,8 @@ static void write_7322_initregs(struct qib_devdata *dd)
5865 unsigned n, regno; 5860 unsigned n, regno;
5866 unsigned long flags; 5861 unsigned long flags;
5867 5862
5868 if (!dd->qpn_mask || !dd->pport[pidx].link_speed_supported) 5863 if (dd->n_krcv_queues < 2 ||
5864 !dd->pport[pidx].link_speed_supported)
5869 continue; 5865 continue;
5870 5866
5871 ppd = &dd->pport[pidx]; 5867 ppd = &dd->pport[pidx];
diff --git a/drivers/infiniband/hw/qib/qib_qp.c b/drivers/infiniband/hw/qib/qib_qp.c
index 32dacd444158..eaab008466ca 100644
--- a/drivers/infiniband/hw/qib/qib_qp.c
+++ b/drivers/infiniband/hw/qib/qib_qp.c
@@ -48,13 +48,12 @@ static inline unsigned mk_qpn(struct qib_qpn_table *qpt,
48 48
49static inline unsigned find_next_offset(struct qib_qpn_table *qpt, 49static inline unsigned find_next_offset(struct qib_qpn_table *qpt,
50 struct qpn_map *map, unsigned off, 50 struct qpn_map *map, unsigned off,
51 unsigned r) 51 unsigned n)
52{ 52{
53 if (qpt->mask) { 53 if (qpt->mask) {
54 off++; 54 off++;
55 if ((off & qpt->mask) >> 1 != r) 55 if (((off & qpt->mask) >> 1) >= n)
56 off = ((off & qpt->mask) ? 56 off = (off | qpt->mask) + 2;
57 (off | qpt->mask) + 1 : off) | (r << 1);
58 } else 57 } else
59 off = find_next_zero_bit(map->page, BITS_PER_PAGE, off); 58 off = find_next_zero_bit(map->page, BITS_PER_PAGE, off);
60 return off; 59 return off;
@@ -123,7 +122,6 @@ static int alloc_qpn(struct qib_devdata *dd, struct qib_qpn_table *qpt,
123 u32 i, offset, max_scan, qpn; 122 u32 i, offset, max_scan, qpn;
124 struct qpn_map *map; 123 struct qpn_map *map;
125 u32 ret; 124 u32 ret;
126 int r;
127 125
128 if (type == IB_QPT_SMI || type == IB_QPT_GSI) { 126 if (type == IB_QPT_SMI || type == IB_QPT_GSI) {
129 unsigned n; 127 unsigned n;
@@ -139,15 +137,11 @@ static int alloc_qpn(struct qib_devdata *dd, struct qib_qpn_table *qpt,
139 goto bail; 137 goto bail;
140 } 138 }
141 139
142 r = smp_processor_id();
143 if (r >= dd->n_krcv_queues)
144 r %= dd->n_krcv_queues;
145 qpn = qpt->last + 1; 140 qpn = qpt->last + 1;
146 if (qpn >= QPN_MAX) 141 if (qpn >= QPN_MAX)
147 qpn = 2; 142 qpn = 2;
148 if (qpt->mask && ((qpn & qpt->mask) >> 1) != r) 143 if (qpt->mask && ((qpn & qpt->mask) >> 1) >= dd->n_krcv_queues)
149 qpn = ((qpn & qpt->mask) ? (qpn | qpt->mask) + 1 : qpn) | 144 qpn = (qpn | qpt->mask) + 2;
150 (r << 1);
151 offset = qpn & BITS_PER_PAGE_MASK; 145 offset = qpn & BITS_PER_PAGE_MASK;
152 map = &qpt->map[qpn / BITS_PER_PAGE]; 146 map = &qpt->map[qpn / BITS_PER_PAGE];
153 max_scan = qpt->nmaps - !offset; 147 max_scan = qpt->nmaps - !offset;
@@ -163,7 +157,8 @@ static int alloc_qpn(struct qib_devdata *dd, struct qib_qpn_table *qpt,
163 ret = qpn; 157 ret = qpn;
164 goto bail; 158 goto bail;
165 } 159 }
166 offset = find_next_offset(qpt, map, offset, r); 160 offset = find_next_offset(qpt, map, offset,
161 dd->n_krcv_queues);
167 qpn = mk_qpn(qpt, map, offset); 162 qpn = mk_qpn(qpt, map, offset);
168 /* 163 /*
169 * This test differs from alloc_pidmap(). 164 * This test differs from alloc_pidmap().
@@ -183,13 +178,13 @@ static int alloc_qpn(struct qib_devdata *dd, struct qib_qpn_table *qpt,
183 if (qpt->nmaps == QPNMAP_ENTRIES) 178 if (qpt->nmaps == QPNMAP_ENTRIES)
184 break; 179 break;
185 map = &qpt->map[qpt->nmaps++]; 180 map = &qpt->map[qpt->nmaps++];
186 offset = qpt->mask ? (r << 1) : 0; 181 offset = 0;
187 } else if (map < &qpt->map[qpt->nmaps]) { 182 } else if (map < &qpt->map[qpt->nmaps]) {
188 ++map; 183 ++map;
189 offset = qpt->mask ? (r << 1) : 0; 184 offset = 0;
190 } else { 185 } else {
191 map = &qpt->map[0]; 186 map = &qpt->map[0];
192 offset = qpt->mask ? (r << 1) : 2; 187 offset = 2;
193 } 188 }
194 qpn = mk_qpn(qpt, map, offset); 189 qpn = mk_qpn(qpt, map, offset);
195 } 190 }
@@ -1065,7 +1060,6 @@ struct ib_qp *qib_create_qp(struct ib_pd *ibpd,
1065 } 1060 }
1066 qp->ibqp.qp_num = err; 1061 qp->ibqp.qp_num = err;
1067 qp->port_num = init_attr->port_num; 1062 qp->port_num = init_attr->port_num;
1068 qp->processor_id = smp_processor_id();
1069 qib_reset_qp(qp, init_attr->qp_type); 1063 qib_reset_qp(qp, init_attr->qp_type);
1070 break; 1064 break;
1071 1065
diff --git a/drivers/infiniband/hw/qib/qib_verbs.h b/drivers/infiniband/hw/qib/qib_verbs.h
index bd57c1273225..a08ceab510e1 100644
--- a/drivers/infiniband/hw/qib/qib_verbs.h
+++ b/drivers/infiniband/hw/qib/qib_verbs.h
@@ -435,7 +435,6 @@ struct qib_qp {
435 spinlock_t r_lock; /* used for APM */ 435 spinlock_t r_lock; /* used for APM */
436 spinlock_t s_lock; 436 spinlock_t s_lock;
437 atomic_t s_dma_busy; 437 atomic_t s_dma_busy;
438 unsigned processor_id; /* Processor ID QP is bound to */
439 u32 s_flags; 438 u32 s_flags;
440 u32 s_cur_size; /* size of send packet in bytes */ 439 u32 s_cur_size; /* size of send packet in bytes */
441 u32 s_len; /* total length of s_sge */ 440 u32 s_len; /* total length of s_sge */
@@ -813,13 +812,8 @@ extern struct workqueue_struct *qib_cq_wq;
813 */ 812 */
814static inline void qib_schedule_send(struct qib_qp *qp) 813static inline void qib_schedule_send(struct qib_qp *qp)
815{ 814{
816 if (qib_send_ok(qp)) { 815 if (qib_send_ok(qp))
817 if (qp->processor_id == smp_processor_id()) 816 queue_work(qib_wq, &qp->s_work);
818 queue_work(qib_wq, &qp->s_work);
819 else
820 queue_work_on(qp->processor_id,
821 qib_wq, &qp->s_work);
822 }
823} 817}
824 818
825static inline int qib_pkey_ok(u16 pkey1, u16 pkey2) 819static inline int qib_pkey_ok(u16 pkey1, u16 pkey2)