diff options
author | David Howells <dhowells@redhat.com> | 2020-03-27 16:02:44 +0100 |
---|---|---|
committer | David Howells <dhowells@redhat.com> | 2020-05-31 16:19:51 +0200 |
commit | 8230fd8217b7ea76f838ae88e4a5a8e54f37099f (patch) | |
tree | c395ba533ee29c24e1ce7e4c0b9f65f8b14e0972 /fs/afs/internal.h | |
parent | afs: Show more information in /proc/net/afs/servers (diff) | |
download | linux-8230fd8217b7ea76f838ae88e4a5a8e54f37099f.tar.xz linux-8230fd8217b7ea76f838ae88e4a5a8e54f37099f.zip |
afs: Make callback processing more efficient.
afs_vol_interest objects represent the volume IDs currently being accessed
from a fileserver. These hold lists of afs_cb_interest objects that
repesent the superblocks using that volume ID on that server.
When a callback notification from the server telling of a modification by
another client arrives, the volume ID specified in the notification is
looked up in the server's afs_vol_interest list. Through the
afs_cb_interest list, the relevant superblocks can be iterated over and the
specific inode looked up and marked in each one.
Make the following efficiency improvements:
(1) Hold rcu_read_lock() over the entire processing rather than locking it
each time.
(2) Do all the callbacks for each vid together rather than individually.
Each volume then only needs to be looked up once.
(3) afs_vol_interest objects are now stored in an rb_tree rather than a
flat list to reduce the lookup step count.
(4) afs_vol_interest lookup is now done with RCU, but because it's in an
rb_tree which may rotate under us, a seqlock is used so that if it
changes during the walk, we repeat the walk with a lock held.
With this and the preceding patch which adds RCU-based lookups in the inode
cache, target volumes/vnodes can be taken without the need to take any
locks, except on the target itself.
Signed-off-by: David Howells <dhowells@redhat.com>
Diffstat (limited to 'fs/afs/internal.h')
-rw-r--r-- | fs/afs/internal.h | 6 |
1 files changed, 3 insertions, 3 deletions
diff --git a/fs/afs/internal.h b/fs/afs/internal.h index 61320a632e15..b6665fc5d355 100644 --- a/fs/afs/internal.h +++ b/fs/afs/internal.h @@ -524,9 +524,9 @@ struct afs_server { rwlock_t fs_lock; /* access lock */ /* callback promise management */ - struct hlist_head cb_volumes; /* List of volume interests on this server */ + struct rb_root cb_volumes; /* List of volume interests on this server */ unsigned cb_s_break; /* Break-everything counter. */ - rwlock_t cb_break_lock; /* Volume finding lock */ + seqlock_t cb_break_lock; /* Volume finding lock */ /* Probe state */ unsigned long probed_at; /* Time last probe was dispatched (jiffies) */ @@ -552,7 +552,7 @@ struct afs_server { * Volume collation in the server's callback interest list. */ struct afs_vol_interest { - struct hlist_node srv_link; /* Link in server->cb_volumes */ + struct rb_node srv_node; /* Link in server->cb_volumes */ struct hlist_head cb_interests; /* List of callback interests on the server */ union { struct rcu_head rcu; |