mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-12-29 09:16:33 +00:00
afs: Dispatch vlserver probes in priority order
When probing all the addresses for a volume location server, 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
This commit is contained in:
parent
92f091cddd
commit
e6a7d7f71b
@ -447,6 +447,7 @@ struct afs_vlserver {
|
|||||||
rwlock_t lock; /* Lock on addresses */
|
rwlock_t lock; /* Lock on addresses */
|
||||||
refcount_t ref;
|
refcount_t ref;
|
||||||
unsigned int rtt; /* Server's current RTT in uS */
|
unsigned int rtt; /* Server's current RTT in uS */
|
||||||
|
unsigned int debug_id;
|
||||||
|
|
||||||
/* Probe state */
|
/* Probe state */
|
||||||
wait_queue_head_t probe_wq;
|
wait_queue_head_t probe_wq;
|
||||||
|
@ -13,6 +13,7 @@ struct afs_vlserver *afs_alloc_vlserver(const char *name, size_t name_len,
|
|||||||
unsigned short port)
|
unsigned short port)
|
||||||
{
|
{
|
||||||
struct afs_vlserver *vlserver;
|
struct afs_vlserver *vlserver;
|
||||||
|
static atomic_t debug_ids;
|
||||||
|
|
||||||
vlserver = kzalloc(struct_size(vlserver, name, name_len + 1),
|
vlserver = kzalloc(struct_size(vlserver, name, name_len + 1),
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
@ -21,6 +22,7 @@ struct afs_vlserver *afs_alloc_vlserver(const char *name, size_t name_len,
|
|||||||
rwlock_init(&vlserver->lock);
|
rwlock_init(&vlserver->lock);
|
||||||
init_waitqueue_head(&vlserver->probe_wq);
|
init_waitqueue_head(&vlserver->probe_wq);
|
||||||
spin_lock_init(&vlserver->probe_lock);
|
spin_lock_init(&vlserver->probe_lock);
|
||||||
|
vlserver->debug_id = atomic_inc_return(&debug_ids);
|
||||||
vlserver->rtt = UINT_MAX;
|
vlserver->rtt = UINT_MAX;
|
||||||
vlserver->name_len = name_len;
|
vlserver->name_len = name_len;
|
||||||
vlserver->service_id = VL_SERVICE;
|
vlserver->service_id = VL_SERVICE;
|
||||||
|
@ -131,6 +131,7 @@ void afs_vlserver_probe_result(struct afs_call *call)
|
|||||||
out:
|
out:
|
||||||
spin_unlock(&server->probe_lock);
|
spin_unlock(&server->probe_lock);
|
||||||
|
|
||||||
|
trace_afs_vl_probe(server, false, alist, index, call->error, call->abort_code, rtt_us);
|
||||||
_debug("probe [%u][%u] %pISpc rtt=%d ret=%d",
|
_debug("probe [%u][%u] %pISpc rtt=%d ret=%d",
|
||||||
server_index, index, rxrpc_kernel_remote_addr(addr->peer),
|
server_index, index, rxrpc_kernel_remote_addr(addr->peer),
|
||||||
rtt_us, ret);
|
rtt_us, ret);
|
||||||
@ -150,8 +151,10 @@ static bool afs_do_probe_vlserver(struct afs_net *net,
|
|||||||
{
|
{
|
||||||
struct afs_addr_list *alist;
|
struct afs_addr_list *alist;
|
||||||
struct afs_call *call;
|
struct afs_call *call;
|
||||||
unsigned int index;
|
unsigned long unprobed;
|
||||||
|
unsigned int index, i;
|
||||||
bool in_progress = false;
|
bool in_progress = false;
|
||||||
|
int best_prio;
|
||||||
|
|
||||||
_enter("%s", server->name);
|
_enter("%s", server->name);
|
||||||
|
|
||||||
@ -165,7 +168,20 @@ static bool afs_do_probe_vlserver(struct afs_net *net,
|
|||||||
memset(&server->probe, 0, sizeof(server->probe));
|
memset(&server->probe, 0, sizeof(server->probe));
|
||||||
server->probe.rtt = UINT_MAX;
|
server->probe.rtt = UINT_MAX;
|
||||||
|
|
||||||
for (index = 0; index < alist->nr_addrs; index++) {
|
unprobed = (1UL << alist->nr_addrs) - 1;
|
||||||
|
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_vl_probe(server, true, alist, index, 0, 0, 0);
|
||||||
call = afs_vl_get_capabilities(net, alist, index, key, server,
|
call = afs_vl_get_capabilities(net, alist, index, key, server,
|
||||||
server_index);
|
server_index);
|
||||||
if (!IS_ERR(call)) {
|
if (!IS_ERR(call)) {
|
||||||
|
@ -1420,6 +1420,40 @@ TRACE_EVENT(afs_fs_probe,
|
|||||||
&__entry->srx.transport)
|
&__entry->srx.transport)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
TRACE_EVENT(afs_vl_probe,
|
||||||
|
TP_PROTO(struct afs_vlserver *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(unsigned short, flags)
|
||||||
|
__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("vl=%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 */
|
#endif /* _TRACE_AFS_H */
|
||||||
|
|
||||||
/* This part must be outside protection */
|
/* This part must be outside protection */
|
||||||
|
Loading…
Reference in New Issue
Block a user