[LU-15178] clean up/clarify use of CEF_SPECULATIVE/LDLM_FL_SPECULATIVE Created: 29/Oct/21  Updated: 03/Nov/21

Status: Open
Project: Lustre
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Minor
Reporter: Patrick Farrell Assignee: Patrick Farrell
Resolution: Unresolved Votes: 0
Labels: None

Rank (Obsolete): 9223372036854775807

 Description   

There were some poor choices made (by me) when the lockahead code was originally finalized.  The concept of a "speculative" lock, a lock requested before it's used (and which may never be used), is a mix of two things: asynchronous on the client, and nonblocking (in terms of not cancelling or waiting for other locks) on the server.

But the async behavior is a client only concept, so LDLM_FL_SPECULATIVE only actually enforces non-blocking behavior, and has nothing to do with async.  (The existing LDLM_FL_BLOCK_NOWAIT is also used for O_NONBLOCK in a way which means it could not be reused for this.)

Async lock requests must be non-blocking, but non-blocking requests are not fundamentally speculative.

Separating the concept of async requests from the concept of a non-blocking request lets us make non-blocking requests for readahead, where the request is best described as 'optional' - The lock will always be used if it is granted, but it's OK if it's not granted.

This means creating separate CEF_ASYNC and CEF_NOWAIT flags on the client.  CEF_ASYNC does require CEF_NOWAIT, but CEF_NOWAIT does not require CEF_ASYNC.  (We'll enforce this with an assert.)

It's also a good idea to rename the existing LDLM_FL_SPECULATIVE lock flag to LDLM_FL_NOWAIT - the behavior and the bit # will remain unchanged, so we can rename it without causing interop issues with older clients.  This will be carefully commented in the code.

To summarize, there are three variables which describe a lock request.
Sync vs Async: Is the requesting thread going to wait for the response from the server?

Blocking vs non-blocking (wait vs nowait): Will the lock request cancel existing locks, or will it fail if it finds a conflicting lock?  Note that async requires non-blocking.

Expansion vs No-expansion: No-expand is a property of lockahead locks, where they have manually specified extent ranges and the server does not expand them.  Normal locks are expanded.

Today, we allow the following:

Sync/Async Blocking/Non-Blocking Expansion/No Expansion Notes
Sync Blocking Expansion OK
Sync Blocking No Expansion OK
Sync Non-Blocking Expansion Not allowed today because Async + Non-blocking behavior combined.
New patch allows this by separating behavior.
Sync Non-Blocking No Expansion  Not allowed today because Async + Non-blocking behavior combined.
New patch allows this by separating behavior.
Async Blocking Expansion No async + blocking
Async Blocking No Expansion No async + blocking
Async Non-Blocking Expansion Not allowed, due to size issues explained in ofd_intent_cb.
Can allow for read locks, will do so in new patch.
Async Non-Blocking No Expansion OK (Standard lockahead)

A little complicated.

Patch forthcoming later.

 



 Comments   
Comment by Gerrit Updater [ 03/Nov/21 ]

"Patrick Farrell <pfarrell@whamcloud.com>" uploaded a new patch: https://review.whamcloud.com/45449
Subject: LU-15178 llite: Clarify async vs nowait
Project: fs/lustre-release
Branch: master
Current Patch Set: 1
Commit: 3d3af4e9a79b85b026ede8409903c0a546844882

Generated at Sat Feb 10 03:16:07 UTC 2024 using Jira 9.4.14#940014-sha1:734e6822bbf0d45eff9af51f82432957f73aa32c.