IB/ehca: Change meaning of hca_cap_mr_pgsize
ehca_shca.hca_cap_mr_pgsize now contains all supported page sizes ORed together. This makes some checks easier to code and understand, plus we can return this value verbatim in query_hca(), fixing a problem with SRP (reported by Anton Blanchard -- thanks!). Signed-off-by: Joachim Fenkes <fenkes@de.ibm.com> Signed-off-by: Roland Dreier <rolandd@cisco.com>
This commit is contained in:
parent
8c08d50d4f
commit
abc39d3672
|
@ -323,7 +323,6 @@ extern int ehca_static_rate;
|
||||||
extern int ehca_port_act_time;
|
extern int ehca_port_act_time;
|
||||||
extern int ehca_use_hp_mr;
|
extern int ehca_use_hp_mr;
|
||||||
extern int ehca_scaling_code;
|
extern int ehca_scaling_code;
|
||||||
extern int ehca_mr_largepage;
|
|
||||||
|
|
||||||
struct ipzu_queue_resp {
|
struct ipzu_queue_resp {
|
||||||
u32 qe_size; /* queue entry size */
|
u32 qe_size; /* queue entry size */
|
||||||
|
|
|
@ -77,6 +77,7 @@ int ehca_query_device(struct ib_device *ibdev, struct ib_device_attr *props)
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(props, 0, sizeof(struct ib_device_attr));
|
memset(props, 0, sizeof(struct ib_device_attr));
|
||||||
|
props->page_size_cap = shca->hca_cap_mr_pgsize;
|
||||||
props->fw_ver = rblock->hw_ver;
|
props->fw_ver = rblock->hw_ver;
|
||||||
props->max_mr_size = rblock->max_mr_size;
|
props->max_mr_size = rblock->max_mr_size;
|
||||||
props->vendor_id = rblock->vendor_id >> 8;
|
props->vendor_id = rblock->vendor_id >> 8;
|
||||||
|
|
|
@ -260,13 +260,20 @@ static struct cap_descr {
|
||||||
{ HCA_CAP_MINI_QP, "HCA_CAP_MINI_QP" },
|
{ HCA_CAP_MINI_QP, "HCA_CAP_MINI_QP" },
|
||||||
};
|
};
|
||||||
|
|
||||||
int ehca_sense_attributes(struct ehca_shca *shca)
|
static int ehca_sense_attributes(struct ehca_shca *shca)
|
||||||
{
|
{
|
||||||
int i, ret = 0;
|
int i, ret = 0;
|
||||||
u64 h_ret;
|
u64 h_ret;
|
||||||
struct hipz_query_hca *rblock;
|
struct hipz_query_hca *rblock;
|
||||||
struct hipz_query_port *port;
|
struct hipz_query_port *port;
|
||||||
|
|
||||||
|
static const u32 pgsize_map[] = {
|
||||||
|
HCA_CAP_MR_PGSIZE_4K, 0x1000,
|
||||||
|
HCA_CAP_MR_PGSIZE_64K, 0x10000,
|
||||||
|
HCA_CAP_MR_PGSIZE_1M, 0x100000,
|
||||||
|
HCA_CAP_MR_PGSIZE_16M, 0x1000000,
|
||||||
|
};
|
||||||
|
|
||||||
rblock = ehca_alloc_fw_ctrlblock(GFP_KERNEL);
|
rblock = ehca_alloc_fw_ctrlblock(GFP_KERNEL);
|
||||||
if (!rblock) {
|
if (!rblock) {
|
||||||
ehca_gen_err("Cannot allocate rblock memory.");
|
ehca_gen_err("Cannot allocate rblock memory.");
|
||||||
|
@ -329,8 +336,15 @@ int ehca_sense_attributes(struct ehca_shca *shca)
|
||||||
if (EHCA_BMASK_GET(hca_cap_descr[i].mask, shca->hca_cap))
|
if (EHCA_BMASK_GET(hca_cap_descr[i].mask, shca->hca_cap))
|
||||||
ehca_gen_dbg(" %s", hca_cap_descr[i].descr);
|
ehca_gen_dbg(" %s", hca_cap_descr[i].descr);
|
||||||
|
|
||||||
shca->hca_cap_mr_pgsize = rblock->memory_page_size_supported;
|
/* translate supported MR page sizes; always support 4K */
|
||||||
|
shca->hca_cap_mr_pgsize = EHCA_PAGESIZE;
|
||||||
|
if (ehca_mr_largepage) { /* support extra sizes only if enabled */
|
||||||
|
for (i = 0; i < ARRAY_SIZE(pgsize_map); i += 2)
|
||||||
|
if (rblock->memory_page_size_supported & pgsize_map[i])
|
||||||
|
shca->hca_cap_mr_pgsize |= pgsize_map[i + 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* query max MTU from first port -- it's the same for all ports */
|
||||||
port = (struct hipz_query_port *)rblock;
|
port = (struct hipz_query_port *)rblock;
|
||||||
h_ret = hipz_h_query_port(shca->ipz_hca_handle, 1, port);
|
h_ret = hipz_h_query_port(shca->ipz_hca_handle, 1, port);
|
||||||
if (h_ret != H_SUCCESS) {
|
if (h_ret != H_SUCCESS) {
|
||||||
|
|
|
@ -79,9 +79,7 @@ static u32 ehca_encode_hwpage_size(u32 pgsize)
|
||||||
|
|
||||||
static u64 ehca_get_max_hwpage_size(struct ehca_shca *shca)
|
static u64 ehca_get_max_hwpage_size(struct ehca_shca *shca)
|
||||||
{
|
{
|
||||||
if (shca->hca_cap_mr_pgsize & HCA_CAP_MR_PGSIZE_16M)
|
return 1UL << ilog2(shca->hca_cap_mr_pgsize);
|
||||||
return EHCA_MR_PGSIZE16M;
|
|
||||||
return EHCA_MR_PGSIZE4K;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct ehca_mr *ehca_mr_new(void)
|
static struct ehca_mr *ehca_mr_new(void)
|
||||||
|
@ -288,7 +286,7 @@ struct ib_mr *ehca_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
|
||||||
container_of(pd->device, struct ehca_shca, ib_device);
|
container_of(pd->device, struct ehca_shca, ib_device);
|
||||||
struct ehca_pd *e_pd = container_of(pd, struct ehca_pd, ib_pd);
|
struct ehca_pd *e_pd = container_of(pd, struct ehca_pd, ib_pd);
|
||||||
struct ehca_mr_pginfo pginfo;
|
struct ehca_mr_pginfo pginfo;
|
||||||
int ret;
|
int ret, page_shift;
|
||||||
u32 num_kpages;
|
u32 num_kpages;
|
||||||
u32 num_hwpages;
|
u32 num_hwpages;
|
||||||
u64 hwpage_size;
|
u64 hwpage_size;
|
||||||
|
@ -343,19 +341,20 @@ struct ib_mr *ehca_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
|
||||||
/* determine number of MR pages */
|
/* determine number of MR pages */
|
||||||
num_kpages = NUM_CHUNKS((virt % PAGE_SIZE) + length, PAGE_SIZE);
|
num_kpages = NUM_CHUNKS((virt % PAGE_SIZE) + length, PAGE_SIZE);
|
||||||
/* select proper hw_pgsize */
|
/* select proper hw_pgsize */
|
||||||
if (ehca_mr_largepage &&
|
page_shift = PAGE_SHIFT;
|
||||||
(shca->hca_cap_mr_pgsize & HCA_CAP_MR_PGSIZE_16M)) {
|
if (e_mr->umem->hugetlb) {
|
||||||
int page_shift = PAGE_SHIFT;
|
/* determine page_shift, clamp between 4K and 16M */
|
||||||
if (e_mr->umem->hugetlb) {
|
page_shift = (fls64(length - 1) + 3) & ~3;
|
||||||
/* determine page_shift, clamp between 4K and 16M */
|
page_shift = min(max(page_shift, EHCA_MR_PGSHIFT4K),
|
||||||
page_shift = (fls64(length - 1) + 3) & ~3;
|
EHCA_MR_PGSHIFT16M);
|
||||||
page_shift = min(max(page_shift, EHCA_MR_PGSHIFT4K),
|
}
|
||||||
EHCA_MR_PGSHIFT16M);
|
hwpage_size = 1UL << page_shift;
|
||||||
}
|
|
||||||
hwpage_size = 1UL << page_shift;
|
/* now that we have the desired page size, shift until it's
|
||||||
} else
|
* supported, too. 4K is always supported, so this terminates.
|
||||||
hwpage_size = EHCA_MR_PGSIZE4K; /* ehca1 only supports 4k */
|
*/
|
||||||
ehca_dbg(pd->device, "hwpage_size=%lx", hwpage_size);
|
while (!(hwpage_size & shca->hca_cap_mr_pgsize))
|
||||||
|
hwpage_size >>= 4;
|
||||||
|
|
||||||
reg_user_mr_fallback:
|
reg_user_mr_fallback:
|
||||||
num_hwpages = NUM_CHUNKS((virt % hwpage_size) + length, hwpage_size);
|
num_hwpages = NUM_CHUNKS((virt % hwpage_size) + length, hwpage_size);
|
||||||
|
@ -801,8 +800,9 @@ struct ib_fmr *ehca_alloc_fmr(struct ib_pd *pd,
|
||||||
ib_fmr = ERR_PTR(-EINVAL);
|
ib_fmr = ERR_PTR(-EINVAL);
|
||||||
goto alloc_fmr_exit0;
|
goto alloc_fmr_exit0;
|
||||||
}
|
}
|
||||||
hw_pgsize = ehca_get_max_hwpage_size(shca);
|
|
||||||
if ((1 << fmr_attr->page_shift) != hw_pgsize) {
|
hw_pgsize = 1 << fmr_attr->page_shift;
|
||||||
|
if (!(hw_pgsize & shca->hca_cap_mr_pgsize)) {
|
||||||
ehca_err(pd->device, "unsupported fmr_attr->page_shift=%x",
|
ehca_err(pd->device, "unsupported fmr_attr->page_shift=%x",
|
||||||
fmr_attr->page_shift);
|
fmr_attr->page_shift);
|
||||||
ib_fmr = ERR_PTR(-EINVAL);
|
ib_fmr = ERR_PTR(-EINVAL);
|
||||||
|
|
Loading…
Reference in a new issue