From 1fd0a52e6727b191aa008f7a260ad748d34d5870 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 15 Aug 2019 17:26:43 +0200 Subject: s3:blocking: use dynamic posix lock wait intervals We want to start with a short timeout (200ms) and slow down to larger timeouts up to 2s for the default value of "lock spin time". BUG: https://bugzilla.samba.org/show_bug.cgi?id=14113 Signed-off-by: Stefan Metzmacher Reviewed-by: Volker Lendecke (cherry picked from commit 15765644d2590d6549f8fcc01c39c56387eed654) --- source3/smbd/blocking.c | 41 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 37 insertions(+), 4 deletions(-) diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index af889a10d62..50e1d436eb7 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -102,6 +102,7 @@ struct smbd_smb1_do_locks_state { struct smb_request *smbreq; struct files_struct *fsp; uint32_t timeout; + uint32_t polling_msecs; struct timeval endtime; bool large_offset; /* required for correct cancel */ enum brl_flavour lock_flav; @@ -115,6 +116,32 @@ static void smbd_smb1_do_locks_retry(struct tevent_req *subreq); static void smbd_smb1_blocked_locks_cleanup( struct tevent_req *req, enum tevent_req_state req_state); +static void smbd_smb1_do_locks_update_polling_msecs( + struct smbd_smb1_do_locks_state *state) +{ + /* + * The default lp_lock_spin_time() is 200ms. + * + * v_min is in the range of 0.002 to 20 secs + * (0.2 secs by default) + * + * v_max is in the range of 0.02 to 200 secs + * (2.0 secs by default) + * + * The typical steps are: + * 0.2, 0.4, 0.6, 0.8, ... 2.0 + */ + uint32_t v_min = MAX(2, MIN(20000, lp_lock_spin_time())); + uint32_t v_max = 10 * v_min; + + if (state->polling_msecs >= v_max) { + state->polling_msecs = v_max; + return; + } + + state->polling_msecs += v_min; +} + struct tevent_req *smbd_smb1_do_locks_send( TALLOC_CTX *mem_ctx, struct tevent_context *ev, @@ -237,9 +264,12 @@ struct tevent_req *smbd_smb1_do_locks_send( if (blocking_smblctx == UINT64_MAX) { struct timeval tmp; - DBG_DEBUG("Blocked on a posix lock. Retry in one second\n"); + smbd_smb1_do_locks_update_polling_msecs(state); + + DBG_DEBUG("Blocked on a posix lock. Retry in %"PRIu32" msecs\n", + state->polling_msecs); - tmp = timeval_current_ofs(1, 0); + tmp = timeval_current_ofs_msec(state->polling_msecs); endtime = timeval_min(&endtime, &tmp); } @@ -373,9 +403,12 @@ static void smbd_smb1_do_locks_try(struct tevent_req *req) if (blocking_smblctx == UINT64_MAX) { struct timeval tmp; - DBG_DEBUG("Blocked on a posix lock. Retry in one second\n"); + smbd_smb1_do_locks_update_polling_msecs(state); + + DBG_DEBUG("Blocked on a posix lock. Retry in %"PRIu32" msecs\n", + state->polling_msecs); - tmp = timeval_current_ofs(1, 0); + tmp = timeval_current_ofs_msec(state->polling_msecs); endtime = timeval_min(&endtime, &tmp); } -- cgit v1.2.1