diff options
author | Jack Morgenstein <jackm@dev.mellanox.co.il> | 2007-08-01 05:28:53 -0400 |
---|---|---|
committer | Roland Dreier <rolandd@cisco.com> | 2007-10-09 22:59:16 -0400 |
commit | d7bb58fb1c0e7264a7261c7d0304121ef9402e94 (patch) | |
tree | aefbae7ee4b4b84022a7646372ddfcdb0a99e72f /drivers/net/mlx4/mr.c | |
parent | 121964ec38d3e17b5ea6183b3c0571df2f4b0eb6 (diff) |
mlx4_core: Write MTTs from CPU instead with of WRITE_MTT FW command
Write MTT entries directly to ICM from the driver (eliminating use of
WRITE_MTT command). This reduces the number of FW commands needed to
register an MR by at least a factor of 2 and speeds up memory
registration significantly. This code will also be used to implement
FMRs.
Signed-off-by: Jack Morgenstein <jackm@dev.mellanox.co.il>
Signed-off-by: Michael S. Tsirkin <mst@dev.mellanox.co.il>
Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/net/mlx4/mr.c')
-rw-r--r-- | drivers/net/mlx4/mr.c | 73 |
1 files changed, 36 insertions, 37 deletions
diff --git a/drivers/net/mlx4/mr.c b/drivers/net/mlx4/mr.c index 60a6ee27cfd4..3cc98c699aaf 100644 --- a/drivers/net/mlx4/mr.c +++ b/drivers/net/mlx4/mr.c | |||
@@ -349,58 +349,57 @@ err_table: | |||
349 | } | 349 | } |
350 | EXPORT_SYMBOL_GPL(mlx4_mr_enable); | 350 | EXPORT_SYMBOL_GPL(mlx4_mr_enable); |
351 | 351 | ||
352 | static int mlx4_WRITE_MTT(struct mlx4_dev *dev, struct mlx4_cmd_mailbox *mailbox, | 352 | static int mlx4_write_mtt_chunk(struct mlx4_dev *dev, struct mlx4_mtt *mtt, |
353 | int num_mtt) | 353 | int start_index, int npages, u64 *page_list) |
354 | { | 354 | { |
355 | return mlx4_cmd(dev, mailbox->dma, num_mtt, 0, MLX4_CMD_WRITE_MTT, | 355 | struct mlx4_priv *priv = mlx4_priv(dev); |
356 | MLX4_CMD_TIME_CLASS_B); | 356 | __be64 *mtts; |
357 | dma_addr_t dma_handle; | ||
358 | int i; | ||
359 | int s = start_index * sizeof (u64); | ||
360 | |||
361 | /* All MTTs must fit in the same page */ | ||
362 | if (start_index / (PAGE_SIZE / sizeof (u64)) != | ||
363 | (start_index + npages - 1) / (PAGE_SIZE / sizeof (u64))) | ||
364 | return -EINVAL; | ||
365 | |||
366 | if (start_index & (MLX4_MTT_ENTRY_PER_SEG - 1)) | ||
367 | return -EINVAL; | ||
368 | |||
369 | mtts = mlx4_table_find(&priv->mr_table.mtt_table, mtt->first_seg + | ||
370 | s / dev->caps.mtt_entry_sz, &dma_handle); | ||
371 | if (!mtts) | ||
372 | return -ENOMEM; | ||
373 | |||
374 | for (i = 0; i < npages; ++i) | ||
375 | mtts[i] = cpu_to_be64(page_list[i] | MLX4_MTT_FLAG_PRESENT); | ||
376 | |||
377 | dma_sync_single(&dev->pdev->dev, dma_handle, npages * sizeof (u64), DMA_TO_DEVICE); | ||
378 | |||
379 | return 0; | ||
357 | } | 380 | } |
358 | 381 | ||
359 | int mlx4_write_mtt(struct mlx4_dev *dev, struct mlx4_mtt *mtt, | 382 | int mlx4_write_mtt(struct mlx4_dev *dev, struct mlx4_mtt *mtt, |
360 | int start_index, int npages, u64 *page_list) | 383 | int start_index, int npages, u64 *page_list) |
361 | { | 384 | { |
362 | struct mlx4_cmd_mailbox *mailbox; | 385 | int chunk; |
363 | __be64 *mtt_entry; | 386 | int err; |
364 | int i; | ||
365 | int err = 0; | ||
366 | 387 | ||
367 | if (mtt->order < 0) | 388 | if (mtt->order < 0) |
368 | return -EINVAL; | 389 | return -EINVAL; |
369 | 390 | ||
370 | mailbox = mlx4_alloc_cmd_mailbox(dev); | ||
371 | if (IS_ERR(mailbox)) | ||
372 | return PTR_ERR(mailbox); | ||
373 | |||
374 | mtt_entry = mailbox->buf; | ||
375 | |||
376 | while (npages > 0) { | 391 | while (npages > 0) { |
377 | mtt_entry[0] = cpu_to_be64(mlx4_mtt_addr(dev, mtt) + start_index * 8); | 392 | chunk = min_t(int, PAGE_SIZE / sizeof(u64), npages); |
378 | mtt_entry[1] = 0; | 393 | err = mlx4_write_mtt_chunk(dev, mtt, start_index, chunk, page_list); |
379 | |||
380 | for (i = 0; i < npages && i < MLX4_MAILBOX_SIZE / 8 - 2; ++i) | ||
381 | mtt_entry[i + 2] = cpu_to_be64(page_list[i] | | ||
382 | MLX4_MTT_FLAG_PRESENT); | ||
383 | |||
384 | /* | ||
385 | * If we have an odd number of entries to write, add | ||
386 | * one more dummy entry for firmware efficiency. | ||
387 | */ | ||
388 | if (i & 1) | ||
389 | mtt_entry[i + 2] = 0; | ||
390 | |||
391 | err = mlx4_WRITE_MTT(dev, mailbox, (i + 1) & ~1); | ||
392 | if (err) | 394 | if (err) |
393 | goto out; | 395 | return err; |
394 | 396 | ||
395 | npages -= i; | 397 | npages -= chunk; |
396 | start_index += i; | 398 | start_index += chunk; |
397 | page_list += i; | 399 | page_list += chunk; |
398 | } | 400 | } |
399 | 401 | ||
400 | out: | 402 | return 0; |
401 | mlx4_free_cmd_mailbox(dev, mailbox); | ||
402 | |||
403 | return err; | ||
404 | } | 403 | } |
405 | EXPORT_SYMBOL_GPL(mlx4_write_mtt); | 404 | EXPORT_SYMBOL_GPL(mlx4_write_mtt); |
406 | 405 | ||