0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/atomic.h>
0011 #include <linux/types.h>
0012 #include <linux/kref.h>
0013 #include <linux/list.h>
0014 #include <linux/rcupdate.h>
0015 #include <linux/rculist.h>
0016 #include <linux/slab.h>
0017 #include <linux/spinlock.h>
0018 #include <linux/sunrpc/xprt.h>
0019 #include <linux/sunrpc/addr.h>
0020 #include <linux/sunrpc/xprtmultipath.h>
0021
0022 #include "sysfs.h"
0023
0024 typedef struct rpc_xprt *(*xprt_switch_find_xprt_t)(struct rpc_xprt_switch *xps,
0025 const struct rpc_xprt *cur);
0026
0027 static const struct rpc_xprt_iter_ops rpc_xprt_iter_singular;
0028 static const struct rpc_xprt_iter_ops rpc_xprt_iter_roundrobin;
0029 static const struct rpc_xprt_iter_ops rpc_xprt_iter_listall;
0030 static const struct rpc_xprt_iter_ops rpc_xprt_iter_listoffline;
0031
0032 static void xprt_switch_add_xprt_locked(struct rpc_xprt_switch *xps,
0033 struct rpc_xprt *xprt)
0034 {
0035 if (unlikely(xprt_get(xprt) == NULL))
0036 return;
0037 list_add_tail_rcu(&xprt->xprt_switch, &xps->xps_xprt_list);
0038 smp_wmb();
0039 if (xps->xps_nxprts == 0)
0040 xps->xps_net = xprt->xprt_net;
0041 xps->xps_nxprts++;
0042 xps->xps_nactive++;
0043 }
0044
0045
0046
0047
0048
0049
0050
0051
0052 void rpc_xprt_switch_add_xprt(struct rpc_xprt_switch *xps,
0053 struct rpc_xprt *xprt)
0054 {
0055 if (xprt == NULL)
0056 return;
0057 spin_lock(&xps->xps_lock);
0058 if (xps->xps_net == xprt->xprt_net || xps->xps_net == NULL)
0059 xprt_switch_add_xprt_locked(xps, xprt);
0060 spin_unlock(&xps->xps_lock);
0061 rpc_sysfs_xprt_setup(xps, xprt, GFP_KERNEL);
0062 }
0063
0064 static void xprt_switch_remove_xprt_locked(struct rpc_xprt_switch *xps,
0065 struct rpc_xprt *xprt, bool offline)
0066 {
0067 if (unlikely(xprt == NULL))
0068 return;
0069 if (!test_bit(XPRT_OFFLINE, &xprt->state) && offline)
0070 xps->xps_nactive--;
0071 xps->xps_nxprts--;
0072 if (xps->xps_nxprts == 0)
0073 xps->xps_net = NULL;
0074 smp_wmb();
0075 list_del_rcu(&xprt->xprt_switch);
0076 }
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086 void rpc_xprt_switch_remove_xprt(struct rpc_xprt_switch *xps,
0087 struct rpc_xprt *xprt, bool offline)
0088 {
0089 spin_lock(&xps->xps_lock);
0090 xprt_switch_remove_xprt_locked(xps, xprt, offline);
0091 spin_unlock(&xps->xps_lock);
0092 xprt_put(xprt);
0093 }
0094
0095 static DEFINE_IDA(rpc_xprtswitch_ids);
0096
0097 void xprt_multipath_cleanup_ids(void)
0098 {
0099 ida_destroy(&rpc_xprtswitch_ids);
0100 }
0101
0102 static int xprt_switch_alloc_id(struct rpc_xprt_switch *xps, gfp_t gfp_flags)
0103 {
0104 int id;
0105
0106 id = ida_simple_get(&rpc_xprtswitch_ids, 0, 0, gfp_flags);
0107 if (id < 0)
0108 return id;
0109
0110 xps->xps_id = id;
0111 return 0;
0112 }
0113
0114 static void xprt_switch_free_id(struct rpc_xprt_switch *xps)
0115 {
0116 ida_simple_remove(&rpc_xprtswitch_ids, xps->xps_id);
0117 }
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127 struct rpc_xprt_switch *xprt_switch_alloc(struct rpc_xprt *xprt,
0128 gfp_t gfp_flags)
0129 {
0130 struct rpc_xprt_switch *xps;
0131
0132 xps = kmalloc(sizeof(*xps), gfp_flags);
0133 if (xps != NULL) {
0134 spin_lock_init(&xps->xps_lock);
0135 kref_init(&xps->xps_kref);
0136 xprt_switch_alloc_id(xps, gfp_flags);
0137 xps->xps_nxprts = xps->xps_nactive = 0;
0138 atomic_long_set(&xps->xps_queuelen, 0);
0139 xps->xps_net = NULL;
0140 INIT_LIST_HEAD(&xps->xps_xprt_list);
0141 xps->xps_iter_ops = &rpc_xprt_iter_singular;
0142 rpc_sysfs_xprt_switch_setup(xps, xprt, gfp_flags);
0143 xprt_switch_add_xprt_locked(xps, xprt);
0144 xps->xps_nunique_destaddr_xprts = 1;
0145 rpc_sysfs_xprt_setup(xps, xprt, gfp_flags);
0146 }
0147
0148 return xps;
0149 }
0150
0151 static void xprt_switch_free_entries(struct rpc_xprt_switch *xps)
0152 {
0153 spin_lock(&xps->xps_lock);
0154 while (!list_empty(&xps->xps_xprt_list)) {
0155 struct rpc_xprt *xprt;
0156
0157 xprt = list_first_entry(&xps->xps_xprt_list,
0158 struct rpc_xprt, xprt_switch);
0159 xprt_switch_remove_xprt_locked(xps, xprt, true);
0160 spin_unlock(&xps->xps_lock);
0161 xprt_put(xprt);
0162 spin_lock(&xps->xps_lock);
0163 }
0164 spin_unlock(&xps->xps_lock);
0165 }
0166
0167 static void xprt_switch_free(struct kref *kref)
0168 {
0169 struct rpc_xprt_switch *xps = container_of(kref,
0170 struct rpc_xprt_switch, xps_kref);
0171
0172 xprt_switch_free_entries(xps);
0173 rpc_sysfs_xprt_switch_destroy(xps);
0174 xprt_switch_free_id(xps);
0175 kfree_rcu(xps, xps_rcu);
0176 }
0177
0178
0179
0180
0181
0182
0183
0184 struct rpc_xprt_switch *xprt_switch_get(struct rpc_xprt_switch *xps)
0185 {
0186 if (xps != NULL && kref_get_unless_zero(&xps->xps_kref))
0187 return xps;
0188 return NULL;
0189 }
0190
0191
0192
0193
0194
0195
0196
0197 void xprt_switch_put(struct rpc_xprt_switch *xps)
0198 {
0199 if (xps != NULL)
0200 kref_put(&xps->xps_kref, xprt_switch_free);
0201 }
0202
0203
0204
0205
0206
0207
0208
0209 void rpc_xprt_switch_set_roundrobin(struct rpc_xprt_switch *xps)
0210 {
0211 if (READ_ONCE(xps->xps_iter_ops) != &rpc_xprt_iter_roundrobin)
0212 WRITE_ONCE(xps->xps_iter_ops, &rpc_xprt_iter_roundrobin);
0213 }
0214
0215 static
0216 const struct rpc_xprt_iter_ops *xprt_iter_ops(const struct rpc_xprt_iter *xpi)
0217 {
0218 if (xpi->xpi_ops != NULL)
0219 return xpi->xpi_ops;
0220 return rcu_dereference(xpi->xpi_xpswitch)->xps_iter_ops;
0221 }
0222
0223 static
0224 void xprt_iter_no_rewind(struct rpc_xprt_iter *xpi)
0225 {
0226 }
0227
0228 static
0229 void xprt_iter_default_rewind(struct rpc_xprt_iter *xpi)
0230 {
0231 WRITE_ONCE(xpi->xpi_cursor, NULL);
0232 }
0233
0234 static
0235 bool xprt_is_active(const struct rpc_xprt *xprt)
0236 {
0237 return (kref_read(&xprt->kref) != 0 &&
0238 !test_bit(XPRT_OFFLINE, &xprt->state));
0239 }
0240
0241 static
0242 struct rpc_xprt *xprt_switch_find_first_entry(struct list_head *head)
0243 {
0244 struct rpc_xprt *pos;
0245
0246 list_for_each_entry_rcu(pos, head, xprt_switch) {
0247 if (xprt_is_active(pos))
0248 return pos;
0249 }
0250 return NULL;
0251 }
0252
0253 static
0254 struct rpc_xprt *xprt_switch_find_first_entry_offline(struct list_head *head)
0255 {
0256 struct rpc_xprt *pos;
0257
0258 list_for_each_entry_rcu(pos, head, xprt_switch) {
0259 if (!xprt_is_active(pos))
0260 return pos;
0261 }
0262 return NULL;
0263 }
0264
0265 static
0266 struct rpc_xprt *xprt_iter_first_entry(struct rpc_xprt_iter *xpi)
0267 {
0268 struct rpc_xprt_switch *xps = rcu_dereference(xpi->xpi_xpswitch);
0269
0270 if (xps == NULL)
0271 return NULL;
0272 return xprt_switch_find_first_entry(&xps->xps_xprt_list);
0273 }
0274
0275 static
0276 struct rpc_xprt *_xprt_switch_find_current_entry(struct list_head *head,
0277 const struct rpc_xprt *cur,
0278 bool find_active)
0279 {
0280 struct rpc_xprt *pos;
0281 bool found = false;
0282
0283 list_for_each_entry_rcu(pos, head, xprt_switch) {
0284 if (cur == pos)
0285 found = true;
0286 if (found && ((find_active && xprt_is_active(pos)) ||
0287 (!find_active && xprt_is_active(pos))))
0288 return pos;
0289 }
0290 return NULL;
0291 }
0292
0293 static
0294 struct rpc_xprt *xprt_switch_find_current_entry(struct list_head *head,
0295 const struct rpc_xprt *cur)
0296 {
0297 return _xprt_switch_find_current_entry(head, cur, true);
0298 }
0299
0300 static
0301 struct rpc_xprt * _xprt_iter_current_entry(struct rpc_xprt_iter *xpi,
0302 struct rpc_xprt *first_entry(struct list_head *head),
0303 struct rpc_xprt *current_entry(struct list_head *head,
0304 const struct rpc_xprt *cur))
0305 {
0306 struct rpc_xprt_switch *xps = rcu_dereference(xpi->xpi_xpswitch);
0307 struct list_head *head;
0308
0309 if (xps == NULL)
0310 return NULL;
0311 head = &xps->xps_xprt_list;
0312 if (xpi->xpi_cursor == NULL || xps->xps_nxprts < 2)
0313 return first_entry(head);
0314 return current_entry(head, xpi->xpi_cursor);
0315 }
0316
0317 static
0318 struct rpc_xprt *xprt_iter_current_entry(struct rpc_xprt_iter *xpi)
0319 {
0320 return _xprt_iter_current_entry(xpi, xprt_switch_find_first_entry,
0321 xprt_switch_find_current_entry);
0322 }
0323
0324 static
0325 struct rpc_xprt *xprt_switch_find_current_entry_offline(struct list_head *head,
0326 const struct rpc_xprt *cur)
0327 {
0328 return _xprt_switch_find_current_entry(head, cur, false);
0329 }
0330
0331 static
0332 struct rpc_xprt *xprt_iter_current_entry_offline(struct rpc_xprt_iter *xpi)
0333 {
0334 return _xprt_iter_current_entry(xpi,
0335 xprt_switch_find_first_entry_offline,
0336 xprt_switch_find_current_entry_offline);
0337 }
0338
0339 bool rpc_xprt_switch_has_addr(struct rpc_xprt_switch *xps,
0340 const struct sockaddr *sap)
0341 {
0342 struct list_head *head;
0343 struct rpc_xprt *pos;
0344
0345 if (xps == NULL || sap == NULL)
0346 return false;
0347
0348 head = &xps->xps_xprt_list;
0349 list_for_each_entry_rcu(pos, head, xprt_switch) {
0350 if (rpc_cmp_addr_port(sap, (struct sockaddr *)&pos->addr)) {
0351 pr_info("RPC: addr %s already in xprt switch\n",
0352 pos->address_strings[RPC_DISPLAY_ADDR]);
0353 return true;
0354 }
0355 }
0356 return false;
0357 }
0358
0359 static
0360 struct rpc_xprt *xprt_switch_find_next_entry(struct list_head *head,
0361 const struct rpc_xprt *cur, bool check_active)
0362 {
0363 struct rpc_xprt *pos, *prev = NULL;
0364 bool found = false;
0365
0366 list_for_each_entry_rcu(pos, head, xprt_switch) {
0367 if (cur == prev)
0368 found = true;
0369
0370
0371
0372
0373 if (found && ((check_active && xprt_is_active(pos)) ||
0374 (!check_active && !xprt_is_active(pos))))
0375 return pos;
0376 prev = pos;
0377 }
0378 return NULL;
0379 }
0380
0381 static
0382 struct rpc_xprt *xprt_switch_set_next_cursor(struct rpc_xprt_switch *xps,
0383 struct rpc_xprt **cursor,
0384 xprt_switch_find_xprt_t find_next)
0385 {
0386 struct rpc_xprt *pos, *old;
0387
0388 old = smp_load_acquire(cursor);
0389 pos = find_next(xps, old);
0390 smp_store_release(cursor, pos);
0391 return pos;
0392 }
0393
0394 static
0395 struct rpc_xprt *xprt_iter_next_entry_multiple(struct rpc_xprt_iter *xpi,
0396 xprt_switch_find_xprt_t find_next)
0397 {
0398 struct rpc_xprt_switch *xps = rcu_dereference(xpi->xpi_xpswitch);
0399
0400 if (xps == NULL)
0401 return NULL;
0402 return xprt_switch_set_next_cursor(xps, &xpi->xpi_cursor, find_next);
0403 }
0404
0405 static
0406 struct rpc_xprt *__xprt_switch_find_next_entry_roundrobin(struct list_head *head,
0407 const struct rpc_xprt *cur)
0408 {
0409 struct rpc_xprt *ret;
0410
0411 ret = xprt_switch_find_next_entry(head, cur, true);
0412 if (ret != NULL)
0413 return ret;
0414 return xprt_switch_find_first_entry(head);
0415 }
0416
0417 static
0418 struct rpc_xprt *xprt_switch_find_next_entry_roundrobin(struct rpc_xprt_switch *xps,
0419 const struct rpc_xprt *cur)
0420 {
0421 struct list_head *head = &xps->xps_xprt_list;
0422 struct rpc_xprt *xprt;
0423 unsigned int nactive;
0424
0425 for (;;) {
0426 unsigned long xprt_queuelen, xps_queuelen;
0427
0428 xprt = __xprt_switch_find_next_entry_roundrobin(head, cur);
0429 if (!xprt)
0430 break;
0431 xprt_queuelen = atomic_long_read(&xprt->queuelen);
0432 xps_queuelen = atomic_long_read(&xps->xps_queuelen);
0433 nactive = READ_ONCE(xps->xps_nactive);
0434
0435 if (xprt_queuelen * nactive <= xps_queuelen)
0436 break;
0437 cur = xprt;
0438 }
0439 return xprt;
0440 }
0441
0442 static
0443 struct rpc_xprt *xprt_iter_next_entry_roundrobin(struct rpc_xprt_iter *xpi)
0444 {
0445 return xprt_iter_next_entry_multiple(xpi,
0446 xprt_switch_find_next_entry_roundrobin);
0447 }
0448
0449 static
0450 struct rpc_xprt *xprt_switch_find_next_entry_all(struct rpc_xprt_switch *xps,
0451 const struct rpc_xprt *cur)
0452 {
0453 return xprt_switch_find_next_entry(&xps->xps_xprt_list, cur, true);
0454 }
0455
0456 static
0457 struct rpc_xprt *xprt_switch_find_next_entry_offline(struct rpc_xprt_switch *xps,
0458 const struct rpc_xprt *cur)
0459 {
0460 return xprt_switch_find_next_entry(&xps->xps_xprt_list, cur, false);
0461 }
0462
0463 static
0464 struct rpc_xprt *xprt_iter_next_entry_all(struct rpc_xprt_iter *xpi)
0465 {
0466 return xprt_iter_next_entry_multiple(xpi,
0467 xprt_switch_find_next_entry_all);
0468 }
0469
0470 static
0471 struct rpc_xprt *xprt_iter_next_entry_offline(struct rpc_xprt_iter *xpi)
0472 {
0473 return xprt_iter_next_entry_multiple(xpi,
0474 xprt_switch_find_next_entry_offline);
0475 }
0476
0477
0478
0479
0480
0481
0482
0483
0484 void xprt_iter_rewind(struct rpc_xprt_iter *xpi)
0485 {
0486 rcu_read_lock();
0487 xprt_iter_ops(xpi)->xpi_rewind(xpi);
0488 rcu_read_unlock();
0489 }
0490
0491 static void __xprt_iter_init(struct rpc_xprt_iter *xpi,
0492 struct rpc_xprt_switch *xps,
0493 const struct rpc_xprt_iter_ops *ops)
0494 {
0495 rcu_assign_pointer(xpi->xpi_xpswitch, xprt_switch_get(xps));
0496 xpi->xpi_cursor = NULL;
0497 xpi->xpi_ops = ops;
0498 }
0499
0500
0501
0502
0503
0504
0505
0506
0507
0508
0509 void xprt_iter_init(struct rpc_xprt_iter *xpi,
0510 struct rpc_xprt_switch *xps)
0511 {
0512 __xprt_iter_init(xpi, xps, NULL);
0513 }
0514
0515
0516
0517
0518
0519
0520
0521
0522
0523 void xprt_iter_init_listall(struct rpc_xprt_iter *xpi,
0524 struct rpc_xprt_switch *xps)
0525 {
0526 __xprt_iter_init(xpi, xps, &rpc_xprt_iter_listall);
0527 }
0528
0529 void xprt_iter_init_listoffline(struct rpc_xprt_iter *xpi,
0530 struct rpc_xprt_switch *xps)
0531 {
0532 __xprt_iter_init(xpi, xps, &rpc_xprt_iter_listoffline);
0533 }
0534
0535
0536
0537
0538
0539
0540
0541
0542 struct rpc_xprt_switch *xprt_iter_xchg_switch(struct rpc_xprt_iter *xpi,
0543 struct rpc_xprt_switch *newswitch)
0544 {
0545 struct rpc_xprt_switch __rcu *oldswitch;
0546
0547
0548 oldswitch = xchg(&xpi->xpi_xpswitch, RCU_INITIALIZER(newswitch));
0549 if (newswitch != NULL)
0550 xprt_iter_rewind(xpi);
0551 return rcu_dereference_protected(oldswitch, true);
0552 }
0553
0554
0555
0556
0557
0558 void xprt_iter_destroy(struct rpc_xprt_iter *xpi)
0559 {
0560 xprt_switch_put(xprt_iter_xchg_switch(xpi, NULL));
0561 }
0562
0563
0564
0565
0566
0567
0568
0569
0570
0571 struct rpc_xprt *xprt_iter_xprt(struct rpc_xprt_iter *xpi)
0572 {
0573 WARN_ON_ONCE(!rcu_read_lock_held());
0574 return xprt_iter_ops(xpi)->xpi_xprt(xpi);
0575 }
0576
0577 static
0578 struct rpc_xprt *xprt_iter_get_helper(struct rpc_xprt_iter *xpi,
0579 struct rpc_xprt *(*fn)(struct rpc_xprt_iter *))
0580 {
0581 struct rpc_xprt *ret;
0582
0583 do {
0584 ret = fn(xpi);
0585 if (ret == NULL)
0586 break;
0587 ret = xprt_get(ret);
0588 } while (ret == NULL);
0589 return ret;
0590 }
0591
0592
0593
0594
0595
0596
0597
0598
0599 struct rpc_xprt *xprt_iter_get_xprt(struct rpc_xprt_iter *xpi)
0600 {
0601 struct rpc_xprt *xprt;
0602
0603 rcu_read_lock();
0604 xprt = xprt_iter_get_helper(xpi, xprt_iter_ops(xpi)->xpi_xprt);
0605 rcu_read_unlock();
0606 return xprt;
0607 }
0608
0609
0610
0611
0612
0613
0614
0615
0616 struct rpc_xprt *xprt_iter_get_next(struct rpc_xprt_iter *xpi)
0617 {
0618 struct rpc_xprt *xprt;
0619
0620 rcu_read_lock();
0621 xprt = xprt_iter_get_helper(xpi, xprt_iter_ops(xpi)->xpi_next);
0622 rcu_read_unlock();
0623 return xprt;
0624 }
0625
0626
0627 static
0628 const struct rpc_xprt_iter_ops rpc_xprt_iter_singular = {
0629 .xpi_rewind = xprt_iter_no_rewind,
0630 .xpi_xprt = xprt_iter_first_entry,
0631 .xpi_next = xprt_iter_first_entry,
0632 };
0633
0634
0635 static
0636 const struct rpc_xprt_iter_ops rpc_xprt_iter_roundrobin = {
0637 .xpi_rewind = xprt_iter_default_rewind,
0638 .xpi_xprt = xprt_iter_current_entry,
0639 .xpi_next = xprt_iter_next_entry_roundrobin,
0640 };
0641
0642
0643 static
0644 const struct rpc_xprt_iter_ops rpc_xprt_iter_listall = {
0645 .xpi_rewind = xprt_iter_default_rewind,
0646 .xpi_xprt = xprt_iter_current_entry,
0647 .xpi_next = xprt_iter_next_entry_all,
0648 };
0649
0650 static
0651 const struct rpc_xprt_iter_ops rpc_xprt_iter_listoffline = {
0652 .xpi_rewind = xprt_iter_default_rewind,
0653 .xpi_xprt = xprt_iter_current_entry_offline,
0654 .xpi_next = xprt_iter_next_entry_offline,
0655 };