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