]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
afs: Dispatch fileserver probes in priority order
authorDavid Howells <dhowells@redhat.com>
Mon, 30 Oct 2023 11:43:24 +0000 (11:43 +0000)
committerDavid Howells <dhowells@redhat.com>
Mon, 1 Jan 2024 16:37:27 +0000 (16:37 +0000)
When probing all the addresses for a fileserver, dispatch them in order of
descending priority to try and get back highest priority one first.

Also add a tracepoint to show the transmission and completion of the
probes.

Signed-off-by: David Howells <dhowells@redhat.com>
cc: Marc Dionne <marc.dionne@auristor.com>
cc: linux-afs@lists.infradead.org

fs/afs/fs_probe.c
include/trace/events/afs.h

index 8008d3ecabab91cac3ba3d1d24dcea67b5e46658..c5702698b18b70f1ff591e1bb98dc0d6da224369 100644 (file)
@@ -102,7 +102,7 @@ void afs_fileserver_probe_result(struct afs_call *call)
        struct afs_address *addr = &alist->addrs[call->probe_index];
        struct afs_server *server = call->server;
        unsigned int index = call->probe_index;
-       unsigned int rtt_us = 0, cap0;
+       unsigned int rtt_us = -1, cap0;
        int ret = call->error;
 
        _enter("%pU,%u", &server->uuid, index);
@@ -182,6 +182,7 @@ responded:
 out:
        spin_unlock(&server->probe_lock);
 
+       trace_afs_fs_probe(server, false, alist, index, call->error, call->abort_code, rtt_us);
        _debug("probe %pU [%u] %pISpc rtt=%d ret=%d",
               &server->uuid, index, rxrpc_kernel_remote_addr(alist->addrs[index].peer),
               rtt_us, ret);
@@ -207,6 +208,8 @@ void afs_fs_probe_fileserver(struct afs_net *net, struct afs_server *server,
        afs_get_addrlist(alist, afs_alist_trace_get_probe);
        read_unlock(&server->fs_lock);
 
+       afs_get_address_preferences(net, alist);
+
        server->probed_at = jiffies;
        atomic_set(&server->probe_outstanding, all ? alist->nr_addrs : 1);
        memset(&server->probe, 0, sizeof(server->probe));
@@ -217,10 +220,28 @@ void afs_fs_probe_fileserver(struct afs_net *net, struct afs_server *server,
                all = true;
 
        if (all) {
-               for (index = 0; index < alist->nr_addrs; index++)
+               unsigned long unprobed = (1UL << alist->nr_addrs) - 1;
+               unsigned int i;
+               int best_prio;
+
+               while (unprobed) {
+                       best_prio = -1;
+                       index = 0;
+                       for (i = 0; i < alist->nr_addrs; i++) {
+                               if (test_bit(i, &unprobed) &&
+                                   alist->addrs[i].prio > best_prio) {
+                                       index = i;
+                                       best_prio = alist->addrs[i].prio;
+                               }
+                       }
+                       __clear_bit(index, &unprobed);
+
+                       trace_afs_fs_probe(server, true, alist, index, 0, 0, 0);
                        if (!afs_fs_get_capabilities(net, server, alist, index, key))
                                afs_fs_probe_not_done(net, server, alist, index);
+               }
        } else {
+               trace_afs_fs_probe(server, true, alist, index, 0, 0, 0);
                if (!afs_fs_get_capabilities(net, server, alist, index, key))
                        afs_fs_probe_not_done(net, server, alist, index);
        }
index 0f68d67f52c8b28353f01d27669d24df21d08d03..81eb87fbcfa7fde62f974435573d20bfb334530c 100644 (file)
@@ -1387,6 +1387,39 @@ TRACE_EVENT(afs_alist,
                      __entry->ref)
            );
 
+TRACE_EVENT(afs_fs_probe,
+           TP_PROTO(struct afs_server *server, bool tx, struct afs_addr_list *alist,
+                    unsigned int addr_index, int error, s32 abort_code, unsigned int rtt_us),
+
+           TP_ARGS(server, tx, alist, addr_index, error, abort_code, rtt_us),
+
+           TP_STRUCT__entry(
+                   __field(unsigned int,               server)
+                   __field(bool,                       tx)
+                   __field(u16,                        addr_index)
+                   __field(short,                      error)
+                   __field(s32,                        abort_code)
+                   __field(unsigned int,               rtt_us)
+                   __field_struct(struct sockaddr_rxrpc, srx)
+                            ),
+
+           TP_fast_assign(
+                   __entry->server = server->debug_id;
+                   __entry->tx = tx;
+                   __entry->addr_index = addr_index;
+                   __entry->error = error;
+                   __entry->abort_code = abort_code;
+                   __entry->rtt_us = rtt_us;
+                   memcpy(&__entry->srx, rxrpc_kernel_remote_srx(alist->addrs[addr_index].peer),
+                          sizeof(__entry->srx));
+                          ),
+
+           TP_printk("s=%08x %s ax=%u e=%d ac=%d rtt=%d %pISpc",
+                     __entry->server, __entry->tx ? "tx" : "rx", __entry->addr_index,
+                     __entry->error, __entry->abort_code, __entry->rtt_us,
+                     &__entry->srx.transport)
+           );
+
 #endif /* _TRACE_AFS_H */
 
 /* This part must be outside protection */