Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 278781
b: refs/heads/master
c: 2b8fb28
h: refs/heads/master
i:
  278779: 8488a52
v: v3
  • Loading branch information
Marcel Apfelbaum authored and David S. Miller committed Dec 13, 2011
1 parent 8f2e778 commit 873cc48
Show file tree
Hide file tree
Showing 8 changed files with 93 additions and 100 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 5b4c4d36860ef1c411d0669ffc15090417a33389
refs/heads/master: 2b8fb2867ca2736a715a88067fd0ec2904777cbe
2 changes: 1 addition & 1 deletion trunk/drivers/net/ethernet/mellanox/mlx4/fw.c
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ int mlx4_QUERY_FUNC_CAP_wrapper(struct mlx4_dev *dev, int slave,
size = dev->caps.num_mpts;
MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_MPT_QUOTA_OFFSET);

size = dev->caps.num_mtt_segs * dev->caps.mtts_per_seg;
size = dev->caps.num_mtts;
MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_MTT_QUOTA_OFFSET);

size = dev->caps.num_mgms + dev->caps.num_amgms;
Expand Down
11 changes: 5 additions & 6 deletions trunk/drivers/net/ethernet/mellanox/mlx4/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ module_param_named(use_prio, use_prio, bool, 0444);
MODULE_PARM_DESC(use_prio, "Enable steering by VLAN priority on ETH ports "
"(0/1, default 0)");

static int log_mtts_per_seg = ilog2(MLX4_MTT_ENTRY_PER_SEG);
int log_mtts_per_seg = ilog2(MLX4_MTT_ENTRY_PER_SEG);
module_param_named(log_mtts_per_seg, log_mtts_per_seg, int, 0444);
MODULE_PARM_DESC(log_mtts_per_seg, "Log2 number of MTT entries per segment (1-7)");

Expand Down Expand Up @@ -222,17 +222,16 @@ static int mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
dev->caps.max_cqes = dev_cap->max_cq_sz - 1;
dev->caps.reserved_cqs = dev_cap->reserved_cqs;
dev->caps.reserved_eqs = dev_cap->reserved_eqs;
dev->caps.mtts_per_seg = 1 << log_mtts_per_seg;
dev->caps.reserved_mtts = DIV_ROUND_UP(dev_cap->reserved_mtts,
dev->caps.mtts_per_seg);
dev->caps.reserved_mtts = dev_cap->reserved_mtts;
dev->caps.reserved_mrws = dev_cap->reserved_mrws;
dev->caps.reserved_uars = dev_cap->reserved_uars;
dev->caps.reserved_pds = dev_cap->reserved_pds;
dev->caps.reserved_xrcds = (dev->caps.flags & MLX4_DEV_CAP_FLAG_XRC) ?
dev_cap->reserved_xrcds : 0;
dev->caps.max_xrcds = (dev->caps.flags & MLX4_DEV_CAP_FLAG_XRC) ?
dev_cap->max_xrcds : 0;
dev->caps.mtt_entry_sz = dev->caps.mtts_per_seg * dev_cap->mtt_entry_sz;
dev->caps.mtt_entry_sz = dev_cap->mtt_entry_sz;

