Skip to content

Commit 93fc9e1

Browse files
Yevgeny PetrilinRoland Dreier
authored andcommitted
mlx4_core: Support multiple pre-reserved QP regions
For ethernet support, we need to reserve QPs for the ethernet and fibre channel driver. The QPs are reserved at the end of the QP table. (This way we assure that they are aligned to their size) We need to consider these reserved ranges in bitmap creation, so we extend the mlx4 bitmap utility functions to allow reserved ranges at both the bottom and the top of the range. Signed-off-by: Yevgeny Petrilin <[email protected]> Signed-off-by: Roland Dreier <[email protected]>
1 parent a3cdcbf commit 93fc9e1

File tree

13 files changed

+144
-29
lines changed

13 files changed

+144
-29
lines changed

drivers/net/mlx4/alloc.c

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -47,13 +47,16 @@ u32 mlx4_bitmap_alloc(struct mlx4_bitmap *bitmap)
4747

4848
obj = find_next_zero_bit(bitmap->table, bitmap->max, bitmap->last);
4949
if (obj >= bitmap->max) {
50-
bitmap->top = (bitmap->top + bitmap->max) & bitmap->mask;
50+
bitmap->top = (bitmap->top + bitmap->max + bitmap->reserved_top)
51+
& bitmap->mask;
5152
obj = find_first_zero_bit(bitmap->table, bitmap->max);
5253
}
5354

5455
if (obj < bitmap->max) {
5556
set_bit(obj, bitmap->table);
56-
bitmap->last = (obj + 1) & (bitmap->max - 1);
57+
bitmap->last = (obj + 1);
58+
if (bitmap->last == bitmap->max)
59+
bitmap->last = 0;
5760
obj |= bitmap->top;
5861
} else
5962
obj = -1;
@@ -109,9 +112,9 @@ u32 mlx4_bitmap_alloc_range(struct mlx4_bitmap *bitmap, int cnt, int align)
109112
obj = find_aligned_range(bitmap->table, bitmap->last,
110113
bitmap->max, cnt, align);
111114
if (obj >= bitmap->max) {
112-
bitmap->top = (bitmap->top + bitmap->max) & bitmap->mask;
113-
obj = find_aligned_range(bitmap->table, 0,
114-
bitmap->max,
115+
bitmap->top = (bitmap->top + bitmap->max + bitmap->reserved_top)
116+
& bitmap->mask;
117+
obj = find_aligned_range(bitmap->table, 0, bitmap->max,
115118
cnt, align);
116119
}
117120

@@ -136,17 +139,19 @@ void mlx4_bitmap_free_range(struct mlx4_bitmap *bitmap, u32 obj, int cnt)
136139
{
137140
u32 i;
138141

139-
obj &= bitmap->max - 1;
142+
obj &= bitmap->max + bitmap->reserved_top - 1;
140143

141144
spin_lock(&bitmap->lock);
142145
for (i = 0; i < cnt; i++)
143146
clear_bit(obj + i, bitmap->table);
144147
bitmap->last = min(bitmap->last, obj);
145-
bitmap->top = (bitmap->top + bitmap->max) & bitmap->mask;
148+
bitmap->top = (bitmap->top + bitmap->max + bitmap->reserved_top)
149+
& bitmap->mask;
146150
spin_unlock(&bitmap->lock);
147151
}
148152

149-
int mlx4_bitmap_init(struct mlx4_bitmap *bitmap, u32 num, u32 mask, u32 reserved)
153+
int mlx4_bitmap_init(struct mlx4_bitmap *bitmap, u32 num, u32 mask,
154+
u32 reserved_bot, u32 reserved_top)
150155
{
151156
int i;
152157

@@ -156,14 +161,16 @@ int mlx4_bitmap_init(struct mlx4_bitmap *bitmap, u32 num, u32 mask, u32 reserved
156161

157162
bitmap->last = 0;
158163
bitmap->top = 0;
159-
bitmap->max = num;
164+
bitmap->max = num - reserved_top;
160165
bitmap->mask = mask;
166+
bitmap->reserved_top = reserved_top;
161167
spin_lock_init(&bitmap->lock);
162-
bitmap->table = kzalloc(BITS_TO_LONGS(num) * sizeof (long), GFP_KERNEL);
168+
bitmap->table = kzalloc(BITS_TO_LONGS(bitmap->max) *
169+
sizeof (long), GFP_KERNEL);
163170
if (!bitmap->table)
164171
return -ENOMEM;
165172

166-
for (i = 0; i < reserved; ++i)
173+
for (i = 0; i < reserved_bot; ++i)
167174
set_bit(i, bitmap->table);
168175

169176
return 0;

drivers/net/mlx4/cq.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,7 @@ int mlx4_init_cq_table(struct mlx4_dev *dev)
300300
INIT_RADIX_TREE(&cq_table->tree, GFP_ATOMIC);
301301

302302
err = mlx4_bitmap_init(&cq_table->bitmap, dev->caps.num_cqs,
303-
dev->caps.num_cqs - 1, dev->caps.reserved_cqs);
303+
dev->caps.num_cqs - 1, dev->caps.reserved_cqs, 0);
304304
if (err)
305305
return err;
306306

drivers/net/mlx4/eq.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -558,7 +558,7 @@ int mlx4_init_eq_table(struct mlx4_dev *dev)
558558
int i;
559559

560560
err = mlx4_bitmap_init(&priv->eq_table.bitmap, dev->caps.num_eqs,
561-
dev->caps.num_eqs - 1, dev->caps.reserved_eqs);
561+
dev->caps.num_eqs - 1, dev->caps.reserved_eqs, 0);
562562
if (err)
563563
return err;
564564

drivers/net/mlx4/fw.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,7 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
357357
#define QUERY_PORT_MTU_OFFSET 0x01
358358
#define QUERY_PORT_WIDTH_OFFSET 0x06
359359
#define QUERY_PORT_MAX_GID_PKEY_OFFSET 0x07
360+
#define QUERY_PORT_MAX_MACVLAN_OFFSET 0x0a
360361
#define QUERY_PORT_MAX_VL_OFFSET 0x0b
361362

362363
for (i = 1; i <= dev_cap->num_ports; ++i) {
@@ -374,6 +375,10 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
374375
dev_cap->max_pkeys[i] = 1 << (field & 0xf);
375376
MLX4_GET(field, outbox, QUERY_PORT_MAX_VL_OFFSET);
376377
dev_cap->max_vl[i] = field & 0xf;
378+
MLX4_GET(field, outbox, QUERY_PORT_MAX_MACVLAN_OFFSET);
379+
dev_cap->log_max_macs[i] = field & 0xf;
380+
dev_cap->log_max_vlans[i] = field >> 4;
381+
377382
}
378383
}
379384

