#ifndef __LNET_LIB_LNET_H__
#define __LNET_LIB_LNET_H__
-#ifndef __KERNEL__
-# error This include is only for kernel use.
-#endif
+/* LNET has 0xeXXX */
+#define CFS_FAIL_PTLRPC_OST_BULK_CB2 0xe000
+
+#include <linux/netdevice.h>
#include <libcfs/libcfs.h>
#include <lnet/api.h>
#define DEFAULT_PEER_TIMEOUT 180
#define LNET_LND_DEFAULT_TIMEOUT 5
-static inline int lnet_is_route_alive(struct lnet_route *route)
-{
- if (!route->lr_gateway->lpni_alive)
- return 0; /* gateway is down */
- if ((route->lr_gateway->lpni_ping_feats &
- LNET_PING_FEAT_NI_STATUS) == 0)
- return 1; /* no NI status, assume it's alive */
- /* has NI status, check # down NIs */
- return route->lr_downis == 0;
-}
+#ifdef HAVE_KERN_SOCK_GETNAME_2ARGS
+#define lnet_kernel_getpeername(sock, addr, addrlen) \
+ kernel_getpeername(sock, addr)
+#define lnet_kernel_getsockname(sock, addr, addrlen) \
+ kernel_getsockname(sock, addr)
+#else
+#define lnet_kernel_getpeername(sock, addr, addrlen) \
+ kernel_getpeername(sock, addr, addrlen)
+#define lnet_kernel_getsockname(sock, addr, addrlen) \
+ kernel_getsockname(sock, addr, addrlen)
+#endif
+
+bool lnet_is_route_alive(struct lnet_route *route);
+bool lnet_is_gateway_alive(struct lnet_peer *gw);
static inline int lnet_is_wire_handle_none(struct lnet_handle_wire *wh)
{
extern struct kmem_cache *lnet_mes_cachep; /* MEs kmem_cache */
extern struct kmem_cache *lnet_small_mds_cachep; /* <= LNET_SMALL_MD_SIZE bytes
* MDs kmem_cache */
+extern struct kmem_cache *lnet_rspt_cachep;
+extern struct kmem_cache *lnet_msg_cachep;
static inline struct lnet_eq *
lnet_eq_alloc (void)
{
unsigned int size;
+ LASSERTF(md->md_rspt_ptr == NULL, "md %p rsp %p\n", md, md->md_rspt_ptr);
+
if ((md->md_options & LNET_MD_KIOV) != 0)
size = offsetof(struct lnet_libmd, md_iov.kiov[md->md_niov]);
else
}
}
-static inline struct lnet_me *
-lnet_me_alloc (void)
-{
- struct lnet_me *me;
-
- me = kmem_cache_alloc(lnet_mes_cachep, GFP_NOFS | __GFP_ZERO);
-
- if (me)
- CDEBUG(D_MALLOC, "slab-alloced 'me' at %p.\n", me);
- else
- CDEBUG(D_MALLOC, "failed to allocate 'me'\n");
-
- return me;
-}
-
-static inline void
-lnet_me_free(struct lnet_me *me)
-{
- CDEBUG(D_MALLOC, "slab-freed 'me' at %p.\n", me);
- kmem_cache_free(lnet_mes_cachep, me);
-}
-
struct lnet_libhandle *lnet_res_lh_lookup(struct lnet_res_container *rec,
__u64 cookie);
void lnet_res_lh_initialize(struct lnet_res_container *rec,
}
static inline void
-lnet_eq2handle(struct lnet_handle_eq *handle, struct lnet_eq *eq)
-{
- if (eq == NULL) {
- LNetInvalidateEQHandle(handle);
- return;
- }
-
- handle->cookie = eq->eq_lh.lh_cookie;
-}
-
-static inline struct lnet_eq *
-lnet_handle2eq(struct lnet_handle_eq *handle)
-{
- /* ALWAYS called with resource lock held */
- struct lnet_libhandle *lh;
-
- lh = lnet_res_lh_lookup(&the_lnet.ln_eq_container, handle->cookie);
- if (lh == NULL)
- return NULL;
-
- return lh_entry(lh, struct lnet_eq, eq_lh);
-}
-
-static inline void
lnet_md2handle(struct lnet_handle_md *handle, struct lnet_libmd *md)
{
handle->cookie = md->md_lh.lh_cookie;
}
static inline void
-lnet_me2handle(struct lnet_handle_me *handle, struct lnet_me *me)
-{
- handle->cookie = me->me_lh.lh_cookie;
-}
-
-static inline struct lnet_me *
-lnet_handle2me(struct lnet_handle_me *handle)
-{
- /* ALWAYS called with resource lock held */
- struct lnet_libhandle *lh;
- int cpt;
-
- cpt = lnet_cpt_of_cookie(handle->cookie);
- lh = lnet_res_lh_lookup(the_lnet.ln_me_containers[cpt],
- handle->cookie);
- if (lh == NULL)
- return NULL;
-
- return lh_entry(lh, struct lnet_me, me_lh);
-}
-
-static inline void
lnet_peer_net_addref_locked(struct lnet_peer_net *lpn)
{
atomic_inc(&lpn->lpn_refcount);
}
static inline int
-lnet_isrouter(struct lnet_peer_ni *lp)
+lnet_isrouter(struct lnet_peer_ni *lpni)
{
- return lp->lpni_rtr_refcount != 0;
+ return lpni->lpni_peer_net->lpn_peer->lp_rtr_refcount != 0;
}
static inline void
{
struct lnet_msg *msg;
- LIBCFS_ALLOC(msg, sizeof(*msg));
+ msg = kmem_cache_alloc(lnet_msg_cachep, GFP_NOFS | __GFP_ZERO);
- /* no need to zero, LIBCFS_ALLOC does for us */
return (msg);
}
lnet_msg_free(struct lnet_msg *msg)
{
LASSERT(!msg->msg_onactivelist);
- LIBCFS_FREE(msg, sizeof(*msg));
+ kmem_cache_free(lnet_msg_cachep, msg);
}
static inline struct lnet_rsp_tracker *
lnet_rspt_alloc(int cpt)
{
struct lnet_rsp_tracker *rspt;
- LIBCFS_ALLOC(rspt, sizeof(*rspt));
- lnet_net_lock(cpt);
- the_lnet.ln_counters[cpt]->lct_health.lch_rst_alloc++;
- lnet_net_unlock(cpt);
+
+ rspt = kmem_cache_alloc(lnet_rspt_cachep, GFP_NOFS | __GFP_ZERO);
+ if (rspt) {
+ lnet_net_lock(cpt);
+ the_lnet.ln_counters[cpt]->lct_health.lch_rst_alloc++;
+ lnet_net_unlock(cpt);
+ }
+ CDEBUG(D_MALLOC, "rspt alloc %p\n", rspt);
return rspt;
}
static inline void
lnet_rspt_free(struct lnet_rsp_tracker *rspt, int cpt)
{
- LIBCFS_FREE(rspt, sizeof(*rspt));
+ CDEBUG(D_MALLOC, "rspt free %p\n", rspt);
+
+ kmem_cache_free(lnet_rspt_cachep, rspt);
lnet_net_lock(cpt);
the_lnet.ln_counters[cpt]->lct_health.lch_rst_alloc--;
lnet_net_unlock(cpt);
((1U << the_lnet.ln_remote_nets_hbits) - 1)];
}
-extern struct lnet_lnd the_lolnd;
+extern const struct lnet_lnd the_lolnd;
extern int avoid_asym_router_failure;
extern unsigned int lnet_nid_cpt_hash(lnet_nid_t nid, unsigned int number);
extern unsigned lnet_retry_count;
extern unsigned int lnet_numa_range;
extern unsigned int lnet_health_sensitivity;
+extern unsigned int lnet_recovery_interval;
extern unsigned int lnet_peer_discovery_disabled;
+extern unsigned int lnet_drop_asym_route;
+extern unsigned int router_sensitivity_percentage;
+extern int alive_router_check_interval;
+extern int live_router_check_interval;
+extern int dead_router_check_interval;
extern int portal_rotor;
-int lnet_notify(struct lnet_ni *ni, lnet_nid_t peer, int alive,
+void lnet_mt_event_handler(struct lnet_event *event);
+
+int lnet_notify(struct lnet_ni *ni, lnet_nid_t peer, bool alive, bool reset,
time64_t when);
void lnet_notify_locked(struct lnet_peer_ni *lp, int notifylnd, int alive,
time64_t when);
int lnet_add_route(__u32 net, __u32 hops, lnet_nid_t gateway_nid,
- unsigned int priority);
-int lnet_check_routes(void);
+ __u32 priority, __u32 sensitivity);
int lnet_del_route(__u32 net, lnet_nid_t gw_nid);
void lnet_destroy_routes(void);
int lnet_get_route(int idx, __u32 *net, __u32 *hops,
- lnet_nid_t *gateway, __u32 *alive, __u32 *priority);
+ lnet_nid_t *gateway, __u32 *alive, __u32 *priority,
+ __u32 *sensitivity);
int lnet_get_rtr_pool_cfg(int idx, struct lnet_ioctl_pool_cfg *pool_cfg);
struct lnet_ni *lnet_get_next_ni_locked(struct lnet_net *mynet,
struct lnet_ni *prev);
int lnet_rtrpools_enable(void);
void lnet_rtrpools_disable(void);
void lnet_rtrpools_free(int keep_pools);
+void lnet_rtr_transfer_to_peer(struct lnet_peer *src,
+ struct lnet_peer *target);
struct lnet_remotenet *lnet_find_rnet_locked(__u32 net);
int lnet_dyn_add_net(struct lnet_ioctl_config_data *conf);
int lnet_dyn_del_net(__u32 net);
int lnet_islocalnid(lnet_nid_t nid);
int lnet_islocalnet(__u32 net);
+int lnet_islocalnet_locked(__u32 net);
void lnet_msg_attach_md(struct lnet_msg *msg, struct lnet_libmd *md,
unsigned int offset, unsigned int mlen);
-void lnet_msg_detach_md(struct lnet_msg *msg, int status);
void lnet_build_unlink_event(struct lnet_libmd *md, struct lnet_event *ev);
void lnet_build_msg_event(struct lnet_msg *msg, enum lnet_event_kind ev_type);
void lnet_msg_commit(struct lnet_msg *msg, int cpt);
unsigned int len);
int lnet_send(lnet_nid_t nid, struct lnet_msg *msg, lnet_nid_t rtr_nid);
int lnet_send_ping(lnet_nid_t dest_nid, struct lnet_handle_md *mdh, int nnis,
- void *user_ptr, struct lnet_handle_eq eqh, bool recovery);
+ void *user_ptr, struct lnet_eq *eq, bool recovery);
void lnet_return_tx_credits_locked(struct lnet_msg *msg);
void lnet_return_rx_credits_locked(struct lnet_msg *msg);
void lnet_schedule_blocked_locked(struct lnet_rtrbufpool *rbp);
void lnet_drop_routed_msgs_locked(struct list_head *list, int cpt);
+struct list_head **lnet_create_array_of_queues(void);
+
/* portals functions */
/* portals attributes */
static inline int
void lnet_set_reply_msg_len(struct lnet_ni *ni, struct lnet_msg *msg,
unsigned int len);
void lnet_detach_rsp_tracker(struct lnet_libmd *md, int cpt);
+void lnet_clean_zombie_rstqs(void);
void lnet_finalize(struct lnet_msg *msg, int rc);
bool lnet_send_error_simulation(struct lnet_msg *msg,
enum lnet_msg_hstatus *hstatus);
+void lnet_handle_remote_failure_locked(struct lnet_peer_ni *lpni);
void lnet_drop_message(struct lnet_ni *ni, int cpt, void *private,
unsigned int nob, __u32 msg_type);
int lnet_fault_init(void);
void lnet_fault_fini(void);
-bool lnet_drop_rule_match(struct lnet_hdr *hdr, enum lnet_msg_hstatus *hstatus);
+bool lnet_drop_rule_match(struct lnet_hdr *hdr, lnet_nid_t local_nid,
+ enum lnet_msg_hstatus *hstatus);
int lnet_delay_rule_add(struct lnet_fault_attr *attr);
int lnet_delay_rule_del(lnet_nid_t src, lnet_nid_t dst, bool shutdown);
int lnet_cpt_of_md(struct lnet_libmd *md, unsigned int offset);
unsigned int lnet_get_lnd_timeout(void);
-void lnet_register_lnd(struct lnet_lnd *lnd);
-void lnet_unregister_lnd(struct lnet_lnd *lnd);
+void lnet_register_lnd(const struct lnet_lnd *lnd);
+void lnet_unregister_lnd(const struct lnet_lnd *lnd);
int lnet_connect(struct socket **sockp, lnet_nid_t peer_nid,
- __u32 local_ip, __u32 peer_ip, int peer_port);
+ __u32 local_ip, __u32 peer_ip, int peer_port, struct net *ns);
void lnet_connect_console_error(int rc, lnet_nid_t peer_nid,
__u32 peer_ip, int port);
int lnet_count_acceptor_nets(void);
int lnet_acceptor_start(void);
void lnet_acceptor_stop(void);
-int lnet_ipif_query(char *name, int *up, __u32 *ip, __u32 *mask);
-int lnet_ipif_enumerate(char ***names);
-void lnet_ipif_free_enumeration(char **names, int n);
+struct lnet_inetdev {
+ u32 li_cpt;
+ u32 li_flags;
+ u32 li_ipaddr;
+ u32 li_netmask;
+ char li_name[IFNAMSIZ];
+};
+
+int lnet_inet_enumerate(struct lnet_inetdev **dev_list, struct net *ns);
int lnet_sock_setbuf(struct socket *socket, int txbufsize, int rxbufsize);
int lnet_sock_getbuf(struct socket *socket, int *txbufsize, int *rxbufsize);
int lnet_sock_getaddr(struct socket *socket, bool remote, __u32 *ip, int *port);
int lnet_sock_write(struct socket *sock, void *buffer, int nob, int timeout);
int lnet_sock_read(struct socket *sock, void *buffer, int nob, int timeout);
-int lnet_sock_listen(struct socket **sockp, __u32 ip, int port, int backlog);
-int lnet_sock_accept(struct socket **newsockp, struct socket *sock);
+int lnet_sock_listen(struct socket **sockp, __u32 ip, int port, int backlog,
+ struct net *ns);
int lnet_sock_connect(struct socket **sockp, int *fatal,
__u32 local_ip, int local_port,
- __u32 peer_ip, int peer_port);
+ __u32 peer_ip, int peer_port, struct net *ns);
int lnet_peers_start_down(void);
int lnet_peer_buffer_credits(struct lnet_net *net);
+void lnet_consolidate_routes_locked(struct lnet_peer *orig_lp,
+ struct lnet_peer *new_lp);
+void lnet_router_discovery_complete(struct lnet_peer *lp);
+void lnet_router_discovery_ping_reply(struct lnet_peer *lp);
int lnet_monitor_thr_start(void);
void lnet_monitor_thr_stop(void);
bool lnet_router_checker_active(void);
void lnet_check_routers(void);
-int lnet_router_pre_mt_start(void);
-void lnet_router_post_mt_start(void);
-void lnet_prune_rc_data(int wait_unlink);
-void lnet_router_cleanup(void);
-void lnet_router_ni_update_locked(struct lnet_peer_ni *gw, __u32 net);
+void lnet_wait_router_start(void);
void lnet_swap_pinginfo(struct lnet_ping_buffer *pbuf);
int lnet_ping_info_validate(struct lnet_ping_info *pinfo);
lnet_ping_buffer_free(pbuf);
}
-static inline int lnet_ping_buffer_numref(struct lnet_ping_buffer *pbuf)
-{
- return atomic_read(&pbuf->pb_refcnt);
-}
-
static inline int lnet_push_target_resize_needed(void)
{
return the_lnet.ln_push_target->pb_nnis < the_lnet.ln_push_target_nnis;
}
int lnet_push_target_resize(void);
+int lnet_push_target_post(struct lnet_ping_buffer *pbuf,
+ struct lnet_handle_md *mdh);
void lnet_peer_push_event(struct lnet_event *ev);
int lnet_parse_ip2nets(char **networksp, char *ip2nets);
bool lnet_ni_unique_net(struct list_head *nilist, char *iface);
void lnet_incr_dlc_seq(void);
__u32 lnet_get_dlc_seq_locked(void);
+int lnet_get_net_count(void);
+extern unsigned int lnet_current_net_count;
+struct lnet_peer_net *lnet_get_next_peer_net_locked(struct lnet_peer *lp,
+ __u32 prev_lpn_id);
struct lnet_peer_ni *lnet_get_next_peer_ni_locked(struct lnet_peer *peer,
struct lnet_peer_net *peer_net,
struct lnet_peer_ni *prev);
struct lnet_peer_ni *lnet_nid2peerni_locked(lnet_nid_t nid, lnet_nid_t pref,
int cpt);
struct lnet_peer_ni *lnet_nid2peerni_ex(lnet_nid_t nid, int cpt);
+struct lnet_peer_ni *lnet_peer_get_ni_locked(struct lnet_peer *lp,
+ lnet_nid_t nid);
struct lnet_peer_ni *lnet_find_peer_ni_locked(lnet_nid_t nid);
struct lnet_peer *lnet_find_peer(lnet_nid_t nid);
void lnet_peer_net_added(struct lnet_net *net);
return NULL;
}
-static inline void
-lnet_peer_set_alive(struct lnet_peer_ni *lp)
-{
- lp->lpni_last_alive = ktime_get_seconds();
- lp->lpni_last_query = lp->lpni_last_alive;
- if (!lp->lpni_alive)
- lnet_notify_locked(lp, 0, 1, lp->lpni_last_alive);
-}
-
static inline bool
lnet_peer_is_multi_rail(struct lnet_peer *lp)
{
}
bool lnet_peer_is_uptodate(struct lnet_peer *lp);
+bool lnet_peer_is_uptodate_locked(struct lnet_peer *lp);
+bool lnet_is_discovery_disabled(struct lnet_peer *lp);
+bool lnet_is_discovery_disabled_locked(struct lnet_peer *lp);
+bool lnet_peer_gw_discovery(struct lnet_peer *lp);
static inline bool
lnet_peer_needs_push(struct lnet_peer *lp)
return true;
if (lp->lp_state & LNET_PEER_NO_DISCOVERY)
return false;
+ /* if discovery is not enabled then no need to push */
+ if (lnet_peer_discovery_disabled)
+ return false;
if (lp->lp_node_seqno < atomic_read(&the_lnet.ln_ping_target_seqno))
return true;
return false;
}
+/*
+ * A peer is alive if it satisfies the following two conditions:
+ * 1. peer health >= LNET_MAX_HEALTH_VALUE * router_sensitivity_percentage
+ * 2. the cached NI status received when we discover the peer is UP
+ */
+static inline bool
+lnet_is_peer_ni_alive(struct lnet_peer_ni *lpni)
+{
+ bool halive = false;
+
+ halive = (atomic_read(&lpni->lpni_healthv) >=
+ (LNET_MAX_HEALTH_VALUE * router_sensitivity_percentage / 100));
+
+ return halive && lpni->lpni_ns_status == LNET_NI_STATUS_UP;
+}
+
+static inline void
+lnet_update_peer_net_healthv(struct lnet_peer_ni *lpni)
+{
+ struct lnet_peer_net *lpn;
+ int best_healthv = 0;
+
+ lpn = lpni->lpni_peer_net;
+
+ list_for_each_entry(lpni, &lpn->lpn_peer_nis, lpni_peer_nis) {
+ int lpni_healthv = atomic_read(&lpni->lpni_healthv);
+ if (best_healthv < lpni_healthv)
+ best_healthv = lpni_healthv;
+ }
+
+ lpn->lpn_healthv = best_healthv;
+}
+
+static inline void
+lnet_set_lpni_healthv_locked(struct lnet_peer_ni *lpni, int value)
+{
+ if (atomic_read(&lpni->lpni_healthv) == value)
+ return;
+ atomic_set(&lpni->lpni_healthv, value);
+ lnet_update_peer_net_healthv(lpni);
+}
+
+static inline void
+lnet_inc_lpni_healthv_locked(struct lnet_peer_ni *lpni)
+{
+ /* only adjust the net health if the lpni health value changed */
+ if (atomic_add_unless(&lpni->lpni_healthv, 1, LNET_MAX_HEALTH_VALUE))
+ lnet_update_peer_net_healthv(lpni);
+}
+
static inline void
lnet_inc_healthv(atomic_t *healthv)
{