From 55e0f0e82879ede4116838318e818c6503d332f7 Mon Sep 17 00:00:00 2001 From: Liang Zhen Date: Mon, 28 Apr 2014 23:11:13 +0800 Subject: [PATCH] LU-4423 lnet: fix deadloop in ksocknal_push ksocknal_push() should break the loop if it can't find matching peer Signed-off-by: Liang Zhen Change-Id: I538b1904fb3bc90572007d3c68f81258fb3d405b Reviewed-on: http://review.whamcloud.com/10128 Tested-by: Jenkins Tested-by: Maloo Reviewed-by: James Simmons Reviewed-by: Doug Oucharek Reviewed-by: Isaac Huang Reviewed-by: Oleg Drokin --- lnet/klnds/socklnd/socklnd.c | 72 ++++++++++++++++++++++---------------------- 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/lnet/klnds/socklnd/socklnd.c b/lnet/klnds/socklnd/socklnd.c index 816f836..1a1fa77 100644 --- a/lnet/klnds/socklnd/socklnd.c +++ b/lnet/klnds/socklnd/socklnd.c @@ -1896,50 +1896,50 @@ ksocknal_push_peer (ksock_peer_t *peer) static int ksocknal_push (lnet_ni_t *ni, lnet_process_id_t id) { - ksock_peer_t *peer; - struct list_head *tmp; - int index; - int i; - int j; - int rc = -ENOENT; - - for (i = 0; i < ksocknal_data.ksnd_peer_hash_size; i++) { - for (j = 0; ; j++) { - read_lock(&ksocknal_data.ksnd_global_lock); + struct list_head *start; + struct list_head *end; + struct list_head *tmp; + int rc = -ENOENT; + unsigned int hsize = ksocknal_data.ksnd_peer_hash_size; - index = 0; - peer = NULL; + if (id.nid == LNET_NID_ANY) { + start = &ksocknal_data.ksnd_peers[0]; + end = &ksocknal_data.ksnd_peers[hsize - 1]; + } else { + start = end = ksocknal_nid2peerlist(id.nid); + } - list_for_each(tmp, &ksocknal_data.ksnd_peers[i]) { - peer = list_entry(tmp, ksock_peer_t, - ksnp_list); + for (tmp = start; tmp <= end; tmp++) { + int peer_off; /* searching offset in peer hash table */ - if (!((id.nid == LNET_NID_ANY || - id.nid == peer->ksnp_id.nid) && - (id.pid == LNET_PID_ANY || - id.pid == peer->ksnp_id.pid))) { - peer = NULL; - continue; - } + for (peer_off = 0; ; peer_off++) { + ksock_peer_t *peer; + int i = 0; - if (index++ == j) { - ksocknal_peer_addref(peer); - break; - } - } + read_lock(&ksocknal_data.ksnd_global_lock); + list_for_each_entry(peer, tmp, ksnp_list) { + if (!((id.nid == LNET_NID_ANY || + id.nid == peer->ksnp_id.nid) && + (id.pid == LNET_PID_ANY || + id.pid == peer->ksnp_id.pid))) + continue; + if (i++ == peer_off) { + ksocknal_peer_addref(peer); + break; + } + } read_unlock(&ksocknal_data.ksnd_global_lock); - if (peer != NULL) { - rc = 0; - ksocknal_push_peer (peer); - ksocknal_peer_decref(peer); - } - } - - } + if (i == 0) /* no match */ + break; - return (rc); + rc = 0; + ksocknal_push_peer(peer); + ksocknal_peer_decref(peer); + } + } + return rc; } static int -- 1.8.3.1