int LNetEQPoll(lnet_handle_eq_t *eventqs_in,
int neq_in,
- int timeout_ms,
+ signed long timeout,
lnet_event_t *event_out,
int *which_eq_out);
/** @} lnet_eq */
#define LNET_PID_USERFLAG 0x80000000 /* set in userspace peers */
#define LNET_PID_LUSTRE 12345
-#define LNET_TIME_FOREVER (-1)
-
/* how an LNET NID encodes net:address */
/** extract the address part of an lnet_nid_t */
module_param(rnet_htable_size, int, 0444);
MODULE_PARM_DESC(rnet_htable_size, "size of remote network hash table");
-static int lnet_ping(lnet_process_id_t id, int timeout_ms,
+static int lnet_ping(lnet_process_id_t id, signed long timeout,
lnet_process_id_t __user *ids, int n_ids);
static char *
case IOC_LIBCFS_LNET_FAULT:
return lnet_fault_ctl(data->ioc_flags, data);
- case IOC_LIBCFS_PING:
+ case IOC_LIBCFS_PING: {
+ signed long timeout;
+
id.nid = data->ioc_nid;
id.pid = data->ioc_u32[0];
- rc = lnet_ping(id, data->ioc_u32[1], /* timeout */
- data->ioc_pbuf1,
- data->ioc_plen1/sizeof(lnet_process_id_t));
+
+ /* Don't block longer than 2 minutes */
+ if (data->ioc_u32[1] > 120 * MSEC_PER_SEC)
+ return -EINVAL;
+
+ /* If timestamp is negative then disable timeout */
+ if ((s32)data->ioc_u32[1] < 0)
+ timeout = MAX_SCHEDULE_TIMEOUT;
+ else
+ timeout = msecs_to_jiffies(data->ioc_u32[1]);
+
+ rc = lnet_ping(id, timeout, data->ioc_pbuf1,
+ data->ioc_plen1 / sizeof(lnet_process_id_t));
if (rc < 0)
return rc;
data->ioc_count = rc;
return 0;
-
+ }
default:
ni = lnet_net2ni(data->ioc_net);
if (ni == NULL)
}
EXPORT_SYMBOL(LNetSnprintHandle);
-static int
-lnet_ping(lnet_process_id_t id, int timeout_ms, lnet_process_id_t __user *ids,
- int n_ids)
+static int lnet_ping(lnet_process_id_t id, signed long timeout,
+ lnet_process_id_t __user *ids, int n_ids)
{
lnet_handle_eq_t eqh;
lnet_handle_md_t mdh;
int which;
int unlinked = 0;
int replied = 0;
- const int a_long_time = 60000; /* mS */
+ const signed long a_long_time = msecs_to_jiffies(60 * MSEC_PER_SEC);
int infosz;
struct lnet_ping_info *info;
lnet_process_id_t tmpid;
infosz = offsetof(struct lnet_ping_info, pi_ni[n_ids]);
- if (n_ids <= 0 ||
- id.nid == LNET_NID_ANY ||
- timeout_ms > 500000 || /* arbitrary limit! */
- n_ids > 20) /* arbitrary limit! */
+ /* n_ids limit is arbitrary */
+ if (n_ids <= 0 || n_ids > 20 || id.nid == LNET_NID_ANY)
return -EINVAL;
if (id.pid == LNET_PID_ANY)
/* NB must wait for the UNLINK event below... */
unlinked = 1;
- timeout_ms = a_long_time;
+ timeout = a_long_time;
}
do {
if (unlinked)
blocked = cfs_block_allsigs();
- rc2 = LNetEQPoll(&eqh, 1, timeout_ms, &event, &which);
+ rc2 = LNetEQPoll(&eqh, 1, timeout, &event, &which);
if (unlinked)
cfs_restore_sigs(blocked);
LNetMDUnlink(mdh);
/* No assertion (racing with network) */
unlinked = 1;
- timeout_ms = a_long_time;
+ timeout = a_long_time;
} else if (rc2 == 0) {
/* timed out waiting for unlink */
CWARN("ping %s: late network completion\n",
{
int which;
- return LNetEQPoll(&eventq, 1, LNET_TIME_FOREVER,
- event, &which);
+ return LNetEQPoll(&eventq, 1, MAX_SCHEDULE_TIMEOUT,
+ event, &which);
}
EXPORT_SYMBOL(LNetEQWait);
static int
-lnet_eq_wait_locked(int *timeout_ms)
+lnet_eq_wait_locked(signed long *timeout)
__must_hold(&the_lnet.ln_eq_wait_lock)
{
- int tms = *timeout_ms;
- int wait;
- wait_queue_t wl;
- cfs_time_t now;
+ signed long tms = *timeout;
+ wait_queue_t wl;
+ int wait;
if (tms == 0)
return -ENXIO; /* don't want to wait and no new event */
init_waitqueue_entry(&wl, current);
- set_current_state(TASK_INTERRUPTIBLE);
add_wait_queue(&the_lnet.ln_eq_waitq, &wl);
lnet_eq_wait_unlock();
- if (tms < 0) {
- schedule();
- } else {
- struct timeval tv;
-
- now = cfs_time_current();
- schedule_timeout(cfs_time_seconds(tms) / 1000);
- cfs_duration_usec(cfs_time_sub(cfs_time_current(), now), &tv);
- tms -= (int)(tv.tv_sec * 1000 + tv.tv_usec / 1000);
- if (tms < 0) /* no more wait but may have new event */
- tms = 0;
- }
-
+ tms = schedule_timeout_interruptible(tms);
wait = tms != 0; /* might need to call here again */
- *timeout_ms = tms;
+ *timeout = tms;
lnet_eq_wait_lock();
remove_wait_queue(&the_lnet.ln_eq_waitq, &wl);
* fixed period, or block indefinitely.
*
* \param eventqs,neq An array of EQ handles, and size of the array.
- * \param timeout_ms Time in milliseconds to wait for an event to occur on
- * one of the EQs. The constant LNET_TIME_FOREVER can be used to indicate an
+ * \param timeout Time in jiffies to wait for an event to occur on
+ * one of the EQs. The constant MAX_SCHEDULE_TIMEOUT can be used to indicate an
* infinite timeout.
* \param event,which On successful return (1 or -EOVERFLOW), \a event will
* hold the next event in the EQs, and \a which will contain the index of the
* \retval -ENOENT If there's an invalid handle in \a eventqs.
*/
int
-LNetEQPoll(lnet_handle_eq_t *eventqs, int neq, int timeout_ms,
+LNetEQPoll(lnet_handle_eq_t *eventqs, int neq, signed long timeout,
lnet_event_t *event, int *which)
{
int wait = 1;
* 0 : don't want to wait anymore, but might have new event
* so need to call dequeue again
*/
- wait = lnet_eq_wait_locked(&timeout_ms);
+ wait = lnet_eq_wait_locked(&timeout);
if (wait < 0) /* no new event */
break;
}
}
}
- if (argc > 2)
- timeout = 1000 * atol(argv[2]);
- else
+ if (argc > 2) {
+ timeout = 1000 * atol(argv[2]);
+ if (timeout > 120 * 1000) {
+ fprintf(stderr, "Timeout %s is to large\n",
+ argv[2]);
+ return -1;
+ }
+ } else
timeout = 1000; /* default 1 second timeout */
LIBCFS_IOC_INIT (data);
Note the replace_nids command skips any invalidated records in the configuration log.
The previous log is backed up with the suffix '.bak'.
.TP
-.BI ping " <nid> "
+.BI ping " <nid> timeout"
Check LNET connectivity via an LNET ping. This will use the fabric
-appropriate to the specified NID.
+appropriate to the specified NID. By default lctl will attempt to
+reach the remote node up to 120 seconds and then timeout. To disable
+the timeout just specify an negative timeout value.
.TP
.BI interface_list
Print the network interface information for a given