Browse Source

[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.
tags/v0.9.8
Michael Brown 14 years ago
parent
commit
0b1222f233
2 changed files with 7 additions and 6 deletions
  1. 5
    4
      src/drivers/infiniband/hermon.c
  2. 2
    2
      src/drivers/infiniband/hermon.h

+ 5
- 4
src/drivers/infiniband/hermon.c View File

@@ -857,7 +857,8 @@ static int hermon_alloc_qpn ( struct ib_device *ibdev,
857 857
 			       hermon );
858 858
 			return qpn_offset;
859 859
 		}
860
-		qp->qpn = ( hermon->qpn_base + qpn_offset );
860
+		qp->qpn = ( ( random() & HERMON_QPN_RANDOM_MASK ) |
861
+			    ( hermon->qpn_base + qpn_offset ) );
861 862
 		return 0;
862 863
 	default:
863 864
 		DBGC ( hermon, "Hermon %p unsupported QP type %d\n",
@@ -877,7 +878,8 @@ static void hermon_free_qpn ( struct ib_device *ibdev,
877 878
 	struct hermon *hermon = ib_get_drvdata ( ibdev );
878 879
 	int qpn_offset;
879 880
 
880
-	qpn_offset = ( qp->qpn - hermon->qpn_base );
881
+	qpn_offset = ( ( qp->qpn & ~HERMON_QPN_RANDOM_MASK )
882
+		       - hermon->qpn_base );
881 883
 	if ( qpn_offset >= 0 )
882 884
 		hermon_bitmask_free ( hermon->qp_inuse, qpn_offset, 1 );
883 885
 }
@@ -2529,8 +2531,7 @@ static int hermon_configure_special_qps ( struct hermon *hermon ) {
2529 2531
 	int rc;
2530 2532
 
2531 2533
 	/* Special QP block must be aligned on its own size */
2532
-	hermon->special_qpn_base = ( ( HERMON_QPN_BASE +
2533
-				       hermon->cap.reserved_qps +
2534
+	hermon->special_qpn_base = ( ( hermon->cap.reserved_qps +
2534 2535
 				       HERMON_NUM_SPECIAL_QPS - 1 )
2535 2536
 				     & ~( HERMON_NUM_SPECIAL_QPS - 1 ) );
2536 2537
 	hermon->qpn_base = ( hermon->special_qpn_base +

+ 2
- 2
src/drivers/infiniband/hermon.h View File

@@ -422,8 +422,8 @@ struct hermon_recv_work_queue {
422 422
  */
423 423
 #define HERMON_MAX_QPS		8
424 424
 
425
-/** Base queue pair number */
426
-#define HERMON_QPN_BASE 0x550000
425
+/** Queue pair number randomisation mask */
426
+#define HERMON_QPN_RANDOM_MASK 0xfff000
427 427
 
428 428
 /** Hermon queue pair state */
429 429
 enum hermon_queue_pair_state {

Loading…
Cancel
Save