drivers/net/mlx4/fw.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,8 @@ struct mlx4_dev_cap {
102102
u32 reserved_lkey;
103103
u64 max_icm_sz;
104104
int max_gso_sz;
105+
u8 log_max_macs[MLX4_MAX_PORTS + 1];
106+
u8 log_max_vlans[MLX4_MAX_PORTS + 1];
105107
};
106108

107109
struct mlx4_adapter {

drivers/net/mlx4/main.c

Lines changed: 56 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,19 @@ static struct mlx4_profile default_profile = {
8585
.num_mtt = 1 << 20,
8686
};
8787

88+
static int log_num_mac = 2;
89+
module_param_named(log_num_mac, log_num_mac, int, 0444);
90+
MODULE_PARM_DESC(log_num_mac, "Log2 max number of MACs per ETH port (1-7)");
91+
92+
static int log_num_vlan;
93+
module_param_named(log_num_vlan, log_num_vlan, int, 0444);
94+
MODULE_PARM_DESC(log_num_vlan, "Log2 max number of VLANs per ETH port (0-7)");
95+
96+
static int use_prio;
97+
module_param_named(use_prio, use_prio, bool, 0444);
98+
MODULE_PARM_DESC(use_prio, "Enable steering by VLAN priority on ETH ports "
99+
"(0/1, default 0)");
100+
88101
static int mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
89102
{
90103
int err;
@@ -134,7 +147,6 @@ static int mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
134147
dev->caps.max_rq_sg = dev_cap->max_rq_sg;
135148
dev->caps.max_wqes = dev_cap->max_qp_sz;
136149
dev->caps.max_qp_init_rdma = dev_cap->max_requester_per_qp;
137-
dev->caps.reserved_qps = dev_cap->reserved_qps;
138150
dev->caps.max_srq_wqes = dev_cap->max_srq_sz;
139151
dev->caps.max_srq_sge = dev_cap->max_rq_sg - 1;
140152
dev->caps.reserved_srqs = dev_cap->reserved_srqs;
@@ -163,6 +175,39 @@ static int mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
163175
dev->caps.stat_rate_support = dev_cap->stat_rate_support;
164176
dev->caps.max_gso_sz = dev_cap->max_gso_sz;
165177

178+
dev->caps.log_num_macs = log_num_mac;
179+
dev->caps.log_num_vlans = log_num_vlan;
180+
dev->caps.log_num_prios = use_prio ? 3 : 0;
181+
182+
for (i = 1; i <= dev->caps.num_ports; ++i) {
183+
if (dev->caps.log_num_macs > dev_cap->log_max_macs[i]) {
184+
dev->caps.log_num_macs = dev_cap->log_max_macs[i];
185+
mlx4_warn(dev, "Requested number of MACs is too much "
186+
"for port %d, reducing to %d.\n",
187+
i, 1 << dev->caps.log_num_macs);
188+
}
189+
if (dev->caps.log_num_vlans > dev_cap->log_max_vlans[i]) {
190+
dev->caps.log_num_vlans = dev_cap->log_max_vlans[i];
191+
mlx4_warn(dev, "Requested number of VLANs is too much "
192+
"for port %d, reducing to %d.\n",
193+
i, 1 << dev->caps.log_num_vlans);
194+
}
195+
}
196+
197+
dev->caps.reserved_qps_cnt[MLX4_QP_REGION_FW] = dev_cap->reserved_qps;
198+
dev->caps.reserved_qps_cnt[MLX4_QP_REGION_ETH_ADDR] =
199+
dev->caps.reserved_qps_cnt[MLX4_QP_REGION_FC_ADDR] =
200+
(1 << dev->caps.log_num_macs) *
201+
(1 << dev->caps.log_num_vlans) *
202+
(1 << dev->caps.log_num_prios) *
203+
dev->caps.num_ports;
204+
dev->caps.reserved_qps_cnt[MLX4_QP_REGION_FC_EXCH] = MLX4_NUM_FEXCH;
205+
206+
dev->caps.reserved_qps = dev->caps.reserved_qps_cnt[MLX4_QP_REGION_FW] +
207+
dev->caps.reserved_qps_cnt[MLX4_QP_REGION_ETH_ADDR] +
208+
dev->caps.reserved_qps_cnt[MLX4_QP_REGION_FC_ADDR] +
209+
dev->caps.reserved_qps_cnt[MLX4_QP_REGION_FC_EXCH];
210+
166211
return 0;
167212
}
168213

@@ -211,7 +256,8 @@ static int mlx4_init_cmpt_table(struct mlx4_dev *dev, u64 cmpt_base,
211256
((u64) (MLX4_CMPT_TYPE_QP *
212257
cmpt_entry_sz) << MLX4_CMPT_SHIFT),
213258
cmpt_entry_sz, dev->caps.num_qps,
214-
dev->caps.reserved_qps, 0, 0);
259+
dev->caps.reserved_qps_cnt[MLX4_QP_REGION_FW],
260+
0, 0);
215261
if (err)
216262
goto err;
217263

