# else /* 64-bit system */
/*
* 256 CPTs for thousands of CPUs, allowing more CPTs might make us
- * under risk of consuming all lh_cooke.
+ * under risk of consuming all lh_cookie.
*/
# define LNET_CPT_MAX_BITS 8
# endif /* BITS_PER_LONG == 32 */
#define LNET_COOKIE_TYPE_ME 2
#define LNET_COOKIE_TYPE_EQ 3
#define LNET_COOKIE_TYPE_BITS 2
-#define LNET_COOKIE_TYPES (1 << LNET_COOKIE_TYPE_BITS)
-/* LNET_COOKIE_TYPES must be a power of 2, so the cookie type can be
- * extracted by masking with (LNET_COOKIE_TYPES - 1) */
+#define LNET_COOKIE_MASK ((1ULL << LNET_COOKIE_TYPE_BITS) - 1ULL)
struct lnet_ni; /* forward ref */
char *ni_interfaces[LNET_MAX_INTERFACES];
} lnet_ni_t;
-#define LNET_PROTO_PING_MATCHBITS 0x8000000000000000LL
-enum {
- LNET_PROTO_PING_UNKNOWN = 0, /* unknown */
- LNET_PROTO_PING_VERSION_1 = 1, /* old version */
- LNET_PROTO_PING_VERSION = 2, /* current version */
-};
+#define LNET_PROTO_PING_MATCHBITS 0x8000000000000000LL
+
+/* NB: value of these features equal to LNET_PROTO_PING_VERSION_x
+ * of old LNet, so there shouldn't be any compatibility issue */
+#define LNET_PING_FEAT_INVAL (0) /* no feature */
+#define LNET_PING_FEAT_BASE (1 << 0) /* just a ping */
+#define LNET_PING_FEAT_NI_STATUS (1 << 1) /* return NI status */
+
+#define LNET_PING_FEAT_MASK (LNET_PING_FEAT_BASE | \
+ LNET_PING_FEAT_NI_STATUS)
typedef struct {
- __u32 pi_magic;
- __u32 pi_version;
- lnet_pid_t pi_pid;
- __u32 pi_nnis;
- lnet_ni_status_t pi_ni[0];
+ __u32 pi_magic;
+ __u32 pi_features;
+ lnet_pid_t pi_pid;
+ __u32 pi_nnis;
+ lnet_ni_status_t pi_ni[0];
} WIRE_ATTR lnet_ping_info_t;
/* router checker data, per router */
int lp_cpt; /* CPT this peer attached on */
/* # refs from lnet_route_t::lr_gateway */
int lp_rtr_refcount;
- /* returned RC ping version */
- unsigned int lp_ping_version;
+ /* returned RC ping features */
+ unsigned int lp_ping_feats;
cfs_list_t lp_routes; /* routers on this peer */
lnet_rc_data_t *lp_rcd; /* router checker state */
} lnet_peer_t;
int ln_nportals;
/* the vector of portals */
lnet_portal_t **ln_portals;
- /* ME container */
+ /* percpt ME containers */
struct lnet_res_container **ln_me_containers;
- /* MD container */
+ /* percpt MD container */
struct lnet_res_container **ln_md_containers;
/* Event Queue container */
#endif
/* protect NI, peer table, credits, routers, rtrbuf... */
struct cfs_percpt_lock *ln_net_lock;
- /* message container for active/finalizing/freed message */
+ /* percpt message containers for active/finalizing/freed message */
struct lnet_msg_container **ln_msg_containers;
lnet_counters_t **ln_counters;
struct lnet_peer_table **ln_peer_tables;
cfs_list_t ln_routers;
/* validity stamp */
__u64 ln_routers_version;
- /* router buffer pools */
+ /* percpt router buffer pools */
lnet_rtrbufpool_t **ln_rtrpools;
lnet_handle_md_t ln_ping_target_md;
{
int count = 0;
- if (rec->rec_type == 0) /* not set yet, it's a uninitialized */
+ if (rec->rec_type == 0) /* not set yet, it's uninitialized */
return;
while (!cfs_list_empty(&rec->rec_active)) {
lnet_libhandle_t *lh;
unsigned int hash;
- if ((cookie & (LNET_COOKIE_TYPES - 1)) != rec->rec_type)
+ if ((cookie & LNET_COOKIE_MASK) != rec->rec_type)
return NULL;
hash = cookie >> (LNET_COOKIE_TYPE_BITS + LNET_CPT_BITS);
int
lnet_prepare(lnet_pid_t requested_pid)
{
- /* Prepare to bring up the network */
+ /* Prepare to bring up the network */
struct lnet_res_container **recs;
int rc = 0;
if (rc != 0)
goto failed;
- /* NB: we will have instance of message container per CPT soon */
rc = lnet_msg_containers_create();
if (rc != 0)
goto failed;
the_lnet.ln_me_containers = recs;
- /* NB: we will have instance of MD container per CPT soon */
recs = lnet_res_containers_create(LNET_COOKIE_TYPE_MD, LNET_FL_MAX_MDS,
sizeof(lnet_libmd_t));
if (recs == NULL)
if (val < number)
return val;
- return (unsigned int)((key + val + (val >> 1)) % number);
+ return (unsigned int)(key + val + (val >> 1)) % number;
}
int
{
int rc;
- lnet_assert_wire_constants ();
- LASSERT (!the_lnet.ln_init);
+ lnet_assert_wire_constants();
+ LASSERT(!the_lnet.ln_init);
- memset(&the_lnet, 0, sizeof(the_lnet));
+ memset(&the_lnet, 0, sizeof(the_lnet));
/* refer to global cfs_cpt_table for now */
the_lnet.ln_cpt_table = cfs_cpt_table;
return -1;
}
- the_lnet.ln_refcount = 0;
- the_lnet.ln_init = 1;
- LNetInvalidateHandle(&the_lnet.ln_rc_eqh);
- CFS_INIT_LIST_HEAD(&the_lnet.ln_lnds);
+ the_lnet.ln_refcount = 0;
+ the_lnet.ln_init = 1;
+ LNetInvalidateHandle(&the_lnet.ln_rc_eqh);
+ CFS_INIT_LIST_HEAD(&the_lnet.ln_lnds);
CFS_INIT_LIST_HEAD(&the_lnet.ln_rcd_zombie);
CFS_INIT_LIST_HEAD(&the_lnet.ln_rcd_deathrow);
pinfo->pi_nnis = n;
pinfo->pi_pid = the_lnet.ln_pid;
pinfo->pi_magic = LNET_PROTO_PING_MAGIC;
- pinfo->pi_version = LNET_PROTO_PING_VERSION;
+ pinfo->pi_features = LNET_PING_FEAT_NI_STATUS;
for (i = 0; i < n; i++) {
lnet_ni_status_t *ns = &pinfo->pi_ni[i];
lnet_ni_decref_locked(ni, 0);
lnet_net_unlock(0);
- }
+ }
- the_lnet.ln_ping_info = pinfo;
- return 0;
+ the_lnet.ln_ping_info = pinfo;
+ return 0;
}
static void
goto out_1;
}
- if (info->pi_version != LNET_PROTO_PING_VERSION) {
- CERROR("%s: Unexpected version 0x%x\n",
- libcfs_id2str(id), info->pi_version);
- goto out_1;
- }
+ if ((info->pi_features & LNET_PING_FEAT_NI_STATUS) == 0) {
+ CERROR("%s: ping w/o NI status: 0x%x\n",
+ libcfs_id2str(id), info->pi_features);
+ goto out_1;
+ }
if (nob < offsetof(lnet_ping_info_t, pi_ni[0])) {
CERROR("%s: Short reply %d(%d min)\n", libcfs_id2str(id),
}
lnet_ni_t *
-lnet_ni_alloc(__u32 net, struct cfs_expr_list **el, cfs_list_t *nilist)
+lnet_ni_alloc(__u32 net, struct cfs_expr_list *el, cfs_list_t *nilist)
{
struct lnet_tx_queue *tq;
struct lnet_ni *ni;
cfs_percpt_for_each(tq, i, ni->ni_tx_queues)
CFS_INIT_LIST_HEAD(&tq->tq_delayed);
- if (el == NULL || *el == NULL) {
+ if (el == NULL) {
ni->ni_cpts = NULL;
ni->ni_ncpts = LNET_CPT_NUMBER;
} else {
- rc = cfs_expr_list_values(*el, LNET_CPT_NUMBER, &ni->ni_cpts);
+ rc = cfs_expr_list_values(el, LNET_CPT_NUMBER, &ni->ni_cpts);
if (rc <= 0) {
CERROR("Failed to set CPTs for NI %s: %d\n",
libcfs_net2str(net), rc);
}
ni->ni_ncpts = rc;
- cfs_expr_list_free(*el); /* consume it */
- *el = NULL;
}
/* LND will fill in the address part of the NID */
}
if (LNET_NETTYP(net) != LOLND && /* LO is implicit */
- lnet_ni_alloc(net, &el, nilist) == NULL)
- goto failed;
+ lnet_ni_alloc(net, el, nilist) == NULL)
+ goto failed;
+
+ if (el != NULL) {
+ cfs_expr_list_free(el);
+ el = NULL;
+ }
str = comma;
continue;
}
nnets++;
- ni = lnet_ni_alloc(net, &el, nilist);
- if (ni == NULL)
- goto failed;
+ ni = lnet_ni_alloc(net, el, nilist);
+ if (ni == NULL)
+ goto failed;
+
+ if (el != NULL) {
+ cfs_expr_list_free(el);
+ el = NULL;
+ }
- niface = 0;
+ niface = 0;
iface = bracket + 1;
bracket = strchr(iface, ')');
if (LNET_SEQ_GT(eq->eq_deq_seq, new_event->sequence))
RETURN(0);
- /* We've got a new event... */
- *ev = *new_event;
+ /* We've got a new event... */
+ *ev = *new_event;
CDEBUG(D_INFO, "event: %p, sequence: %lu, eq->size: %u\n",
new_event, eq->eq_deq_seq, eq->eq_size);
static int
lnet_eq_wait_locked(int *timeout_ms)
{
- int tms = *timeout_ms;
- int wait;
- cfs_waitlink_t wl;
- cfs_time_t now;
+ int tms = *timeout_ms;
+ int wait;
+ cfs_waitlink_t wl;
+ cfs_time_t now;
if (tms == 0)
return -1; /* don't want to wait and no new event */
static int
lnet_eq_wait_locked(int *timeout_ms)
{
- lnet_ni_t *eq_waitni = NULL;
- int tms = *timeout_ms;
- int wait;
- struct timeval then;
- struct timeval now;
+ lnet_ni_t *eq_waitni = NULL;
+ int tms = *timeout_ms;
+ int wait;
+ struct timeval then;
+ struct timeval now;
if (the_lnet.ln_eq_waitni != NULL) {
/* I have a single NI that I have to call into, to get
* \retval -ENOENT If there's an invalid handle in \a eventqs.
*/
int
-LNetEQPoll (lnet_handle_eq_t *eventqs, int neq, int timeout_ms,
- lnet_event_t *event, int *which)
+LNetEQPoll(lnet_handle_eq_t *eventqs, int neq, int timeout_ms,
+ lnet_event_t *event, int *which)
{
int wait = 1;
int rc;
lnet_eq_wait_lock();
- for (;;) {
+ for (;;) {
#ifndef __KERNEL__
lnet_eq_wait_unlock();
*/
int
LNetMDAttach(lnet_handle_me_t meh, lnet_md_t umd,
- lnet_unlink_t unlink, lnet_handle_md_t *handle)
+ lnet_unlink_t unlink, lnet_handle_md_t *handle)
{
CFS_LIST_HEAD (matches);
CFS_LIST_HEAD (drops);
if (rc != 0)
goto failed;
- me = lnet_handle2me(&meh);
+ me = lnet_handle2me(&meh);
if (me == NULL)
rc = -ENOENT;
else if (me->me_md != NULL)
- rc = -EBUSY;
+ rc = -EBUSY;
else
rc = lnet_md_link(md, umd.eq_handle, cpt);
if (mtable == NULL) /* can't match portal type */
return -EPERM;
- me = lnet_me_alloc();
- if (me == NULL)
- return -ENOMEM;
+ me = lnet_me_alloc();
+ if (me == NULL)
+ return -ENOMEM;
lnet_res_lock(mtable->mt_cpt);
if (pos == LNET_INS_LOCAL)
return -EPERM;
- new_me = lnet_me_alloc();
- if (new_me == NULL)
- return -ENOMEM;
+ new_me = lnet_me_alloc();
+ if (new_me == NULL)
+ return -ENOMEM;
cpt = lnet_cpt_of_cookie(current_meh.cookie);
ptl = the_lnet.ln_portals[current_me->me_portal];
if (lnet_ptl_is_unique(ptl)) {
- /* nosense to insertion on unique portal */
+ /* nosense to insertion on unique portal */
lnet_me_free_locked(new_me);
lnet_res_unlock(cpt);
return -EPERM;
LASSERT(!msg->msg_sending);
LASSERT(msg->msg_receiving);
+ LASSERT(!msg->msg_rx_ready_delay);
LASSERT(ni->ni_lnd->lnd_eager_recv != NULL);
msg->msg_rx_ready_delay = 1;
lp = rtr->lr_gateway;
if (!lp->lp_alive || /* gateway is down */
- (lp->lp_ping_version == LNET_PROTO_PING_VERSION &&
+ ((lp->lp_ping_feats & LNET_PING_FEAT_NI_STATUS) != 0 &&
rtr->lr_downis != 0)) /* NI to target is down */
continue;
lnet_msg_attach_md(msg, md, 0, mlength);
- if (mlength != 0)
- lnet_setpayloadbuffer(msg);
+ if (mlength != 0)
+ lnet_setpayloadbuffer(msg);
lnet_res_unlock(cpt);
lnet_build_msg_event(msg, LNET_EVENT_REPLY);
- lnet_ni_recv(ni, private, msg, 0, 0, mlength, rlength);
- return 0;
+ lnet_ni_recv(ni, private, msg, 0, 0, mlength, rlength);
+ return 0;
}
static int
lnet_res_unlock(cpt);
lnet_msg_free(msg);
- return -ENOENT;
- }
+ return -ENOENT;
+ }
- CDEBUG(D_NET, "LNetPut -> %s\n", libcfs_id2str(target));
+ CDEBUG(D_NET, "LNetPut -> %s\n", libcfs_id2str(target));
lnet_msg_attach_md(msg, md, 0, 0);
getmd);
lnet_res_unlock(cpt);
goto drop;
- }
+ }
- LASSERT (getmd->md_offset == 0);
+ LASSERT(getmd->md_offset == 0);
CDEBUG(D_NET, "%s: Reply from %s md %p\n",
libcfs_nid2str(ni->ni_nid), libcfs_id2str(peer_id), getmd);
/* setup information for lnet_build_msg_event */
msg->msg_from = peer_id.nid;
- msg->msg_type = LNET_MSG_GET; /* flag this msg as an "optimized" GET */
+ msg->msg_type = LNET_MSG_GET; /* flag this msg as an "optimized" GET */
msg->msg_hdr.src_nid = peer_id.nid;
msg->msg_hdr.payload_length = getmd->md_length;
msg->msg_receiving = 1; /* required by lnet_msg_attach_md */
ev->target.pid = le32_to_cpu(hdr->dest_pid);
ev->initiator.nid = LNET_NID_ANY;
ev->initiator.pid = the_lnet.ln_pid;
- ev->sender = LNET_NID_ANY;
+ ev->sender = LNET_NID_ANY;
} else {
/* event for passive message */
ev->initiator.pid = hdr->src_pid;
ev->initiator.nid = hdr->src_nid;
ev->rlength = hdr->payload_length;
- ev->sender = msg->msg_from;
+ ev->sender = msg->msg_from;
ev->mlength = msg->msg_wanted;
ev->offset = msg->msg_offset;
}
mlength = md->md_length - offset;
}
- if (info->mi_rlength <= mlength) { /* fits in allowed space */
+ if (info->mi_rlength <= mlength) { /* fits in allowed space */
mlength = info->mi_rlength;
} else if ((md->md_options & LNET_MD_TRUNCATE) == 0) {
/* this packet _really_ is too big */
if (lp != NULL)
memset(lp, 0, sizeof(*lp));
else
- LIBCFS_ALLOC(lp, sizeof(*lp));
+ LIBCFS_CPT_ALLOC(lp, lnet_cpt_table(), cpt2, sizeof(*lp));
if (lp == NULL) {
*lpp = NULL;
}
CFS_INIT_LIST_HEAD(&lp->lp_txq);
- CFS_INIT_LIST_HEAD(&lp->lp_rtrq);
+ CFS_INIT_LIST_HEAD(&lp->lp_rtrq);
CFS_INIT_LIST_HEAD(&lp->lp_routes);
lp->lp_notify = 0;
lp->lp_last_alive = cfs_time_current(); /* assumes alive */
lp->lp_last_query = 0; /* haven't asked NI yet */
lp->lp_ping_timestamp = 0;
- lp->lp_ping_version = LNET_PROTO_PING_UNKNOWN;
+ lp->lp_ping_feats = LNET_PING_FEAT_INVAL;
lp->lp_nid = nid;
lp->lp_cpt = cpt2;
lp->lp_refcount = 2; /* 1 for caller; 1 for hash */
lp->lp_notify = 1;
lp->lp_notifylnd |= notifylnd;
if (lp->lp_alive)
- lp->lp_ping_version = LNET_PROTO_PING_UNKNOWN; /* reset */
+ lp->lp_ping_feats = LNET_PING_FEAT_INVAL; /* reset */
- CDEBUG(D_NET, "set %s %d\n", libcfs_nid2str(lp->lp_nid), alive);
+ CDEBUG(D_NET, "set %s %d\n", libcfs_nid2str(lp->lp_nid), alive);
}
void
cfs_list_add(&route->lr_list, e);
cfs_list_add(&route->lr_gwlist, &route->lr_gateway->lp_routes);
- the_lnet.ln_remote_nets_version++;
- lnet_rtr_addref_locked(route->lr_gateway);
+ the_lnet.ln_remote_nets_version++;
+ lnet_rtr_addref_locked(route->lr_gateway);
}
int
LIBCFS_FREE(rnet, sizeof(*rnet));
if (rc == -EHOSTUNREACH) { /* gateway is not on a local net */
- return 0; /* ignore the route entry */
+ return 0; /* ignore the route entry */
} else {
CERROR("Error %d creating route %s %d %s\n", rc,
libcfs_net2str(net), hops,
if (!add_route)
LIBCFS_FREE(route, sizeof(*route));
- if (rnet != rnet2)
- LIBCFS_FREE(rnet, sizeof(*rnet));
+ if (rnet != rnet2)
+ LIBCFS_FREE(rnet, sizeof(*rnet));
- return 0;
+ return 0;
}
int
}
int
-lnet_del_route (__u32 net, lnet_nid_t gw_nid)
+lnet_del_route(__u32 net, lnet_nid_t gw_nid)
{
struct lnet_peer *gateway;
lnet_remotenet_t *rnet;
void
lnet_swap_pinginfo(lnet_ping_info_t *info)
{
- int i;
- lnet_ni_status_t *stat;
+ int i;
+ lnet_ni_status_t *stat;
__swab32s(&info->pi_magic);
- __swab32s(&info->pi_version);
+ __swab32s(&info->pi_features);
__swab32s(&info->pi_pid);
__swab32s(&info->pi_nnis);
for (i = 0; i < info->pi_nnis && i < LNET_MAX_RTR_NIS; i++) {
if (info->pi_magic != LNET_PROTO_PING_MAGIC) {
CDEBUG(D_NET, "%s: Unexpected magic %08x\n",
libcfs_nid2str(gw->lp_nid), info->pi_magic);
- gw->lp_ping_version = LNET_PROTO_PING_UNKNOWN;
+ gw->lp_ping_feats = LNET_PING_FEAT_INVAL;
return;
}
- gw->lp_ping_version = info->pi_version;
- if (gw->lp_ping_version == LNET_PROTO_PING_VERSION_1)
- return; /* v1 doesn't carry NI status info */
-
- if (gw->lp_ping_version != LNET_PROTO_PING_VERSION) {
- CDEBUG(D_NET, "%s: Unexpected version 0x%x\n",
- libcfs_nid2str(gw->lp_nid), gw->lp_ping_version);
- gw->lp_ping_version = LNET_PROTO_PING_UNKNOWN;
- return;
+ gw->lp_ping_feats = info->pi_features;
+ if ((gw->lp_ping_feats & LNET_PING_FEAT_MASK) == 0) {
+ CDEBUG(D_NET, "%s: Unexpected features 0x%x\n",
+ libcfs_nid2str(gw->lp_nid), gw->lp_ping_feats);
+ return; /* nothing I can understand */
}
+ if ((gw->lp_ping_feats & LNET_PING_FEAT_NI_STATUS) == 0)
+ return; /* can't carry NI status info */
+
cfs_list_for_each_entry(rtr, &gw->lp_routes, lr_gwlist) {
int ptl_status = LNET_NI_STATUS_INVALID;
int down = 0;
if (nid == LNET_NID_ANY) {
CDEBUG(D_NET, "%s: unexpected LNET_NID_ANY\n",
libcfs_nid2str(gw->lp_nid));
- gw->lp_ping_version = LNET_PROTO_PING_UNKNOWN;
+ gw->lp_ping_feats = LNET_PING_FEAT_INVAL;
return;
}
CDEBUG(D_NET, "%s: Unexpected status 0x%x\n",
libcfs_nid2str(gw->lp_nid), stat->ns_status);
- gw->lp_ping_version = LNET_PROTO_PING_UNKNOWN;
+ gw->lp_ping_feats = LNET_PING_FEAT_INVAL;
return;
}
if (event->unlinked) {
LNetInvalidateHandle(&rcd->rcd_mdh);
return;
- }
+ }
LASSERT(event->type == LNET_EVENT_SEND ||
event->type == LNET_EVENT_REPLY);
mdh = rcd->rcd_mdh;
if (rtr->lp_ping_deadline == 0) {
- rtr->lp_ping_deadline = \
+ rtr->lp_ping_deadline =
cfs_time_shift(router_ping_timeout);
}
LNetMDUnlink(rcd->rcd_mdh);
lnet_net_lock(LNET_LOCK_EX);
- }
+ }
cfs_list_splice_init(&head, &the_lnet.ln_rcd_zombie);
rcd_list) {
if (!LNetHandleIsInvalid(rcd->rcd_mdh))
cfs_list_move(&rcd->rcd_list, &head);
- }
+ }
wait_unlink = wait_unlink &&
!cfs_list_empty(&the_lnet.ln_rcd_zombie);
the_lnet.ln_rc_state = LNET_RC_STATE_SHUTDOWN;
cfs_up(&the_lnet.ln_rc_signal);
- /* The unlink event callback will signal final completion */
- return 0;
+ /* The unlink event callback will signal final completion */
+ return 0;
}
void
lnet_rtrpools_free(void)
{
lnet_rtrbufpool_t *rtrp;
- int i;
+ int i;
if (the_lnet.ln_rtrpools == NULL) /* uninitialized or freed */
return;
int down_ni = 0;
lnet_route_t *rtr;
- if (peer->lp_ping_version == LNET_PROTO_PING_VERSION) {
+ if ((peer->lp_ping_feats &
+ LNET_PING_FEAT_NI_STATUS) != 0) {
cfs_list_for_each_entry(rtr, &peer->lp_routes,
lr_gwlist) {
/* downis on any route should be the