Skip to content

Commit f3c130e

Browse files
committed
afs: Don't use probe running state to make decisions outside probe code
Don't use the running state for fileserver probes to make decisions about which server to use as the state is cleared at the start of a probe and also intermediate values might be misleading. Instead, add a separate 'latest known' rtt in the afs_server struct and a flag to indicate if the server is known to be responding and update these as and when we know what to change them to. Signed-off-by: David Howells <dhowells@redhat.com>
1 parent f11a016 commit f3c130e

4 files changed

Lines changed: 18 additions & 8 deletions

File tree

fs/afs/fs_probe.c

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,13 @@ static void afs_finished_fs_probe(struct afs_net *net, struct afs_server *server
4242
bool responded = server->probe.responded;
4343

4444
write_seqlock(&net->fs_lock);
45-
if (responded)
45+
if (responded) {
4646
list_add_tail(&server->probe_link, &net->fs_probe_slow);
47-
else
47+
} else {
48+
server->rtt = UINT_MAX;
49+
clear_bit(AFS_SERVER_FL_RESPONDING, &server->flags);
4850
list_add_tail(&server->probe_link, &net->fs_probe_fast);
51+
}
4952
write_sequnlock(&net->fs_lock);
5053

5154
afs_schedule_fs_probe(net, server, !responded);
@@ -161,12 +164,14 @@ void afs_fileserver_probe_result(struct afs_call *call)
161164
rtt_us = rxrpc_kernel_get_srtt(call->net->socket, call->rxcall);
162165
if (rtt_us < server->probe.rtt) {
163166
server->probe.rtt = rtt_us;
167+
server->rtt = rtt_us;
164168
alist->preferred = index;
165169
}
166170

167171
smp_wmb(); /* Set rtt before responded. */
168172
server->probe.responded = true;
169173
set_bit(index, &alist->responded);
174+
set_bit(AFS_SERVER_FL_RESPONDING, &server->flags);
170175
out:
171176
spin_unlock(&server->probe_lock);
172177

@@ -224,7 +229,7 @@ int afs_wait_for_fs_probes(struct afs_server_list *slist, unsigned long untried)
224229
{
225230
struct wait_queue_entry *waits;
226231
struct afs_server *server;
227-
unsigned int rtt = UINT_MAX;
232+
unsigned int rtt = UINT_MAX, rtt_s;
228233
bool have_responders = false;
229234
int pref = -1, i;
230235

@@ -280,10 +285,11 @@ int afs_wait_for_fs_probes(struct afs_server_list *slist, unsigned long untried)
280285
for (i = 0; i < slist->nr_servers; i++) {
281286
if (test_bit(i, &untried)) {
282287
server = slist->servers[i].server;
283-
if (server->probe.responded &&
284-
server->probe.rtt < rtt) {
288+
rtt_s = READ_ONCE(server->rtt);
289+
if (test_bit(AFS_SERVER_FL_RESPONDING, &server->flags) &&
290+
rtt_s < rtt) {
285291
pref = i;
286-
rtt = server->probe.rtt;
292+
rtt = rtt_s;
287293
}
288294

289295
remove_wait_queue(&server->probe_wq, &waits[i]);

fs/afs/internal.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -496,6 +496,7 @@ struct afs_server {
496496
struct afs_server *gc_next; /* Next server in manager's list */
497497
time64_t unuse_time; /* Time at which last unused */
498498
unsigned long flags;
499+
#define AFS_SERVER_FL_RESPONDING 0 /* The server is responding */
499500
#define AFS_SERVER_FL_NOT_READY 1 /* The record is not ready for use */
500501
#define AFS_SERVER_FL_NOT_FOUND 2 /* VL server says no such server */
501502
#define AFS_SERVER_FL_VL_FAIL 3 /* Failed to access VL server */
@@ -508,6 +509,7 @@ struct afs_server {
508509
atomic_t ref; /* Object refcount */
509510
atomic_t active; /* Active user count */
510511
u32 addr_version; /* Address list version */
512+
unsigned int rtt; /* Server's current RTT in uS */
511513
unsigned int debug_id; /* Debugging ID for traces */
512514

513515
/* file service access */
@@ -522,7 +524,7 @@ struct afs_server {
522524
atomic_t probe_outstanding;
523525
spinlock_t probe_lock;
524526
struct {
525-
unsigned int rtt; /* RTT as ktime/64 */
527+
unsigned int rtt; /* RTT in uS */
526528
u32 abort_code;
527529
short error;
528530
bool responded:1;

fs/afs/rotate.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -341,7 +341,8 @@ bool afs_select_fileserver(struct afs_operation *op)
341341
for (i = 0; i < op->server_list->nr_servers; i++) {
342342
struct afs_server *s = op->server_list->servers[i].server;
343343

344-
if (!test_bit(i, &op->untried) || !s->probe.responded)
344+
if (!test_bit(i, &op->untried) ||
345+
!test_bit(AFS_SERVER_FL_RESPONDING, &s->flags))
345346
continue;
346347
if (s->probe.rtt < rtt) {
347348
op->index = i;

fs/afs/server.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,7 @@ static struct afs_server *afs_alloc_server(struct afs_cell *cell,
239239
INIT_LIST_HEAD(&server->probe_link);
240240
spin_lock_init(&server->probe_lock);
241241
server->cell = cell;
242+
server->rtt = UINT_MAX;
242243

243244
afs_inc_servers_outstanding(net);
244245
trace_afs_server(server, 1, 1, afs_server_trace_alloc);

0 commit comments

Comments
 (0)