diff options
author | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2012-11-25 17:23:57 -0500 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2012-11-25 17:23:57 -0500 |
commit | 2a859ab07b6ab66f4134c4fffc341398bd3d328c (patch) | |
tree | c5e7eaf3bffbc18feb326940e39794328d98dc07 /drivers/infiniband | |
parent | cedddd812a79a4fda3885a15711aee3de78c4a24 (diff) | |
parent | e716e014384688d1a50d1aa5213ee74748c6d4e0 (diff) |
Merge branch 'merge' into next
Merge my own merge branch to get various fixes from there
and upstream, especially the hvc console tty refcouting fixes
which which testing is quite a bit harder...
Diffstat (limited to 'drivers/infiniband')
-rw-r--r-- | drivers/infiniband/hw/cxgb4/mem.c | 2 | ||||
-rw-r--r-- | drivers/infiniband/hw/mlx4/alias_GUID.c | 2 | ||||
-rw-r--r-- | drivers/infiniband/hw/mlx4/mad.c | 85 | ||||
-rw-r--r-- | drivers/infiniband/hw/mlx4/mcg.c | 18 |
4 files changed, 52 insertions, 55 deletions
diff --git a/drivers/infiniband/hw/cxgb4/mem.c b/drivers/infiniband/hw/cxgb4/mem.c index 57e07c61ace2..afd81790ab3c 100644 --- a/drivers/infiniband/hw/cxgb4/mem.c +++ b/drivers/infiniband/hw/cxgb4/mem.c | |||
@@ -468,7 +468,7 @@ struct ib_mr *c4iw_register_phys_mem(struct ib_pd *pd, | |||
468 | ret = alloc_pbl(mhp, npages); | 468 | ret = alloc_pbl(mhp, npages); |
469 | if (ret) { | 469 | if (ret) { |
470 | kfree(page_list); | 470 | kfree(page_list); |
471 | goto err_pbl; | 471 | goto err; |
472 | } | 472 | } |
473 | 473 | ||
474 | ret = write_pbl(&mhp->rhp->rdev, page_list, mhp->attr.pbl_addr, | 474 | ret = write_pbl(&mhp->rhp->rdev, page_list, mhp->attr.pbl_addr, |
diff --git a/drivers/infiniband/hw/mlx4/alias_GUID.c b/drivers/infiniband/hw/mlx4/alias_GUID.c index d2fb38d43571..2f215b93db6b 100644 --- a/drivers/infiniband/hw/mlx4/alias_GUID.c +++ b/drivers/infiniband/hw/mlx4/alias_GUID.c | |||
@@ -107,7 +107,7 @@ static __be64 get_cached_alias_guid(struct mlx4_ib_dev *dev, int port, int index | |||
107 | { | 107 | { |
108 | if (index >= NUM_ALIAS_GUID_PER_PORT) { | 108 | if (index >= NUM_ALIAS_GUID_PER_PORT) { |
109 | pr_err("%s: ERROR: asked for index:%d\n", __func__, index); | 109 | pr_err("%s: ERROR: asked for index:%d\n", __func__, index); |
110 | return (__force __be64) ((u64) 0xFFFFFFFFFFFFFFFFUL); | 110 | return (__force __be64) -1; |
111 | } | 111 | } |
112 | return *(__be64 *)&dev->sriov.demux[port - 1].guid_cache[index]; | 112 | return *(__be64 *)&dev->sriov.demux[port - 1].guid_cache[index]; |
113 | } | 113 | } |
diff --git a/drivers/infiniband/hw/mlx4/mad.c b/drivers/infiniband/hw/mlx4/mad.c index 21a794152d15..0a903c129f0a 100644 --- a/drivers/infiniband/hw/mlx4/mad.c +++ b/drivers/infiniband/hw/mlx4/mad.c | |||
@@ -409,38 +409,45 @@ int mlx4_ib_find_real_gid(struct ib_device *ibdev, u8 port, __be64 guid) | |||
409 | } | 409 | } |
410 | 410 | ||
411 | 411 | ||
412 | static int get_pkey_phys_indices(struct mlx4_ib_dev *ibdev, u8 port, u8 ph_pkey_ix, | 412 | static int find_slave_port_pkey_ix(struct mlx4_ib_dev *dev, int slave, |
413 | u8 *full_pk_ix, u8 *partial_pk_ix, | 413 | u8 port, u16 pkey, u16 *ix) |
414 | int *is_full_member) | ||
415 | { | 414 | { |
416 | u16 search_pkey; | 415 | int i, ret; |
417 | int fm; | 416 | u8 unassigned_pkey_ix, pkey_ix, partial_ix = 0xFF; |
418 | int err = 0; | 417 | u16 slot_pkey; |
419 | u16 pk; | ||
420 | 418 | ||
421 | err = ib_get_cached_pkey(&ibdev->ib_dev, port, ph_pkey_ix, &search_pkey); | 419 | if (slave == mlx4_master_func_num(dev->dev)) |
422 | if (err) | 420 | return ib_find_cached_pkey(&dev->ib_dev, port, pkey, ix); |
423 | return err; | ||
424 | 421 | ||
425 | fm = (search_pkey & 0x8000) ? 1 : 0; | 422 | unassigned_pkey_ix = dev->dev->phys_caps.pkey_phys_table_len[port] - 1; |
426 | if (fm) { | ||
427 | *full_pk_ix = ph_pkey_ix; | ||
428 | search_pkey &= 0x7FFF; | ||
429 | } else { | ||
430 | *partial_pk_ix = ph_pkey_ix; | ||
431 | search_pkey |= 0x8000; | ||
432 | } | ||
433 | 423 | ||
434 | if (ib_find_exact_cached_pkey(&ibdev->ib_dev, port, search_pkey, &pk)) | 424 | for (i = 0; i < dev->dev->caps.pkey_table_len[port]; i++) { |
435 | pk = 0xFFFF; | 425 | if (dev->pkeys.virt2phys_pkey[slave][port - 1][i] == unassigned_pkey_ix) |
426 | continue; | ||
436 | 427 | ||
437 | if (fm) | 428 | pkey_ix = dev->pkeys.virt2phys_pkey[slave][port - 1][i]; |
438 | *partial_pk_ix = (pk & 0xFF); | ||
439 | else | ||
440 | *full_pk_ix = (pk & 0xFF); | ||
441 | 429 | ||
442 | *is_full_member = fm; | 430 | ret = ib_get_cached_pkey(&dev->ib_dev, port, pkey_ix, &slot_pkey); |
443 | return err; | 431 | if (ret) |
432 | continue; | ||
433 | if ((slot_pkey & 0x7FFF) == (pkey & 0x7FFF)) { | ||
434 | if (slot_pkey & 0x8000) { | ||
435 | *ix = (u16) pkey_ix; | ||
436 | return 0; | ||
437 | } else { | ||
438 | /* take first partial pkey index found */ | ||
439 | if (partial_ix == 0xFF) | ||
440 | partial_ix = pkey_ix; | ||
441 | } | ||
442 | } | ||
443 | } | ||
444 | |||
445 | if (partial_ix < 0xFF) { | ||
446 | *ix = (u16) partial_ix; | ||
447 | return 0; | ||
448 | } | ||
449 | |||
450 | return -EINVAL; | ||
444 | } | 451 | } |
445 | 452 | ||
446 | int mlx4_ib_send_to_slave(struct mlx4_ib_dev *dev, int slave, u8 port, | 453 | int mlx4_ib_send_to_slave(struct mlx4_ib_dev *dev, int slave, u8 port, |
@@ -458,10 +465,8 @@ int mlx4_ib_send_to_slave(struct mlx4_ib_dev *dev, int slave, u8 port, | |||
458 | unsigned tun_tx_ix = 0; | 465 | unsigned tun_tx_ix = 0; |
459 | int dqpn; | 466 | int dqpn; |
460 | int ret = 0; | 467 | int ret = 0; |
461 | int i; | ||
462 | int is_full_member = 0; | ||
463 | u16 tun_pkey_ix; | 468 | u16 tun_pkey_ix; |
464 | u8 ph_pkey_ix, full_pk_ix = 0, partial_pk_ix = 0; | 469 | u16 cached_pkey; |
465 | 470 | ||
466 | if (dest_qpt > IB_QPT_GSI) | 471 | if (dest_qpt > IB_QPT_GSI) |
467 | return -EINVAL; | 472 | return -EINVAL; |
@@ -481,27 +486,17 @@ int mlx4_ib_send_to_slave(struct mlx4_ib_dev *dev, int slave, u8 port, | |||
481 | else | 486 | else |
482 | tun_qp = &tun_ctx->qp[1]; | 487 | tun_qp = &tun_ctx->qp[1]; |
483 | 488 | ||
484 | /* compute pkey index for slave */ | 489 | /* compute P_Key index to put in tunnel header for slave */ |
485 | /* get physical pkey -- virtualized Dom0 pkey to phys*/ | ||
486 | if (dest_qpt) { | 490 | if (dest_qpt) { |
487 | ph_pkey_ix = | 491 | u16 pkey_ix; |
488 | dev->pkeys.virt2phys_pkey[mlx4_master_func_num(dev->dev)][port - 1][wc->pkey_index]; | 492 | ret = ib_get_cached_pkey(&dev->ib_dev, port, wc->pkey_index, &cached_pkey); |
489 | |||
490 | /* now, translate this to the slave pkey index */ | ||
491 | ret = get_pkey_phys_indices(dev, port, ph_pkey_ix, &full_pk_ix, | ||
492 | &partial_pk_ix, &is_full_member); | ||
493 | if (ret) | 493 | if (ret) |
494 | return -EINVAL; | 494 | return -EINVAL; |
495 | 495 | ||
496 | for (i = 0; i < dev->dev->caps.pkey_table_len[port]; i++) { | 496 | ret = find_slave_port_pkey_ix(dev, slave, port, cached_pkey, &pkey_ix); |
497 | if ((dev->pkeys.virt2phys_pkey[slave][port - 1][i] == full_pk_ix) || | 497 | if (ret) |
498 | (is_full_member && | ||
499 | (dev->pkeys.virt2phys_pkey[slave][port - 1][i] == partial_pk_ix))) | ||
500 | break; | ||
501 | } | ||
502 | if (i == dev->dev->caps.pkey_table_len[port]) | ||
503 | return -EINVAL; | 498 | return -EINVAL; |
504 | tun_pkey_ix = i; | 499 | tun_pkey_ix = pkey_ix; |
505 | } else | 500 | } else |
506 | tun_pkey_ix = dev->pkeys.virt2phys_pkey[slave][port - 1][0]; | 501 | tun_pkey_ix = dev->pkeys.virt2phys_pkey[slave][port - 1][0]; |
507 | 502 | ||
diff --git a/drivers/infiniband/hw/mlx4/mcg.c b/drivers/infiniband/hw/mlx4/mcg.c index 3c3b54c3fdd9..25b2cdff00f8 100644 --- a/drivers/infiniband/hw/mlx4/mcg.c +++ b/drivers/infiniband/hw/mlx4/mcg.c | |||
@@ -233,7 +233,8 @@ static int send_mad_to_slave(int slave, struct mlx4_ib_demux_ctx *ctx, | |||
233 | 233 | ||
234 | ib_query_ah(dev->sm_ah[ctx->port - 1], &ah_attr); | 234 | ib_query_ah(dev->sm_ah[ctx->port - 1], &ah_attr); |
235 | 235 | ||
236 | wc.pkey_index = 0; | 236 | if (ib_find_cached_pkey(&dev->ib_dev, ctx->port, IB_DEFAULT_PKEY_FULL, &wc.pkey_index)) |
237 | return -EINVAL; | ||
237 | wc.sl = 0; | 238 | wc.sl = 0; |
238 | wc.dlid_path_bits = 0; | 239 | wc.dlid_path_bits = 0; |
239 | wc.port_num = ctx->port; | 240 | wc.port_num = ctx->port; |
@@ -1074,10 +1075,6 @@ static void _mlx4_ib_mcg_port_cleanup(struct mlx4_ib_demux_ctx *ctx, int destroy | |||
1074 | unsigned long end; | 1075 | unsigned long end; |
1075 | int count; | 1076 | int count; |
1076 | 1077 | ||
1077 | if (ctx->flushing) | ||
1078 | return; | ||
1079 | |||
1080 | ctx->flushing = 1; | ||
1081 | for (i = 0; i < MAX_VFS; ++i) | 1078 | for (i = 0; i < MAX_VFS; ++i) |
1082 | clean_vf_mcast(ctx, i); | 1079 | clean_vf_mcast(ctx, i); |
1083 | 1080 | ||
@@ -1107,9 +1104,6 @@ static void _mlx4_ib_mcg_port_cleanup(struct mlx4_ib_demux_ctx *ctx, int destroy | |||
1107 | force_clean_group(group); | 1104 | force_clean_group(group); |
1108 | } | 1105 | } |
1109 | mutex_unlock(&ctx->mcg_table_lock); | 1106 | mutex_unlock(&ctx->mcg_table_lock); |
1110 | |||
1111 | if (!destroy_wq) | ||
1112 | ctx->flushing = 0; | ||
1113 | } | 1107 | } |
1114 | 1108 | ||
1115 | struct clean_work { | 1109 | struct clean_work { |
@@ -1123,6 +1117,7 @@ static void mcg_clean_task(struct work_struct *work) | |||
1123 | struct clean_work *cw = container_of(work, struct clean_work, work); | 1117 | struct clean_work *cw = container_of(work, struct clean_work, work); |
1124 | 1118 | ||
1125 | _mlx4_ib_mcg_port_cleanup(cw->ctx, cw->destroy_wq); | 1119 | _mlx4_ib_mcg_port_cleanup(cw->ctx, cw->destroy_wq); |
1120 | cw->ctx->flushing = 0; | ||
1126 | kfree(cw); | 1121 | kfree(cw); |
1127 | } | 1122 | } |
1128 | 1123 | ||
@@ -1130,13 +1125,20 @@ void mlx4_ib_mcg_port_cleanup(struct mlx4_ib_demux_ctx *ctx, int destroy_wq) | |||
1130 | { | 1125 | { |
1131 | struct clean_work *work; | 1126 | struct clean_work *work; |
1132 | 1127 | ||
1128 | if (ctx->flushing) | ||
1129 | return; | ||
1130 | |||
1131 | ctx->flushing = 1; | ||
1132 | |||
1133 | if (destroy_wq) { | 1133 | if (destroy_wq) { |
1134 | _mlx4_ib_mcg_port_cleanup(ctx, destroy_wq); | 1134 | _mlx4_ib_mcg_port_cleanup(ctx, destroy_wq); |
1135 | ctx->flushing = 0; | ||
1135 | return; | 1136 | return; |
1136 | } | 1137 | } |
1137 | 1138 | ||
1138 | work = kmalloc(sizeof *work, GFP_KERNEL); | 1139 | work = kmalloc(sizeof *work, GFP_KERNEL); |
1139 | if (!work) { | 1140 | if (!work) { |
1141 | ctx->flushing = 0; | ||
1140 | mcg_warn("failed allocating work for cleanup\n"); | 1142 | mcg_warn("failed allocating work for cleanup\n"); |
1141 | return; | 1143 | return; |
1142 | } | 1144 | } |