dev->caps.max_msg_sz = dev_cap->max_msg_sz;
dev->caps.page_size_cap = ~(u32) (dev_cap->min_page_sz - 1);
dev->caps.flags = dev_cap->flags;
Expand Down Expand Up @@ -569,7 +568,7 @@ static int mlx4_init_icm(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap,
err = mlx4_init_icm_table(dev, &priv->mr_table.mtt_table,
init_hca->mtt_base,
dev->caps.mtt_entry_sz,
dev->caps.num_mtt_segs,
dev->caps.num_mtts,
dev->caps.reserved_mtts, 1, 0);
if (err) {
mlx4_err(dev, "Failed to map MTT context memory, aborting.\n");
Expand Down
3 changes: 2 additions & 1 deletion trunk/drivers/net/ethernet/mellanox/mlx4/mlx4.h
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@ do { \
dev_warn(&mdev->pdev->dev, format, ##arg)

extern int mlx4_log_num_mgm_entry_size;
extern int log_mtts_per_seg;

#define MLX4_MAX_NUM_SLAVES (MLX4_MAX_NUM_PF + MLX4_MAX_NUM_VF)
#define ALL_SLAVES 0xff
Expand Down Expand Up @@ -240,7 +241,7 @@ struct mlx4_mpt_entry {
__be32 win_cnt;
u8 reserved1[3];
u8 mtt_rep;
__be64 mtt_seg;
__be64 mtt_addr;
__be32 mtt_sz;
__be32 entity_size;
__be32 first_byte_offset;
Expand Down
107 changes: 56 additions & 51 deletions trunk/drivers/net/ethernet/mellanox/mlx4/mr.c
Original file line number Diff line number Diff line change
Expand Up @@ -166,18 +166,24 @@ u32 __mlx4_alloc_mtt_range(struct mlx4_dev *dev, int order)
{
struct mlx4_mr_table *mr_table = &mlx4_priv(dev)->mr_table;
u32 seg;
int seg_order;
u32 offset;

seg = mlx4_buddy_alloc(&mr_table->mtt_buddy, order);
seg_order = max_t(int, order - log_mtts_per_seg, 0);

seg = mlx4_buddy_alloc(&mr_table->mtt_buddy, seg_order);
if (seg == -1)
return -1;

if (mlx4_table_get_range(dev, &mr_table->mtt_table, seg,
seg + (1 << order) - 1)) {
mlx4_buddy_free(&mr_table->mtt_buddy, seg, order);
offset = seg * (1 << log_mtts_per_seg);

if (mlx4_table_get_range(dev, &mr_table->mtt_table, offset,
offset + (1 << order) - 1)) {
mlx4_buddy_free(&mr_table->mtt_buddy, seg, seg_order);
return -1;
}

return seg;
return offset;
}

static u32 mlx4_alloc_mtt_range(struct mlx4_dev *dev, int order)
Expand Down Expand Up @@ -212,59 +218,63 @@ int mlx4_mtt_init(struct mlx4_dev *dev, int npages, int page_shift,
} else
mtt->page_shift = page_shift;

for (mtt->order = 0, i = dev->caps.mtts_per_seg; i < npages; i <<= 1)
for (mtt->order = 0, i = 1; i < npages; i <<= 1)
++mtt->order;

mtt->first_seg = mlx4_alloc_mtt_range(dev, mtt->order);
if (mtt->first_seg == -1)
mtt->offset = mlx4_alloc_mtt_range(dev, mtt->order);
if (mtt->offset == -1)
return -ENOMEM;

return 0;
}
EXPORT_SYMBOL_GPL(mlx4_mtt_init);

void __mlx4_free_mtt_range(struct mlx4_dev *dev, u32 first_seg,
int order)
void __mlx4_free_mtt_range(struct mlx4_dev *dev, u32 offset, int order)
{
u32 first_seg;
int seg_order;
struct mlx4_mr_table *mr_table = &mlx4_priv(dev)->mr_table;

mlx4_buddy_free(&mr_table->mtt_buddy, first_seg, order);
seg_order = max_t(int, order - log_mtts_per_seg, 0);
first_seg = offset / (1 << log_mtts_per_seg);

mlx4_buddy_free(&mr_table->mtt_buddy, first_seg, seg_order);
mlx4_table_put_range(dev, &mr_table->mtt_table, first_seg,
first_seg + (1 << order) - 1);
first_seg + (1 << seg_order) - 1);
}

static void mlx4_free_mtt_range(struct mlx4_dev *dev, u32 first_seg, int order)
static void mlx4_free_mtt_range(struct mlx4_dev *dev, u32 offset, int order)
{
u64 in_param;
int err;

if (mlx4_is_mfunc(dev)) {
set_param_l(&in_param, first_seg);
set_param_l(&in_param, offset);
set_param_h(&in_param, order);
err = mlx4_cmd(dev, in_param, RES_MTT, RES_OP_RESERVE_AND_MAP,
MLX4_CMD_FREE_RES,
MLX4_CMD_TIME_CLASS_A,
MLX4_CMD_WRAPPED);
if (err)
mlx4_warn(dev, "Failed to free mtt range at:%d"
" order:%d\n", first_seg, order);
mlx4_warn(dev, "Failed to free mtt range at:"
"%d order:%d\n", offset, order);
return;
}
__mlx4_free_mtt_range(dev, first_seg, order);
__mlx4_free_mtt_range(dev, offset, order);
}

void mlx4_mtt_cleanup(struct mlx4_dev *dev, struct mlx4_mtt *mtt)
{
if (mtt->order < 0)
return;

mlx4_free_mtt_range(dev, mtt->first_seg, mtt->order);
mlx4_free_mtt_range(dev, mtt->offset, mtt->order);
}
EXPORT_SYMBOL_GPL(mlx4_mtt_cleanup);

u64 mlx4_mtt_addr(struct mlx4_dev *dev, struct mlx4_mtt *mtt)
{
return (u64) mtt->first_seg * dev->caps.mtt_entry_sz;
return (u64) mtt->offset * dev->caps.mtt_entry_sz;
}
EXPORT_SYMBOL_GPL(mlx4_mtt_addr);

Expand Down Expand Up @@ -504,18 +514,18 @@ int mlx4_mr_enable(struct mlx4_dev *dev, struct mlx4_mr *mr)

if (mr->mtt.order < 0) {
mpt_entry->flags |= cpu_to_be32(MLX4_MPT_FLAG_PHYSICAL);
mpt_entry->mtt_seg = 0;
mpt_entry->mtt_addr = 0;
} else {
mpt_entry->mtt_seg = cpu_to_be64(mlx4_mtt_addr(dev, &mr->mtt));
mpt_entry->mtt_addr = cpu_to_be64(mlx4_mtt_addr(dev,
&mr->mtt));
}

if (mr->mtt.order >= 0 && mr->mtt.page_shift == 0) {
/* fast register MR in free state */
mpt_entry->flags |= cpu_to_be32(MLX4_MPT_FLAG_FREE);
mpt_entry->pd_flags |= cpu_to_be32(MLX4_MPT_PD_FLAG_FAST_REG |
MLX4_MPT_PD_FLAG_RAE);
mpt_entry->mtt_sz = cpu_to_be32((1 << mr->mtt.order) *
dev->caps.mtts_per_seg);
mpt_entry->mtt_sz = cpu_to_be32(1 << mr->mtt.order);
} else {
mpt_entry->flags |= cpu_to_be32(MLX4_MPT_FLAG_SW_OWNS);
}
Expand Down Expand Up @@ -548,18 +558,10 @@ static int mlx4_write_mtt_chunk(struct mlx4_dev *dev, struct mlx4_mtt *mtt,
__be64 *mtts;
dma_addr_t dma_handle;
int i;
int s = start_index * sizeof (u64);

/* All MTTs must fit in the same page */
if (start_index / (PAGE_SIZE / sizeof (u64)) !=
(start_index + npages - 1) / (PAGE_SIZE / sizeof (u64)))
return -EINVAL;

if (start_index & (dev->caps.mtts_per_seg - 1))
return -EINVAL;
mtts = mlx4_table_find(&priv->mr_table.mtt_table, mtt->offset +
start_index, &dma_handle);

mtts = mlx4_table_find(&priv->mr_table.mtt_table, mtt->first_seg +
s / dev->caps.mtt_entry_sz, &dma_handle);
if (!mtts)
return -ENOMEM;

Expand All @@ -580,15 +582,25 @@ int __mlx4_write_mtt(struct mlx4_dev *dev, struct mlx4_mtt *mtt,
{
int err = 0;
int chunk;
int mtts_per_page;
int max_mtts_first_page;

/* compute how may mtts fit in the first page */
mtts_per_page = PAGE_SIZE / sizeof(u64);
max_mtts_first_page = mtts_per_page - (mtt->offset + start_index)
% mtts_per_page;

chunk = min_t(int, max_mtts_first_page, npages);

while (npages > 0) {
chunk = min_t(int, PAGE_SIZE / sizeof(u64), npages);
err = mlx4_write_mtt_chunk(dev, mtt, start_index, chunk, page_list);
if (err)
return err;
npages -= chunk;
start_index += chunk;
page_list += chunk;

chunk = min_t(int, mtts_per_page, npages);
}
return err;
}
Expand All @@ -612,18 +624,9 @@ int mlx4_write_mtt(struct mlx4_dev *dev, struct mlx4_mtt *mtt,
inbox = mailbox->buf;

while (npages > 0) {
int s = mtt->first_seg * dev->caps.mtts_per_seg +
start_index;
chunk = min_t(int, MLX4_MAILBOX_SIZE / sizeof(u64) -
dev->caps.mtts_per_seg, npages);
if (s / (PAGE_SIZE / sizeof(u64)) !=
(s + chunk - 1) / (PAGE_SIZE / sizeof(u64)))
chunk = PAGE_SIZE / sizeof(u64) -
(s % (PAGE_SIZE / sizeof(u64)));

inbox[0] = cpu_to_be64(mtt->first_seg *
dev->caps.mtts_per_seg +
start_index);
chunk = min_t(int, MLX4_MAILBOX_SIZE / sizeof(u64) - 2,
npages);
inbox[0] = cpu_to_be64(mtt->offset + start_index);
inbox[1] = 0;
for (i = 0; i < chunk; ++i)
inbox[i + 2] = cpu_to_be64(page_list[i] |
Expand Down Expand Up @@ -690,7 +693,8 @@ int mlx4_init_mr_table(struct mlx4_dev *dev)
return err;

err = mlx4_buddy_init(&mr_table->mtt_buddy,
ilog2(dev->caps.num_mtt_segs));
ilog2(dev->caps.num_mtts /
(1 << log_mtts_per_seg)));
if (err)
goto err_buddy;

Expand Down Expand Up @@ -809,7 +813,7 @@ int mlx4_fmr_alloc(struct mlx4_dev *dev, u32 pd, u32 access, int max_pages,
int max_maps, u8 page_shift, struct mlx4_fmr *fmr)
{
struct mlx4_priv *priv = mlx4_priv(dev);
u64 mtt_seg;
u64 mtt_offset;
int err = -ENOMEM;

if (page_shift < (ffs(dev->caps.page_size_cap) - 1) || page_shift >= 32)
Expand All @@ -829,11 +833,12 @@ int mlx4_fmr_alloc(struct mlx4_dev *dev, u32 pd, u32 access, int max_pages,
if (err)
return err;

mtt_seg = fmr->mr.mtt.first_seg * dev->caps.mtt_entry_sz;
mtt_offset = fmr->mr.mtt.offset * dev->caps.mtt_entry_sz;

fmr->mtts = mlx4_table_find(&priv->mr_table.mtt_table,
fmr->mr.mtt.first_seg,
fmr->mr.mtt.offset,
&fmr->dma_handle);

if (!fmr->mtts) {
err = -ENOMEM;
goto err_free;
Expand Down Expand Up @@ -872,7 +877,7 @@ static int mlx4_fmr_alloc_reserved(struct mlx4_dev *dev, u32 mridx,
return err;

fmr->mtts = mlx4_table_find(&priv->mr_table.mtt_table,
fmr->mr.mtt.first_seg,
fmr->mr.mtt.offset,
&fmr->dma_handle);
if (!fmr->mtts) {
err = -ENOMEM;
Expand Down
4 changes: 2 additions & 2 deletions trunk/drivers/net/ethernet/mellanox/mlx4/profile.c
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ u64 mlx4_make_profile(struct mlx4_dev *dev,
profile[MLX4_RES_EQ].size = dev_cap->eqc_entry_sz;
profile[MLX4_RES_DMPT].size = dev_cap->dmpt_entry_sz;
profile[MLX4_RES_CMPT].size = dev_cap->cmpt_entry_sz;
profile[MLX4_RES_MTT].size = dev->caps.mtts_per_seg * dev_cap->mtt_entry_sz;
profile[MLX4_RES_MTT].size = dev_cap->mtt_entry_sz;
profile[MLX4_RES_MCG].size = mlx4_get_mgm_entry_size(dev);

profile[MLX4_RES_QP].num = request->num_qp;
Expand Down Expand Up @@ -210,7 +210,7 @@ u64 mlx4_make_profile(struct mlx4_dev *dev,
init_hca->cmpt_base = profile[i].start;
break;
case MLX4_RES_MTT:
dev->caps.num_mtt_segs = profile[i].num;
dev->caps.num_mtts = profile[i].num;
priv->mr_table.mtt_base = profile[i].start;
init_hca->mtt_base = profile[i].start;
break;
Expand Down
Loading

0 comments on commit 873cc48

Please sign in to comment.