@@ -336,7 +382,8 @@ static int mlx4_init_icm(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap,
336382
init_hca->qpc_base,
337383
dev_cap->qpc_entry_sz,
338384
dev->caps.num_qps,
339-
dev->caps.reserved_qps, 0, 0);
385+
dev->caps.reserved_qps_cnt[MLX4_QP_REGION_FW],
386+
0, 0);
340387
if (err) {
341388
mlx4_err(dev, "Failed to map QP context memory, aborting.\n");
342389
goto err_unmap_dmpt;
@@ -346,7 +393,8 @@ static int mlx4_init_icm(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap,
346393
init_hca->auxc_base,
347394
dev_cap->aux_entry_sz,
348395
dev->caps.num_qps,
349-
dev->caps.reserved_qps, 0, 0);
396+
dev->caps.reserved_qps_cnt[MLX4_QP_REGION_FW],
397+
0, 0);
350398
if (err) {
351399
mlx4_err(dev, "Failed to map AUXC context memory, aborting.\n");
352400
goto err_unmap_qp;
@@ -356,7 +404,8 @@ static int mlx4_init_icm(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap,
356404
init_hca->altc_base,
357405
dev_cap->altc_entry_sz,
358406
dev->caps.num_qps,
359-
dev->caps.reserved_qps, 0, 0);
407+
dev->caps.reserved_qps_cnt[MLX4_QP_REGION_FW],
408+
0, 0);
360409
if (err) {
361410
mlx4_err(dev, "Failed to map ALTC context memory, aborting.\n");
362411
goto err_unmap_auxc;
@@ -366,7 +415,8 @@ static int mlx4_init_icm(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap,
366415
init_hca->rdmarc_base,
367416
dev_cap->rdmarc_entry_sz << priv->qp_table.rdmarc_shift,
368417
dev->caps.num_qps,
369-
dev->caps.reserved_qps, 0, 0);
418+
dev->caps.reserved_qps_cnt[MLX4_QP_REGION_FW],
419+
0, 0);
370420
if (err) {
371421
mlx4_err(dev, "Failed to map RDMARC context memory, aborting\n");
372422
goto err_unmap_altc;

drivers/net/mlx4/mcg.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -368,8 +368,8 @@ int mlx4_init_mcg_table(struct mlx4_dev *dev)
368368
struct mlx4_priv *priv = mlx4_priv(dev);
369369
int err;
370370

371-
err = mlx4_bitmap_init(&priv->mcg_table.bitmap,
372-
dev->caps.num_amgms, dev->caps.num_amgms - 1, 0);
371+
err = mlx4_bitmap_init(&priv->mcg_table.bitmap, dev->caps.num_amgms,
372+
dev->caps.num_amgms - 1, 0, 0);
373373
if (err)
374374
return err;
375375

drivers/net/mlx4/mlx4.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ struct mlx4_bitmap {
111111
u32 last;
112112
u32 top;
113113
u32 max;
114+
u32 reserved_top;
114115
u32 mask;
115116
spinlock_t lock;
116117
unsigned long *table;
@@ -290,7 +291,8 @@ u32 mlx4_bitmap_alloc(struct mlx4_bitmap *bitmap);
290291
void mlx4_bitmap_free(struct mlx4_bitmap *bitmap, u32 obj);
291292
u32 mlx4_bitmap_alloc_range(struct mlx4_bitmap *bitmap, int cnt, int align);
292293
void mlx4_bitmap_free_range(struct mlx4_bitmap *bitmap, u32 obj, int cnt);
293-
int mlx4_bitmap_init(struct mlx4_bitmap *bitmap, u32 num, u32 mask, u32 reserved);
294+
int mlx4_bitmap_init(struct mlx4_bitmap *bitmap, u32 num, u32 mask,
295+
u32 reserved_bot, u32 resetrved_top);
294296
void mlx4_bitmap_cleanup(struct mlx4_bitmap *bitmap);
295297

296298
int mlx4_reset(struct mlx4_dev *dev);

drivers/net/mlx4/mr.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -461,7 +461,7 @@ int mlx4_init_mr_table(struct mlx4_dev *dev)
461461
int err;
462462

463463
err = mlx4_bitmap_init(&mr_table->mpt_bitmap, dev->caps.num_mpts,
464-
~0, dev->caps.reserved_mrws);
464+
~0, dev->caps.reserved_mrws, 0);
465465
if (err)
466466
return err;
467467

drivers/net/mlx4/pd.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ int mlx4_init_pd_table(struct mlx4_dev *dev)
6262
struct mlx4_priv *priv = mlx4_priv(dev);
6363

6464
return mlx4_bitmap_init(&priv->pd_bitmap, dev->caps.num_pds,
65-
(1 << 24) - 1, dev->caps.reserved_pds);
65+
(1 << 24) - 1, dev->caps.reserved_pds, 0);
6666
}
6767

