So, I think we have to be careful here. When I first developed lockahead, I tested turning off lock expansion when doing multi-client shared file. So exactly what you're suggesting here.
I found it hurt performance in the shared file case.
The reason is a little challenging to explain (and the graphs I made for this are lost long ago, heh).
Normally, when (for example) two clients are writing a single OST object with one process each, we imagine the process is something like this.
Client 1 writes [0, 1 MiB). Requests lock, call it lock 'A'. Server expands lock A, 0 - infinity.
Client 2 writes [1,2 MiB). Requests lock B. Server cancels lock A. Server expands lock B, 0 - infinity. (Or maybe it's 1 MiB to infinity? Doesn't matter)
Client 1 writes [2, 3 Mib). Requests lock C... etc, etc.
Here is what actually happens.
Client 1 writes [0, 1 MiB). Acquires lock A, 0 - infinity.
Client 2 tries to write [1, 2 MiB), sends request to server, etc.
Client 1 writes [2, 3 MiB) using lock A.
Client 1 writes [4, 5 MiB) using lock A...
Client 1 writes [6. 7 MiB) using lock A...
[...]
Server calls back lock A, but only after client 1 has done some number of writes. (In my testing, I think it was like 4 1 MiB writes on average?)
So client 2 is waiting for client 1, but client 1 gets a bunch of work done before the lock is called back.
This is very important, because if you turn off lock expansion, now the client write process looks like this.
Start write
Request lock
Lock request goes to server
Get lock from server
Do write...
We have added an extra round trip to the server for every write.
So what I found in my testing was that until contention was very high (many clients to a single object), the overhead of doing a lock request for every write was worse than waiting for the other client. Note if there is > 1 process writing to each OST object on the same client, they also benefit from sharing the expanded lock. So disabling lock expansion on contention often made performance worse, because the overhead of asking for a lock for every write was worse than the serialization of waiting for the other client(s).
This is just something to be aware of and test for. My testing was on disk, flash may change things. I think disabling expansion will help under heavy contention, but only under heavy contention (many clients to one object). So we should do some careful testing of write performance with disabling expansion on contention, with both a small and a large number of clients and processes per object.
In this formula, if current_count = previous_count, then "rate = 1.5 x current_count" which is bad.
I think one of the important properties of decaying average is that they are equal to the original value if it is constant. For example:
That means that the weighted sum = 1.0 no matter what the weight is, and if previous_value = current_value, then new_value will be the same.
In the above formulas