mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-10 21:07:02 +09:00
IB/qib: Change lkey table allocation to support more MRs
commit d6f1c17e16 upstream.
The lkey table is allocated with with a get_user_pages() with an
order based on a number of index bits from a module parameter.
The underlying kernel code cannot allocate that many contiguous pages.
There is no reason the underlying memory needs to be physically
contiguous.
This patch:
- switches the allocation/deallocation to vmalloc/vfree
- caps the number of bits to 23 to insure at least 1 generation bit
o this matches the module parameter description
Reviewed-by: Vinit Agnihotri <vinit.abhay.agnihotri@intel.com>
Signed-off-by: Mike Marciniszyn <mike.marciniszyn@intel.com>
Signed-off-by: Doug Ledford <dledford@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
480ed182e3
commit
ef5844a015
@@ -1467,27 +1467,22 @@ extern struct mutex qib_mutex;
|
||||
* first to avoid possible serial port delays from printk.
|
||||
*/
|
||||
#define qib_early_err(dev, fmt, ...) \
|
||||
do { \
|
||||
dev_err(dev, fmt, ##__VA_ARGS__); \
|
||||
} while (0)
|
||||
dev_err(dev, fmt, ##__VA_ARGS__)
|
||||
|
||||
#define qib_dev_err(dd, fmt, ...) \
|
||||
do { \
|
||||
dev_err(&(dd)->pcidev->dev, "%s: " fmt, \
|
||||
qib_get_unit_name((dd)->unit), ##__VA_ARGS__); \
|
||||
} while (0)
|
||||
dev_err(&(dd)->pcidev->dev, "%s: " fmt, \
|
||||
qib_get_unit_name((dd)->unit), ##__VA_ARGS__)
|
||||
|
||||
#define qib_dev_warn(dd, fmt, ...) \
|
||||
dev_warn(&(dd)->pcidev->dev, "%s: " fmt, \
|
||||
qib_get_unit_name((dd)->unit), ##__VA_ARGS__)
|
||||
|
||||
#define qib_dev_porterr(dd, port, fmt, ...) \
|
||||
do { \
|
||||
dev_err(&(dd)->pcidev->dev, "%s: IB%u:%u " fmt, \
|
||||
qib_get_unit_name((dd)->unit), (dd)->unit, (port), \
|
||||
##__VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
dev_err(&(dd)->pcidev->dev, "%s: IB%u:%u " fmt, \
|
||||
qib_get_unit_name((dd)->unit), (dd)->unit, (port), \
|
||||
##__VA_ARGS__)
|
||||
#define qib_devinfo(pcidev, fmt, ...) \
|
||||
do { \
|
||||
dev_info(&(pcidev)->dev, fmt, ##__VA_ARGS__); \
|
||||
} while (0)
|
||||
dev_info(&(pcidev)->dev, fmt, ##__VA_ARGS__)
|
||||
|
||||
/*
|
||||
* this is used for formatting hw error messages...
|
||||
|
||||
@@ -86,6 +86,10 @@ int qib_alloc_lkey(struct qib_mregion *mr, int dma_region)
|
||||
* unrestricted LKEY.
|
||||
*/
|
||||
rkt->gen++;
|
||||
/*
|
||||
* bits are capped in qib_verbs.c to insure enough bits
|
||||
* for generation number
|
||||
*/
|
||||
mr->lkey = (r << (32 - ib_qib_lkey_table_size)) |
|
||||
((((1 << (24 - ib_qib_lkey_table_size)) - 1) & rkt->gen)
|
||||
<< 8);
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
#include <linux/rculist.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/random.h>
|
||||
#include <linux/vmalloc.h>
|
||||
|
||||
#include "qib.h"
|
||||
#include "qib_common.h"
|
||||
@@ -2084,10 +2085,16 @@ int qib_register_ib_device(struct qib_devdata *dd)
|
||||
* the LKEY). The remaining bits act as a generation number or tag.
|
||||
*/
|
||||
spin_lock_init(&dev->lk_table.lock);
|
||||
/* insure generation is at least 4 bits see keys.c */
|
||||
if (ib_qib_lkey_table_size > MAX_LKEY_TABLE_BITS) {
|
||||
qib_dev_warn(dd, "lkey bits %u too large, reduced to %u\n",
|
||||
ib_qib_lkey_table_size, MAX_LKEY_TABLE_BITS);
|
||||
ib_qib_lkey_table_size = MAX_LKEY_TABLE_BITS;
|
||||
}
|
||||
dev->lk_table.max = 1 << ib_qib_lkey_table_size;
|
||||
lk_tab_size = dev->lk_table.max * sizeof(*dev->lk_table.table);
|
||||
dev->lk_table.table = (struct qib_mregion __rcu **)
|
||||
__get_free_pages(GFP_KERNEL, get_order(lk_tab_size));
|
||||
vmalloc(lk_tab_size);
|
||||
if (dev->lk_table.table == NULL) {
|
||||
ret = -ENOMEM;
|
||||
goto err_lk;
|
||||
@@ -2260,7 +2267,7 @@ err_tx:
|
||||
sizeof(struct qib_pio_header),
|
||||
dev->pio_hdrs, dev->pio_hdrs_phys);
|
||||
err_hdrs:
|
||||
free_pages((unsigned long) dev->lk_table.table, get_order(lk_tab_size));
|
||||
vfree(dev->lk_table.table);
|
||||
err_lk:
|
||||
kfree(dev->qp_table);
|
||||
err_qpt:
|
||||
@@ -2314,8 +2321,7 @@ void qib_unregister_ib_device(struct qib_devdata *dd)
|
||||
sizeof(struct qib_pio_header),
|
||||
dev->pio_hdrs, dev->pio_hdrs_phys);
|
||||
lk_tab_size = dev->lk_table.max * sizeof(*dev->lk_table.table);
|
||||
free_pages((unsigned long) dev->lk_table.table,
|
||||
get_order(lk_tab_size));
|
||||
vfree(dev->lk_table.table);
|
||||
kfree(dev->qp_table);
|
||||
}
|
||||
|
||||
|
||||
@@ -645,6 +645,8 @@ struct qib_qpn_table {
|
||||
struct qpn_map map[QPNMAP_ENTRIES];
|
||||
};
|
||||
|
||||
#define MAX_LKEY_TABLE_BITS 23
|
||||
|
||||
struct qib_lkey_table {
|
||||
spinlock_t lock; /* protect changes in this struct */
|
||||
u32 next; /* next unused index (speeds search) */
|
||||
|
||||
Reference in New Issue
Block a user