6868
void mlx4_cleanup_pd_table(struct mlx4_dev *dev)
@@ -100,7 +100,7 @@ int mlx4_init_uar_table(struct mlx4_dev *dev)
100100

101101
return mlx4_bitmap_init(&mlx4_priv(dev)->uar_table.bitmap,
102102
dev->caps.num_uars, dev->caps.num_uars - 1,
103-
max(128, dev->caps.reserved_uars));
103+
max(128, dev->caps.reserved_uars), 0);
104104
}
105105

106106
void mlx4_cleanup_uar_table(struct mlx4_dev *dev)

drivers/net/mlx4/qp.c

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,7 @@ int mlx4_init_qp_table(struct mlx4_dev *dev)
272272
{
273273
struct mlx4_qp_table *qp_table = &mlx4_priv(dev)->qp_table;
274274
int err;
275+
int reserved_from_top = 0;
275276

276277
spin_lock_init(&qp_table->lock);
277278
INIT_RADIX_TREE(&dev->qp_table_tree, GFP_ATOMIC);
@@ -281,9 +282,40 @@ int mlx4_init_qp_table(struct mlx4_dev *dev)
281282
* block of special QPs must be aligned to a multiple of 8, so
282283
* round up.
283284
*/
284-
dev->caps.sqp_start = ALIGN(dev->caps.reserved_qps, 8);
285+
dev->caps.sqp_start =
286+
ALIGN(dev->caps.reserved_qps_cnt[MLX4_QP_REGION_FW], 8);
287+
288+
{
289+
int sort[MLX4_NUM_QP_REGION];
290+
int i, j, tmp;
291+
int last_base = dev->caps.num_qps;
292+
293+
for (i = 1; i < MLX4_NUM_QP_REGION; ++i)
294+
sort[i] = i;
295+
296+
for (i = MLX4_NUM_QP_REGION; i > 0; --i) {
297+
for (j = 2; j < i; ++j) {
298+
if (dev->caps.reserved_qps_cnt[sort[j]] >
299+
dev->caps.reserved_qps_cnt[sort[j - 1]]) {
300+
tmp = sort[j];
301+
sort[j] = sort[j - 1];
302+
sort[j - 1] = tmp;
303+
}
304+
}
305+
}
306+
307+
for (i = 1; i < MLX4_NUM_QP_REGION; ++i) {
308+
last_base -= dev->caps.reserved_qps_cnt[sort[i]];
309+
dev->caps.reserved_qps_base[sort[i]] = last_base;
310+
reserved_from_top +=
311+
dev->caps.reserved_qps_cnt[sort[i]];
312+
}
313+
314+
}
315+
285316
err = mlx4_bitmap_init(&qp_table->bitmap, dev->caps.num_qps,
286-
(1 << 24) - 1, dev->caps.sqp_start + 8);
317+
(1 << 23) - 1, dev->caps.sqp_start + 8,
318+
reserved_from_top);
287319
if (err)
288320
return err;
289321

