+ struct list_head ni_list; /* chain on ln_nis */
+ struct list_head ni_cptlist; /* chain on ln_nis_cpt */
+ int ni_maxtxcredits; /* # tx credits */
+ /* # per-peer send credits */
+ int ni_peertxcredits;
+ /* # per-peer router buffer credits */
+ int ni_peerrtrcredits;
+ /* seconds to consider peer dead */
+ int ni_peertimeout;
+ int ni_ncpts; /* number of CPTs */
+ __u32 *ni_cpts; /* bond NI on some CPTs */
+ lnet_nid_t ni_nid; /* interface's NID */
+ void *ni_data; /* instance-specific data */
+ lnd_t *ni_lnd; /* procedural interface */
+ struct lnet_tx_queue **ni_tx_queues; /* percpt TX queues */
+ int **ni_refs; /* percpt reference count */
+ long ni_last_alive; /* when I was last alive */
+ lnet_ni_status_t *ni_status; /* my health status */
+ /* equivalent interfaces to use */
+ char *ni_interfaces[LNET_MAX_INTERFACES];
+} lnet_ni_t;
+
+#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_RTE_DISABLED (1 << 2) /* Routing enabled */
+
+#define LNET_PING_FEAT_MASK (LNET_PING_FEAT_BASE | \
+ LNET_PING_FEAT_NI_STATUS)
+
+typedef struct {
+ __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 */
+#define LNET_MAX_RTR_NIS 16
+#define LNET_PINGINFO_SIZE offsetof(lnet_ping_info_t, pi_ni[LNET_MAX_RTR_NIS])
+typedef struct {
+ /* chain on the_lnet.ln_zombie_rcd or ln_deathrow_rcd */
+ struct list_head rcd_list;
+ lnet_handle_md_t rcd_mdh; /* ping buffer MD */
+ struct lnet_peer *rcd_gateway; /* reference to gateway */
+ lnet_ping_info_t *rcd_pinginfo; /* ping buffer */
+} lnet_rc_data_t;
+
+typedef struct lnet_peer {
+ /* chain on peer hash */
+ struct list_head lp_hashlist;
+ /* messages blocking for tx credits */
+ struct list_head lp_txq;
+ /* messages blocking for router credits */
+ struct list_head lp_rtrq;
+ /* chain on router list */
+ struct list_head lp_rtr_list;
+ /* # tx credits available */
+ int lp_txcredits;
+ /* low water mark */
+ int lp_mintxcredits;
+ /* # router credits */
+ int lp_rtrcredits;
+ /* low water mark */
+ int lp_minrtrcredits;
+ /* alive/dead? */
+ unsigned int lp_alive:1;
+ /* notification outstanding? */
+ unsigned int lp_notify:1;
+ /* outstanding notification for LND? */
+ unsigned int lp_notifylnd:1;
+ /* some thread is handling notification */
+ unsigned int lp_notifying:1;
+ /* SEND event outstanding from ping */
+ unsigned int lp_ping_notsent;
+ /* # times router went dead<->alive */
+ int lp_alive_count;
+ /* bytes queued for sending */
+ long lp_txqnob;
+ /* time of last aliveness news */
+ cfs_time_t lp_timestamp;
+ /* time of last ping attempt */
+ cfs_time_t lp_ping_timestamp;
+ /* != 0 if ping reply expected */
+ cfs_time_t lp_ping_deadline;
+ /* when I was last alive */
+ cfs_time_t lp_last_alive;
+ /* when lp_ni was queried last time */
+ cfs_time_t lp_last_query;
+ /* interface peer is on */
+ lnet_ni_t *lp_ni;
+ lnet_nid_t lp_nid; /* peer's NID */
+ int lp_refcount; /* # refs */
+ int lp_cpt; /* CPT this peer attached on */
+ /* # refs from lnet_route_t::lr_gateway */
+ int lp_rtr_refcount;
+ /* returned RC ping features */
+ unsigned int lp_ping_feats;
+ struct list_head lp_routes; /* routers on this peer */
+ lnet_rc_data_t *lp_rcd; /* router checker state */
+} lnet_peer_t;
+
+/* peer hash size */
+#define LNET_PEER_HASH_BITS 9
+#define LNET_PEER_HASH_SIZE (1 << LNET_PEER_HASH_BITS)
+
+/* peer hash table */
+struct lnet_peer_table {
+ int pt_version; /* /proc validity stamp */
+ int pt_number; /* # peers extant */
+ int pt_zombies; /* # zombies to go to deathrow
+ * (and not there yet) */
+ struct list_head pt_deathrow; /* zombie peers */
+ struct list_head *pt_hash; /* NID->peer hash */
+};
+
+/* peer aliveness is enabled only on routers for peers in a network where the
+ * lnet_ni_t::ni_peertimeout has been set to a positive value */
+#define lnet_peer_aliveness_enabled(lp) (the_lnet.ln_routing != 0 && \
+ (lp)->lp_ni->ni_peertimeout > 0)
+
+typedef struct {
+ struct list_head lr_list; /* chain on net */
+ struct list_head lr_gwlist; /* chain on gateway */
+ lnet_peer_t *lr_gateway; /* router node */
+ __u32 lr_net; /* remote network number */
+ int lr_seq; /* sequence for round-robin */
+ unsigned int lr_downis; /* number of down NIs */
+ unsigned int lr_hops; /* how far I am */
+ unsigned int lr_priority; /* route priority */
+} lnet_route_t;
+
+#define LNET_REMOTE_NETS_HASH_DEFAULT (1U << 7)
+#define LNET_REMOTE_NETS_HASH_MAX (1U << 16)
+#define LNET_REMOTE_NETS_HASH_SIZE (1 << the_lnet.ln_remote_nets_hbits)
+
+typedef struct {
+ /* chain on ln_remote_nets_hash */
+ struct list_head lrn_list;
+ /* routes to me */
+ struct list_head lrn_routes;
+ /* my net number */
+ __u32 lrn_net;
+} lnet_remotenet_t;
+
+typedef struct {
+ /* my free buffer pool */
+ struct list_head rbp_bufs;
+ /* messages blocking for a buffer */
+ struct list_head rbp_msgs;
+ /* # pages in each buffer */
+ int rbp_npages;
+ /* # buffers */
+ int rbp_nbuffers;
+ /* # free buffers / blocked messages */
+ int rbp_credits;
+ /* low water mark */
+ int rbp_mincredits;
+} lnet_rtrbufpool_t;
+
+typedef struct {
+ struct list_head rb_list; /* chain on rbp_bufs */
+ lnet_rtrbufpool_t *rb_pool; /* owning pool */
+ lnet_kiov_t rb_kiov[0]; /* the buffer space */
+} lnet_rtrbuf_t;
+
+typedef struct {
+ __u32 msgs_alloc;
+ __u32 msgs_max;
+ __u32 errors;
+ __u32 send_count;
+ __u32 recv_count;
+ __u32 route_count;
+ __u32 drop_count;
+ __u64 send_length;
+ __u64 recv_length;
+ __u64 route_length;
+ __u64 drop_length;
+} WIRE_ATTR lnet_counters_t;
+
+#define LNET_PEER_HASHSIZE 503 /* prime! */
+
+#define LNET_TINY_BUF_IDX 0
+#define LNET_SMALL_BUF_IDX 1
+#define LNET_LARGE_BUF_IDX 2
+
+/* # different router buffer pools */
+#define LNET_NRBPOOLS (LNET_LARGE_BUF_IDX + 1)
+
+enum {
+ /* Didn't match anything */
+ LNET_MATCHMD_NONE = (1 << 0),
+ /* Matched OK */
+ LNET_MATCHMD_OK = (1 << 1),
+ /* Must be discarded */
+ LNET_MATCHMD_DROP = (1 << 2),
+ /* match and buffer is exhausted */
+ LNET_MATCHMD_EXHAUSTED = (1 << 3),
+ /* match or drop */
+ LNET_MATCHMD_FINISH = (LNET_MATCHMD_OK | LNET_MATCHMD_DROP),
+};