Commit 92f091cd authored by David Howells's avatar David Howells
Browse files

afs: Dispatch fileserver probes in priority order



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: default avatarDavid Howells <dhowells@redhat.com>
cc: Marc Dionne <marc.dionne@auristor.com>
cc: linux-afs@lists.infradead.org
parent d14cf8ed
Loading
Loading
Loading
Loading
+23 −2
Original line number Diff line number Diff line
@@ -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 @@ void afs_fileserver_probe_result(struct afs_call *call)
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);
	}
+33 −0
Original line number Diff line number Diff line
@@ -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 */