Set the NID in ptlrpc_connection::c_peer to the primary NID of a peer.
This ensures that regardless of the NID used to start a connection, we
consistently use the same NID (the primary NID) to identify a peer. It
also means that PtlRPC will not create multiple connections to a peer.
The primary NID is obtained by calling LNetPrimaryNID(), an addition
to the exported symbols of the LNet module. The name was chosen to
match the existing naming pattern.
Test-Parameters: trivial
Signed-off-by: Olaf Weber <olaf@sgi.com>
Change-Id: Idc0605d17a58678b634db246221028cf81ad2407
Reviewed-on: http://review.whamcloud.com/21710
Tested-by: Jenkins
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Amir Shehata <amir.shehata@intel.com>
Tested-by: Amir Shehata <amir.shehata@intel.com>
int LNetGetId(unsigned int index, lnet_process_id_t *id);
int LNetDist(lnet_nid_t nid, lnet_nid_t *srcnid, __u32 *order);
void LNetSnprintHandle(char *str, int str_len, lnet_handle_any_t handle);
int LNetGetId(unsigned int index, lnet_process_id_t *id);
int LNetDist(lnet_nid_t nid, lnet_nid_t *srcnid, __u32 *order);
void LNetSnprintHandle(char *str, int str_len, lnet_handle_any_t handle);
+lnet_nid_t LNetPrimaryNID(lnet_nid_t nid);
+lnet_nid_t
+LNetPrimaryNID(lnet_nid_t nid)
+{
+ struct lnet_peer_ni *lpni;
+ lnet_nid_t primary_nid = nid;
+ int rc = 0;
+ int cpt;
+
+ cpt = lnet_net_lock_current();
+ lpni = lnet_nid2peerni_locked(nid, cpt);
+ if (IS_ERR(lpni)) {
+ rc = PTR_ERR(lpni);
+ goto out_unlock;
+ }
+ primary_nid = lpni->lpni_peer_net->lpn_peer->lp_primary_nid;
+ lnet_peer_ni_decref_locked(lpni);
+out_unlock:
+ lnet_net_unlock(cpt);
+
+ CDEBUG(D_NET, "NID %s primary NID %s rc %d\n", libcfs_nid2str(nid),
+ libcfs_nid2str(primary_nid), rc);
+ return primary_nid;
+}
+EXPORT_SYMBOL(LNetPrimaryNID);
+
struct lnet_peer_net *
lnet_peer_get_net_locked(struct lnet_peer *peer, __u32 net_id)
{
struct lnet_peer_net *
lnet_peer_get_net_locked(struct lnet_peer *peer, __u32 net_id)
{
struct ptlrpc_connection *
ptlrpc_connection_get(lnet_process_id_t peer, lnet_nid_t self,
struct ptlrpc_connection *
ptlrpc_connection_get(lnet_process_id_t peer, lnet_nid_t self,
- struct ptlrpc_connection *conn, *conn2;
- ENTRY;
+ struct ptlrpc_connection *conn, *conn2;
+ ENTRY;
- conn = cfs_hash_lookup(conn_hash, &peer);
- if (conn)
- GOTO(out, conn);
+ peer.nid = LNetPrimaryNID(peer.nid);
+ conn = cfs_hash_lookup(conn_hash, &peer);
+ if (conn)
+ GOTO(out, conn);
- OBD_ALLOC_PTR(conn);
- if (!conn)
- RETURN(NULL);
+ OBD_ALLOC_PTR(conn);
+ if (!conn)
+ RETURN(NULL);
- conn->c_peer = peer;
- conn->c_self = self;
+ conn->c_peer = peer;
+ conn->c_self = self;
INIT_HLIST_NODE(&conn->c_hash);
atomic_set(&conn->c_refcount, 1);
INIT_HLIST_NODE(&conn->c_hash);
atomic_set(&conn->c_refcount, 1);
- if (uuid)
- obd_str2uuid(&conn->c_remote_uuid, uuid->uuid);
+ if (uuid)
+ obd_str2uuid(&conn->c_remote_uuid, uuid->uuid);
/*
* Add the newly created conn to the hash, on key collision we
* lost a racing addition and must destroy our newly allocated
/*
* Add the newly created conn to the hash, on key collision we
* lost a racing addition and must destroy our newly allocated
- * connection. The object which exists in the has will be
+ * connection. The object which exists in the hash will be
* returned and may be compared against out object.
*/
/* In the function below, .hs_keycmp resolves to
* returned and may be compared against out object.
*/
/* In the function below, .hs_keycmp resolves to