drivers/net/mlx4/srq.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,7 @@ int mlx4_init_srq_table(struct mlx4_dev *dev)
245245
INIT_RADIX_TREE(&srq_table->tree, GFP_ATOMIC);
246246

247247
err = mlx4_bitmap_init(&srq_table->bitmap, dev->caps.num_srqs,
248-
dev->caps.num_srqs - 1, dev->caps.reserved_srqs);
248+
dev->caps.num_srqs - 1, dev->caps.reserved_srqs, 0);
249249
if (err)
250250
return err;
251251

include/linux/mlx4/device.h

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,18 @@ enum {
145145
MLX4_MTT_FLAG_PRESENT = 1
146146
};
147147

148+
enum mlx4_qp_region {
149+
MLX4_QP_REGION_FW = 0,
150+
MLX4_QP_REGION_ETH_ADDR,
151+
MLX4_QP_REGION_FC_ADDR,
152+
MLX4_QP_REGION_FC_EXCH,
153+
MLX4_NUM_QP_REGION
154+
};
155+
156+
enum {
157+
MLX4_NUM_FEXCH = 64 * 1024,
158+
};
159+
148160
static inline u64 mlx4_fw_ver(u64 major, u64 minor, u64 subminor)
149161
{
150162
return (major << 32) | (minor << 16) | subminor;
@@ -169,7 +181,6 @@ struct mlx4_caps {
169181
int max_rq_desc_sz;
170182
int max_qp_init_rdma;
171183
int max_qp_dest_rdma;
172-
int reserved_qps;
173184
int sqp_start;
174185
int num_srqs;
175186
int max_srq_wqes;
@@ -201,6 +212,12 @@ struct mlx4_caps {
201212
u16 stat_rate_support;
202213
u8 port_width_cap[MLX4_MAX_PORTS + 1];
203214
int max_gso_sz;
215+
int reserved_qps_cnt[MLX4_NUM_QP_REGION];
216+
int reserved_qps;
217+
int reserved_qps_base[MLX4_NUM_QP_REGION];
218+
int log_num_macs;
219+
int log_num_vlans;
220+
int log_num_prios;
204221
};
205222

206223
struct mlx4_buf_list {

0 commit comments

Comments
 (0)