1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /* AFS vlserver probing
4 * Copyright (C) 2018 Red Hat, Inc. All Rights Reserved.
5 * Written by David Howells (dhowells@redhat.com)
8 #include <linux/sched.h>
9 #include <linux/slab.h>
12 #include "protocol_yfs.h"
16 * Handle the completion of a set of probes.
18 static void afs_finished_vl_probe(struct afs_vlserver
*server
)
20 if (!(server
->probe
.flags
& AFS_VLSERVER_PROBE_RESPONDED
)) {
21 server
->rtt
= UINT_MAX
;
22 clear_bit(AFS_VLSERVER_FL_RESPONDING
, &server
->flags
);
25 clear_bit_unlock(AFS_VLSERVER_FL_PROBING
, &server
->flags
);
26 wake_up_bit(&server
->flags
, AFS_VLSERVER_FL_PROBING
);
30 * Handle the completion of a probe RPC call.
32 static void afs_done_one_vl_probe(struct afs_vlserver
*server
, bool wake_up
)
34 if (atomic_dec_and_test(&server
->probe_outstanding
)) {
35 afs_finished_vl_probe(server
);
40 wake_up_all(&server
->probe_wq
);
44 * Process the result of probing a vlserver. This is called after successful
45 * or failed delivery of an VL.GetCapabilities operation.
47 void afs_vlserver_probe_result(struct afs_call
*call
)
49 struct afs_addr_list
*alist
= call
->vl_probe
;
50 struct afs_vlserver
*server
= call
->vlserver
;
51 struct afs_address
*addr
= &alist
->addrs
[call
->probe_index
];
52 unsigned int server_index
= call
->server_index
;
53 unsigned int rtt_us
= 0;
54 unsigned int index
= call
->probe_index
;
55 bool have_result
= false;
56 int ret
= call
->error
;
58 _enter("%s,%u,%u,%d,%d", server
->name
, server_index
, index
, ret
, call
->abort_code
);
60 spin_lock(&server
->probe_lock
);
64 server
->probe
.error
= 0;
67 if (!(server
->probe
.flags
& AFS_VLSERVER_PROBE_RESPONDED
)) {
68 server
->probe
.abort_code
= call
->abort_code
;
69 server
->probe
.error
= ret
;
77 server
->probe
.flags
|= AFS_VLSERVER_PROBE_LOCAL_FAILURE
;
78 if (server
->probe
.error
== 0)
79 server
->probe
.error
= ret
;
80 trace_afs_io_error(call
->debug_id
, ret
, afs_io_error_vl_probe_fail
);
82 case -ECONNRESET
: /* Responded, but call expired. */
92 clear_bit(index
, &alist
->responded
);
93 set_bit(index
, &alist
->probe_failed
);
94 if (!(server
->probe
.flags
& AFS_VLSERVER_PROBE_RESPONDED
) &&
95 (server
->probe
.error
== 0 ||
96 server
->probe
.error
== -ETIMEDOUT
||
97 server
->probe
.error
== -ETIME
))
98 server
->probe
.error
= ret
;
99 trace_afs_io_error(call
->debug_id
, ret
, afs_io_error_vl_probe_fail
);
104 set_bit(index
, &alist
->responded
);
105 clear_bit(index
, &alist
->probe_failed
);
107 if (call
->service_id
== YFS_VL_SERVICE
) {
108 server
->probe
.flags
|= AFS_VLSERVER_PROBE_IS_YFS
;
109 set_bit(AFS_VLSERVER_FL_IS_YFS
, &server
->flags
);
110 server
->service_id
= call
->service_id
;
112 server
->probe
.flags
|= AFS_VLSERVER_PROBE_NOT_YFS
;
113 if (!(server
->probe
.flags
& AFS_VLSERVER_PROBE_IS_YFS
)) {
114 clear_bit(AFS_VLSERVER_FL_IS_YFS
, &server
->flags
);
115 server
->service_id
= call
->service_id
;
119 rtt_us
= rxrpc_kernel_get_srtt(addr
->peer
);
120 if (rtt_us
< server
->probe
.rtt
) {
121 server
->probe
.rtt
= rtt_us
;
122 server
->rtt
= rtt_us
;
123 alist
->preferred
= index
;
126 smp_wmb(); /* Set rtt before responded. */
127 server
->probe
.flags
|= AFS_VLSERVER_PROBE_RESPONDED
;
128 set_bit(AFS_VLSERVER_FL_PROBED
, &server
->flags
);
129 set_bit(AFS_VLSERVER_FL_RESPONDING
, &server
->flags
);
132 spin_unlock(&server
->probe_lock
);
134 trace_afs_vl_probe(server
, false, alist
, index
, call
->error
, call
->abort_code
, rtt_us
);
135 _debug("probe [%u][%u] %pISpc rtt=%d ret=%d",
136 server_index
, index
, rxrpc_kernel_remote_addr(addr
->peer
),
139 afs_done_one_vl_probe(server
, have_result
);
143 * Probe all of a vlserver's addresses to find out the best route and to
144 * query its capabilities.
146 static bool afs_do_probe_vlserver(struct afs_net
*net
,
147 struct afs_vlserver
*server
,
149 unsigned int server_index
,
150 struct afs_error
*_e
)
152 struct afs_addr_list
*alist
;
153 struct afs_call
*call
;
154 unsigned long unprobed
;
155 unsigned int index
, i
;
156 bool in_progress
= false;
159 _enter("%s", server
->name
);
161 read_lock(&server
->lock
);
162 alist
= rcu_dereference_protected(server
->addresses
,
163 lockdep_is_held(&server
->lock
));
164 afs_get_addrlist(alist
, afs_alist_trace_get_vlprobe
);
165 read_unlock(&server
->lock
);
167 atomic_set(&server
->probe_outstanding
, alist
->nr_addrs
);
168 memset(&server
->probe
, 0, sizeof(server
->probe
));
169 server
->probe
.rtt
= UINT_MAX
;
171 unprobed
= (1UL << alist
->nr_addrs
) - 1;
175 for (i
= 0; i
< alist
->nr_addrs
; i
++) {
176 if (test_bit(i
, &unprobed
) &&
177 alist
->addrs
[i
].prio
> best_prio
) {
179 best_prio
= alist
->addrs
[i
].prio
;
182 __clear_bit(index
, &unprobed
);
184 trace_afs_vl_probe(server
, true, alist
, index
, 0, 0, 0);
185 call
= afs_vl_get_capabilities(net
, alist
, index
, key
, server
,
188 afs_prioritise_error(_e
, call
->error
, call
->abort_code
);
192 afs_prioritise_error(_e
, PTR_ERR(call
), 0);
193 afs_done_one_vl_probe(server
, false);
197 afs_put_addrlist(alist
, afs_alist_trace_put_vlprobe
);
202 * Send off probes to all unprobed servers.
204 int afs_send_vl_probes(struct afs_net
*net
, struct key
*key
,
205 struct afs_vlserver_list
*vllist
)
207 struct afs_vlserver
*server
;
208 struct afs_error e
= {};
209 bool in_progress
= false;
212 for (i
= 0; i
< vllist
->nr_servers
; i
++) {
213 server
= vllist
->servers
[i
].server
;
214 if (test_bit(AFS_VLSERVER_FL_PROBED
, &server
->flags
))
217 if (!test_and_set_bit_lock(AFS_VLSERVER_FL_PROBING
, &server
->flags
) &&
218 afs_do_probe_vlserver(net
, server
, key
, i
, &e
))
222 return in_progress
? 0 : e
.error
;
226 * Wait for the first as-yet untried server to respond.
228 int afs_wait_for_vl_probes(struct afs_vlserver_list
*vllist
,
229 unsigned long untried
)
231 struct wait_queue_entry
*waits
;
232 struct afs_vlserver
*server
;
233 unsigned int rtt
= UINT_MAX
, rtt_s
;
234 bool have_responders
= false;
237 _enter("%u,%lx", vllist
->nr_servers
, untried
);
239 /* Only wait for servers that have a probe outstanding. */
240 for (i
= 0; i
< vllist
->nr_servers
; i
++) {
241 if (test_bit(i
, &untried
)) {
242 server
= vllist
->servers
[i
].server
;
243 if (!test_bit(AFS_VLSERVER_FL_PROBING
, &server
->flags
))
244 __clear_bit(i
, &untried
);
245 if (server
->probe
.flags
& AFS_VLSERVER_PROBE_RESPONDED
)
246 have_responders
= true;
249 if (have_responders
|| !untried
)
252 waits
= kmalloc(array_size(vllist
->nr_servers
, sizeof(*waits
)), GFP_KERNEL
);
256 for (i
= 0; i
< vllist
->nr_servers
; i
++) {
257 if (test_bit(i
, &untried
)) {
258 server
= vllist
->servers
[i
].server
;
259 init_waitqueue_entry(&waits
[i
], current
);
260 add_wait_queue(&server
->probe_wq
, &waits
[i
]);
265 bool still_probing
= false;
267 set_current_state(TASK_INTERRUPTIBLE
);
268 for (i
= 0; i
< vllist
->nr_servers
; i
++) {
269 if (test_bit(i
, &untried
)) {
270 server
= vllist
->servers
[i
].server
;
271 if (server
->probe
.flags
& AFS_VLSERVER_PROBE_RESPONDED
)
273 if (test_bit(AFS_VLSERVER_FL_PROBING
, &server
->flags
))
274 still_probing
= true;
278 if (!still_probing
|| signal_pending(current
))
284 set_current_state(TASK_RUNNING
);
286 for (i
= 0; i
< vllist
->nr_servers
; i
++) {
287 if (test_bit(i
, &untried
)) {
288 server
= vllist
->servers
[i
].server
;
289 rtt_s
= READ_ONCE(server
->rtt
);
290 if (test_bit(AFS_VLSERVER_FL_RESPONDING
, &server
->flags
) &&
296 remove_wait_queue(&server
->probe_wq
, &waits
[i
]);
302 if (pref
== -1 && signal_pending(current
))
306 vllist
->preferred
= pref
;
308 _leave(" = 0 [%u]", pref
);