From 0b1222f2332e89bcece1912ec6058479b45f62f1 Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Sun, 9 Aug 2009 20:38:35 +0100 Subject: [hermon] Randomise the high-order bits of queue pair numbers The Infiniband Communication Manager will refuse to establish a connection if it believes the connection is already established. There is no immediately obvious way to ask it to tear down the existing connection and replace it; to issue a DREP we would need to know the local and remote communication IDs used for the previous connection setup. We can work around this by randomising the high-order bits of the queue pair number; these have no significance to the hardware, but are sufficient to convince the IB CM that this is a different connection. --- src/drivers/infiniband/hermon.c | 9 +++++---- src/drivers/infiniband/hermon.h | 4 ++-- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/drivers/infiniband/hermon.c b/src/drivers/infiniband/hermon.c index 6e2f3230..0012904f 100644 --- a/src/drivers/infiniband/hermon.c +++ b/src/drivers/infiniband/hermon.c @@ -857,7 +857,8 @@ static int hermon_alloc_qpn ( struct ib_device *ibdev, hermon ); return qpn_offset; } - qp->qpn = ( hermon->qpn_base + qpn_offset ); + qp->qpn = ( ( random() & HERMON_QPN_RANDOM_MASK ) | + ( hermon->qpn_base + qpn_offset ) ); return 0; default: DBGC ( hermon, "Hermon %p unsupported QP type %d\n", @@ -877,7 +878,8 @@ static void hermon_free_qpn ( struct ib_device *ibdev, struct hermon *hermon = ib_get_drvdata ( ibdev ); int qpn_offset; - qpn_offset = ( qp->qpn - hermon->qpn_base ); + qpn_offset = ( ( qp->qpn & ~HERMON_QPN_RANDOM_MASK ) + - hermon->qpn_base ); if ( qpn_offset >= 0 ) hermon_bitmask_free ( hermon->qp_inuse, qpn_offset, 1 ); } @@ -2529,8 +2531,7 @@ static int hermon_configure_special_qps ( struct hermon *hermon ) { int rc; /* Special QP block must be aligned on its own size */ - hermon->special_qpn_base = ( ( HERMON_QPN_BASE + - hermon->cap.reserved_qps + + hermon->special_qpn_base = ( ( hermon->cap.reserved_qps + HERMON_NUM_SPECIAL_QPS - 1 ) & ~( HERMON_NUM_SPECIAL_QPS - 1 ) ); hermon->qpn_base = ( hermon->special_qpn_base + diff --git a/src/drivers/infiniband/hermon.h b/src/drivers/infiniband/hermon.h index c3d895c6..f19fd359 100644 --- a/src/drivers/infiniband/hermon.h +++ b/src/drivers/infiniband/hermon.h @@ -422,8 +422,8 @@ struct hermon_recv_work_queue { */ #define HERMON_MAX_QPS 8 -/** Base queue pair number */ -#define HERMON_QPN_BASE 0x550000 +/** Queue pair number randomisation mask */ +#define HERMON_QPN_RANDOM_MASK 0xfff000 /** Hermon queue pair state */ enum hermon_queue_pair_state { -- cgit v1.2.3-55-g7522