static void ptlrpc_at_timer(unsigned long castmeharder)
{
struct ptlrpc_service *svc = (struct ptlrpc_service *)castmeharder;
- CDEBUG(D_ADAPTTO, "at timer %s hit at %ld%s\n",
+ CDEBUG(D_INFO, "at timer %s hit at %ld%s\n",
svc->srv_name, cfs_time_current_sec(),
list_empty(&svc->srv_at_list) ? ", empty" : "");
svc->srv_at_check = 1;
struct ptlrpc_service *svc = req->rq_rqbd->rqbd_service;
struct ptlrpc_request *reqcopy;
struct lustre_msg *reqmsg;
- long deadline = req->rq_deadline - cfs_time_current_sec();
+ long olddl = req->rq_deadline - cfs_time_current_sec();
+ time_t newdl;
int rc;
ENTRY;
DEBUG_REQ(D_ADAPTTO, req,
"%ssending early reply (deadline %+lds, margin %+lds) for "
"%d+%d", AT_OFF ? "AT off - not " : "",
- deadline, deadline - at_get(&svc->srv_at_estimate),
+ olddl, olddl - at_get(&svc->srv_at_estimate),
at_get(&svc->srv_at_estimate), extra_time);
if (AT_OFF)
RETURN(0);
- if (deadline < 0) {
- CERROR("Already past deadline (%+lds), not sending early "
- "reply\n", deadline);
+ if (olddl < 0) {
+ CDEBUG(D_ADAPTTO, "x"LPU64": Already past deadline (%+lds), not"
+ " sending early reply\n", req->rq_xid, olddl);
/* Return an error so we're not re-added to the timed list. */
RETURN(-ETIMEDOUT);
}
if ((lustre_msg_get_flags(req->rq_reqmsg) & MSG_AT_SUPPORT) == 0) {
- CERROR("Wanted to ask client for more time, but no AT "
- "support\n");
+ CDEBUG(D_INFO, "Wanted to ask client for more time, but no AT "
+ "support\n");
RETURN(-ENOSYS);
}
+ if (extra_time) {
+ /* Fake our processing time into the future to ask the
+ clients for some extra amount of time */
+ extra_time += cfs_time_current_sec() -
+ req->rq_arrival_time.tv_sec;
+ at_add(&svc->srv_at_estimate, extra_time);
+ }
+
+ newdl = req->rq_arrival_time.tv_sec + at_get(&svc->srv_at_estimate);
+ if (req->rq_deadline >= newdl) {
+ /* We're not adding any time, no need to send an early reply
+ (e.g. maybe at adaptive_max) */
+ CDEBUG(D_ADAPTTO, "x"LPU64": Couldn't add any time (%ld/%ld), "
+ "not sending early reply\n", req->rq_xid, olddl,
+ newdl - cfs_time_current_sec());
+ RETURN(-ETIMEDOUT);
+ }
+
OBD_ALLOC(reqcopy, sizeof *reqcopy);
if (reqcopy == NULL)
RETURN(-ENOMEM);
}
*reqcopy = *req;
- /* We need the reqmsg for the magic */
+ reqcopy->rq_reply_state = NULL;
+ reqcopy->rq_rep_swab_mask = 0;
+ /* We only need the reqmsg for the magic */
reqcopy->rq_reqmsg = reqmsg;
memcpy(reqmsg, req->rq_reqmsg, req->rq_reqlen);
if (rc)
GOTO(out, rc);
- if (extra_time) {
- /* Fake our processing time into the future to ask the
- clients for some extra amount of time */
- extra_time += cfs_time_current_sec() -
- reqcopy->rq_arrival_time.tv_sec;
- at_add(&svc->srv_at_estimate, extra_time);
- }
-
rc = ptlrpc_send_reply(reqcopy, PTLRPC_REPLY_EARLY);
if (!rc) {
/* Adjust our own deadline to what we told the client */
- req->rq_deadline = req->rq_arrival_time.tv_sec +
- at_get(&svc->srv_at_estimate);
+ req->rq_deadline = newdl;
req->rq_early_count++; /* number sent, server side */
} else {
DEBUG_REQ(D_ERROR, req, "Early reply send failed %d", rc);
deleted, and is safe to take a ref to keep the req around */
atomic_inc(&rq->rq_refcount);
spin_unlock(&svc->srv_at_lock);
- if (!rq->rq_packed_final &&
- (ptlrpc_at_send_early_reply(rq, at_extra) == 0)) {
+ if (ptlrpc_at_send_early_reply(rq, at_extra) == 0) {
counter++;
ptlrpc_at_add_timed(rq);
}
SAMPLE_NAME=recovery-small.junk
SAMPLE_FILE=$TMP/$SAMPLE_NAME
-dd if=/dev/urandom of=$SAMPLE_FILE bs=1K count=4
+# make this big, else test 9 doesn't wait for bulk -- bz 5595
+dd if=/dev/urandom of=$SAMPLE_FILE bs=1M count=4
test_4() {
do_facet client "cp $SAMPLE_FILE $MOUNT/$SAMPLE_NAME" || return 1
run_test 16 "timeout bulk put, don't evict client (2732)"
test_17() {
+ # With adaptive timeouts, bulk_get won't expire until adaptive_timeout_max
+ OST_AT_MAX=$(do_facet ost1 sysctl -n lustre.adaptive_max)
+ do_facet ost1 sysctl -w lustre.adaptive_max=$TIMEOUT
+
# OBD_FAIL_PTLRPC_BULK_GET_NET 0x0503 | OBD_FAIL_ONCE
# OST bulk will time out here, client retries
do_facet ost1 sysctl -w lustre.fail_loc=0x80000503
do_facet client cp $SAMPLE_FILE $DIR/$tfile
sync
- sleep $TIMEOUT
+ # with AT, client will wait adaptive_max*factor+net_latency before
+ # expiring the req, hopefully timeout*2 is enough
+ sleep $(($TIMEOUT*2))
+
do_facet ost1 sysctl -w lustre.fail_loc=0
do_facet client "df $DIR"
# expect cmp to succeed, client resent bulk
do_facet client "cmp $SAMPLE_FILE $DIR/$tfile" || return 3
do_facet client "rm $DIR/$tfile" || return 4
+ do_facet ost1 sysctl -w lustre.adaptive_max=$OST_AT_MAX
return 0
}
run_test 17 "timeout bulk get, don't evict client (2732)"
fi
}
-test_65() #bug 3055
+test_65a() #bug 3055
{
at_start
$LCTL dk > /dev/null
unlinkmany $DIR/$tfile 10 > /dev/null
# check for log message
$LCTL dk | grep "Early reply #" || error "No early reply"
- # client should show 30s timeouts
+ # client should show 30s estimates
grep portal $LPROC/mdc/${FSNAME}-MDT0000-mdc-*/timeouts
sleep 9
grep portal $LPROC/mdc/${FSNAME}-MDT0000-mdc-*/timeouts
}
-run_test 65 "AT: verify early replies"
+run_test 65a "AT: verify early replies"
+
+test_65b() #bug 3055
+{
+ at_start
+ # turn on D_ADAPTTO
+ debugsave
+ sysctl -w lnet.debug="+other"
+ $LCTL dk > /dev/null
+ # slow down bulk i/o
+ do_facet ost1 sysctl -w lustre.fail_val=30
+#define OBD_FAIL_OST_BRW_PAUSE_PACK 0x224
+ do_facet ost1 sysctl -w lustre.fail_loc=0x224
+
+ rm -f $DIR/$tfile
+ lfs setstripe $DIR/$tfile --index=0 --count=1
+ # force some real bulk transfer
+ dd if=/dev/urandom of=$TMP/big bs=1M count=4
+ cp $TMP/big $DIR/$tfile
+ echo "append" >> $DIR/$tfile
+ cat $DIR/$tfile >> /dev/null
+ rm $TMP/big
+
+ do_facet ost1 sysctl -w lustre.fail_loc=0
+ # check for log message
+ $LCTL dk | grep "Early reply #" || error "No early reply"
+ debugrestore
+ # client should show 30s estimates
+ grep portal $LPROC/osc/${FSNAME}-OST0000-osc-*/timeouts
+}
+run_test 65b "AT: verify early replies on packed reply / bulk"
test_66a() #bug 3055
{