Commit 7a18208383ab3f3ce4a1f4e0536acc9372523d81

Authored by Tom Tucker
Committed by J. Bruce Fields
1 parent bb5cf160b2

svc: Make close transport independent

Move sk_list and sk_ready to svc_xprt. This involves close because these
lists are walked by svcs when closing all their transports. So I combined
the moving of these lists to svc_xprt with making close transport independent.

The svc_force_sock_close has been changed to svc_close_all and takes a list
as an argument. This removes some svc internals knowledge from the svcs.

This code races with module removal and transport addition.

Thanks to Simon Holm Thøgersen for a compile fix.

Signed-off-by: Tom Tucker <tom@opengridcomputing.com>
Acked-by: Neil Brown <neilb@suse.de>
Reviewed-by: Chuck Lever <chuck.lever@oracle.com>
Reviewed-by: Greg Banks <gnb@sgi.com>
Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
Cc: Simon Holm Thøgersen <odie@cs.aau.dk>

Showing 7 changed files with 62 additions and 69 deletions Side-by-side Diff

... ... @@ -221,10 +221,10 @@
221 221  
222 222 static int find_xprt(struct svc_serv *serv, char *proto)
223 223 {
224   - struct svc_sock *svsk;
  224 + struct svc_xprt *xprt;
225 225 int found = 0;
226   - list_for_each_entry(svsk, &serv->sv_permsocks, sk_list)
227   - if (strcmp(svsk->sk_xprt.xpt_class->xcl_name, proto) == 0) {
  226 + list_for_each_entry(xprt, &serv->sv_permsocks, xpt_list)
  227 + if (strcmp(xprt->xpt_class->xcl_name, proto) == 0) {
228 228 found = 1;
229 229 break;
230 230 }
... ... @@ -155,8 +155,8 @@
155 155 static void nfsd_last_thread(struct svc_serv *serv)
156 156 {
157 157 /* When last nfsd thread exits we need to do some clean-up */
158   - struct svc_sock *svsk;
159   - list_for_each_entry(svsk, &serv->sv_permsocks, sk_list)
  158 + struct svc_xprt *xprt;
  159 + list_for_each_entry(xprt, &serv->sv_permsocks, xpt_list)
160 160 lockd_down();
161 161 nfsd_serv = NULL;
162 162 nfsd_racache_shutdown();
include/linux/sunrpc/svc_xprt.h
... ... @@ -36,6 +36,8 @@
36 36 struct svc_xprt_class *xpt_class;
37 37 struct svc_xprt_ops *xpt_ops;
38 38 struct kref xpt_ref;
  39 + struct list_head xpt_list;
  40 + struct list_head xpt_ready;
39 41 unsigned long xpt_flags;
40 42 #define XPT_BUSY 0 /* enqueued/receiving */
41 43 #define XPT_CONN 1 /* conn pending */
include/linux/sunrpc/svcsock.h
... ... @@ -17,8 +17,6 @@
17 17 */
18 18 struct svc_sock {
19 19 struct svc_xprt sk_xprt;
20   - struct list_head sk_ready; /* list of ready sockets */
21   - struct list_head sk_list; /* list of all sockets */
22 20 struct socket * sk_sock; /* berkeley socket layer */
23 21 struct sock * sk_sk; /* INET layer */
24 22  
... ... @@ -51,7 +49,7 @@
51 49 /*
52 50 * Function prototypes.
53 51 */
54   -void svc_force_close_socket(struct svc_sock *);
  52 +void svc_close_all(struct list_head *);
55 53 int svc_recv(struct svc_rqst *, long);
56 54 int svc_send(struct svc_rqst *);
57 55 void svc_drop(struct svc_rqst *);
... ... @@ -459,9 +459,6 @@
459 459 void
460 460 svc_destroy(struct svc_serv *serv)
461 461 {
462   - struct svc_sock *svsk;
463   - struct svc_sock *tmp;
464   -
465 462 dprintk("svc: svc_destroy(%s, %d)\n",
466 463 serv->sv_program->pg_name,
467 464 serv->sv_nrthreads);
468 465  
... ... @@ -476,14 +473,12 @@
476 473  
477 474 del_timer_sync(&serv->sv_temptimer);
478 475  
479   - list_for_each_entry_safe(svsk, tmp, &serv->sv_tempsocks, sk_list)
480   - svc_force_close_socket(svsk);
  476 + svc_close_all(&serv->sv_tempsocks);
481 477  
482 478 if (serv->sv_shutdown)
483 479 serv->sv_shutdown(serv);
484 480  
485   - list_for_each_entry_safe(svsk, tmp, &serv->sv_permsocks, sk_list)
486   - svc_force_close_socket(svsk);
  481 + svc_close_all(&serv->sv_permsocks);
487 482  
488 483 BUG_ON(!list_empty(&serv->sv_permsocks));
489 484 BUG_ON(!list_empty(&serv->sv_tempsocks));
net/sunrpc/svc_xprt.c
... ... @@ -97,6 +97,8 @@
97 97 xprt->xpt_ops = xcl->xcl_ops;
98 98 kref_init(&xprt->xpt_ref);
99 99 xprt->xpt_server = serv;
  100 + INIT_LIST_HEAD(&xprt->xpt_list);
  101 + INIT_LIST_HEAD(&xprt->xpt_ready);
100 102 }
101 103 EXPORT_SYMBOL_GPL(svc_xprt_init);
102 104  
net/sunrpc/svcsock.c
... ... @@ -81,11 +81,11 @@
81 81  
82 82 static struct svc_sock *svc_setup_socket(struct svc_serv *, struct socket *,
83 83 int *errp, int flags);
84   -static void svc_delete_socket(struct svc_sock *svsk);
  84 +static void svc_delete_xprt(struct svc_xprt *xprt);
85 85 static void svc_udp_data_ready(struct sock *, int);
86 86 static int svc_udp_recvfrom(struct svc_rqst *);
87 87 static int svc_udp_sendto(struct svc_rqst *);
88   -static void svc_close_socket(struct svc_sock *svsk);
  88 +static void svc_close_xprt(struct svc_xprt *xprt);
89 89 static void svc_sock_detach(struct svc_xprt *);
90 90 static void svc_sock_free(struct svc_xprt *);
91 91  
... ... @@ -293,7 +293,7 @@
293 293 wake_up(&rqstp->rq_wait);
294 294 } else {
295 295 dprintk("svc: socket %p put into queue\n", svsk->sk_sk);
296   - list_add_tail(&svsk->sk_ready, &pool->sp_sockets);
  296 + list_add_tail(&svsk->sk_xprt.xpt_ready, &pool->sp_sockets);
297 297 BUG_ON(svsk->sk_xprt.xpt_pool != pool);
298 298 }
299 299  
... ... @@ -313,8 +313,8 @@
313 313 return NULL;
314 314  
315 315 svsk = list_entry(pool->sp_sockets.next,
316   - struct svc_sock, sk_ready);
317   - list_del_init(&svsk->sk_ready);
  316 + struct svc_sock, sk_xprt.xpt_ready);
  317 + list_del_init(&svsk->sk_xprt.xpt_ready);
318 318  
319 319 dprintk("svc: socket %p dequeued, inuse=%d\n",
320 320 svsk->sk_sk, atomic_read(&svsk->sk_xprt.xpt_ref.refcount));
... ... @@ -572,7 +572,7 @@
572 572 if (!serv)
573 573 return 0;
574 574 spin_lock_bh(&serv->sv_lock);
575   - list_for_each_entry(svsk, &serv->sv_permsocks, sk_list) {
  575 + list_for_each_entry(svsk, &serv->sv_permsocks, sk_xprt.xpt_list) {
576 576 int onelen = one_sock_name(buf+len, svsk);
577 577 if (toclose && strcmp(toclose, buf+len) == 0)
578 578 closesk = svsk;
... ... @@ -584,7 +584,7 @@
584 584 /* Should unregister with portmap, but you cannot
585 585 * unregister just one protocol...
586 586 */
587   - svc_close_socket(closesk);
  587 + svc_close_xprt(&closesk->sk_xprt);
588 588 else if (toclose)
589 589 return -ENOENT;
590 590 return len;
591 591  
... ... @@ -1427,12 +1427,12 @@
1427 1427 spin_lock_bh(&serv->sv_lock);
1428 1428 list_for_each(le, &serv->sv_permsocks) {
1429 1429 struct svc_sock *svsk =
1430   - list_entry(le, struct svc_sock, sk_list);
  1430 + list_entry(le, struct svc_sock, sk_xprt.xpt_list);
1431 1431 set_bit(XPT_CHNGBUF, &svsk->sk_xprt.xpt_flags);
1432 1432 }
1433 1433 list_for_each(le, &serv->sv_tempsocks) {
1434 1434 struct svc_sock *svsk =
1435   - list_entry(le, struct svc_sock, sk_list);
  1435 + list_entry(le, struct svc_sock, sk_xprt.xpt_list);
1436 1436 set_bit(XPT_CHNGBUF, &svsk->sk_xprt.xpt_flags);
1437 1437 }
1438 1438 spin_unlock_bh(&serv->sv_lock);
... ... @@ -1469,7 +1469,7 @@
1469 1469 */
1470 1470 svsk = list_entry(serv->sv_tempsocks.prev,
1471 1471 struct svc_sock,
1472   - sk_list);
  1472 + sk_xprt.xpt_list);
1473 1473 set_bit(XPT_CLOSE, &svsk->sk_xprt.xpt_flags);
1474 1474 svc_xprt_get(&svsk->sk_xprt);
1475 1475 }
... ... @@ -1576,7 +1576,7 @@
1576 1576 len = 0;
1577 1577 if (test_bit(XPT_CLOSE, &svsk->sk_xprt.xpt_flags)) {
1578 1578 dprintk("svc_recv: found XPT_CLOSE\n");
1579   - svc_delete_socket(svsk);
  1579 + svc_delete_xprt(&svsk->sk_xprt);
1580 1580 } else if (test_bit(XPT_LISTENER, &svsk->sk_xprt.xpt_flags)) {
1581 1581 struct svc_xprt *newxpt;
1582 1582 newxpt = svsk->sk_xprt.xpt_ops->xpo_accept(&svsk->sk_xprt);
... ... @@ -1685,7 +1685,7 @@
1685 1685 }
1686 1686  
1687 1687 list_for_each_safe(le, next, &serv->sv_tempsocks) {
1688   - svsk = list_entry(le, struct svc_sock, sk_list);
  1688 + svsk = list_entry(le, struct svc_sock, sk_xprt.xpt_list);
1689 1689  
1690 1690 if (!test_and_set_bit(XPT_OLD, &svsk->sk_xprt.xpt_flags))
1691 1691 continue;
1692 1692  
... ... @@ -1701,9 +1701,9 @@
1701 1701  
1702 1702 while (!list_empty(&to_be_aged)) {
1703 1703 le = to_be_aged.next;
1704   - /* fiddling the sk_list node is safe 'cos we're XPT_DETACHED */
  1704 + /* fiddling the sk_xprt.xpt_list node is safe 'cos we're XPT_DETACHED */
1705 1705 list_del_init(le);
1706   - svsk = list_entry(le, struct svc_sock, sk_list);
  1706 + svsk = list_entry(le, struct svc_sock, sk_xprt.xpt_list);
1707 1707  
1708 1708 dprintk("queuing svsk %p for closing, %lu seconds old\n",
1709 1709 svsk, get_seconds() - svsk->sk_lastrecv);
... ... @@ -1757,7 +1757,6 @@
1757 1757 svsk->sk_lastrecv = get_seconds();
1758 1758 spin_lock_init(&svsk->sk_lock);
1759 1759 INIT_LIST_HEAD(&svsk->sk_deferred);
1760   - INIT_LIST_HEAD(&svsk->sk_ready);
1761 1760 mutex_init(&svsk->sk_mutex);
1762 1761  
1763 1762 /* Initialize the socket */
... ... @@ -1769,7 +1768,7 @@
1769 1768 spin_lock_bh(&serv->sv_lock);
1770 1769 if (is_temporary) {
1771 1770 set_bit(XPT_TEMP, &svsk->sk_xprt.xpt_flags);
1772   - list_add(&svsk->sk_list, &serv->sv_tempsocks);
  1771 + list_add(&svsk->sk_xprt.xpt_list, &serv->sv_tempsocks);
1773 1772 serv->sv_tmpcnt++;
1774 1773 if (serv->sv_temptimer.function == NULL) {
1775 1774 /* setup timer to age temp sockets */
... ... @@ -1780,7 +1779,7 @@
1780 1779 }
1781 1780 } else {
1782 1781 clear_bit(XPT_TEMP, &svsk->sk_xprt.xpt_flags);
1783   - list_add(&svsk->sk_list, &serv->sv_permsocks);
  1782 + list_add(&svsk->sk_xprt.xpt_list, &serv->sv_permsocks);
1784 1783 }
1785 1784 spin_unlock_bh(&serv->sv_lock);
1786 1785  
1787 1786  
1788 1787  
1789 1788  
1790 1789  
1791 1790  
1792 1791  
1793 1792  
1794 1793  
1795 1794  
1796 1795  
1797 1796  
1798 1797  
1799 1798  
1800 1799  
1801 1800  
... ... @@ -1912,66 +1911,63 @@
1912 1911 }
1913 1912  
1914 1913 /*
1915   - * Remove a dead socket
  1914 + * Remove a dead transport
1916 1915 */
1917   -static void
1918   -svc_delete_socket(struct svc_sock *svsk)
  1916 +static void svc_delete_xprt(struct svc_xprt *xprt)
1919 1917 {
1920   - struct svc_serv *serv;
1921   - struct sock *sk;
  1918 + struct svc_serv *serv = xprt->xpt_server;
1922 1919  
1923   - dprintk("svc: svc_delete_socket(%p)\n", svsk);
  1920 + dprintk("svc: svc_delete_xprt(%p)\n", xprt);
  1921 + xprt->xpt_ops->xpo_detach(xprt);
1924 1922  
1925   - serv = svsk->sk_xprt.xpt_server;
1926   - sk = svsk->sk_sk;
1927   -
1928   - svsk->sk_xprt.xpt_ops->xpo_detach(&svsk->sk_xprt);
1929   -
1930 1923 spin_lock_bh(&serv->sv_lock);
1931   -
1932   - if (!test_and_set_bit(XPT_DETACHED, &svsk->sk_xprt.xpt_flags))
1933   - list_del_init(&svsk->sk_list);
  1924 + if (!test_and_set_bit(XPT_DETACHED, &xprt->xpt_flags))
  1925 + list_del_init(&xprt->xpt_list);
1934 1926 /*
1935   - * We used to delete the svc_sock from whichever list
1936   - * it's sk_ready node was on, but we don't actually
  1927 + * We used to delete the transport from whichever list
  1928 + * it's sk_xprt.xpt_ready node was on, but we don't actually
1937 1929 * need to. This is because the only time we're called
1938 1930 * while still attached to a queue, the queue itself
1939 1931 * is about to be destroyed (in svc_destroy).
1940 1932 */
1941   - if (!test_and_set_bit(XPT_DEAD, &svsk->sk_xprt.xpt_flags)) {
1942   - BUG_ON(atomic_read(&svsk->sk_xprt.xpt_ref.refcount) < 2);
1943   - if (test_bit(XPT_TEMP, &svsk->sk_xprt.xpt_flags))
  1933 + if (!test_and_set_bit(XPT_DEAD, &xprt->xpt_flags)) {
  1934 + BUG_ON(atomic_read(&xprt->xpt_ref.refcount) < 2);
  1935 + if (test_bit(XPT_TEMP, &xprt->xpt_flags))
1944 1936 serv->sv_tmpcnt--;
1945   - svc_xprt_put(&svsk->sk_xprt);
  1937 + svc_xprt_put(xprt);
1946 1938 }
1947   -
1948 1939 spin_unlock_bh(&serv->sv_lock);
1949 1940 }
1950 1941  
1951   -static void svc_close_socket(struct svc_sock *svsk)
  1942 +static void svc_close_xprt(struct svc_xprt *xprt)
1952 1943 {
1953   - set_bit(XPT_CLOSE, &svsk->sk_xprt.xpt_flags);
1954   - if (test_and_set_bit(XPT_BUSY, &svsk->sk_xprt.xpt_flags))
  1944 + set_bit(XPT_CLOSE, &xprt->xpt_flags);
  1945 + if (test_and_set_bit(XPT_BUSY, &xprt->xpt_flags))
1955 1946 /* someone else will have to effect the close */
1956 1947 return;
1957 1948  
1958   - svc_xprt_get(&svsk->sk_xprt);
1959   - svc_delete_socket(svsk);
1960   - clear_bit(XPT_BUSY, &svsk->sk_xprt.xpt_flags);
1961   - svc_xprt_put(&svsk->sk_xprt);
  1949 + svc_xprt_get(xprt);
  1950 + svc_delete_xprt(xprt);
  1951 + clear_bit(XPT_BUSY, &xprt->xpt_flags);
  1952 + svc_xprt_put(xprt);
1962 1953 }
1963 1954  
1964   -void svc_force_close_socket(struct svc_sock *svsk)
  1955 +void svc_close_all(struct list_head *xprt_list)
1965 1956 {
1966   - set_bit(XPT_CLOSE, &svsk->sk_xprt.xpt_flags);
1967   - if (test_bit(XPT_BUSY, &svsk->sk_xprt.xpt_flags)) {
1968   - /* Waiting to be processed, but no threads left,
1969   - * So just remove it from the waiting list
1970   - */
1971   - list_del_init(&svsk->sk_ready);
1972   - clear_bit(XPT_BUSY, &svsk->sk_xprt.xpt_flags);
  1957 + struct svc_xprt *xprt;
  1958 + struct svc_xprt *tmp;
  1959 +
  1960 + list_for_each_entry_safe(xprt, tmp, xprt_list, xpt_list) {
  1961 + set_bit(XPT_CLOSE, &xprt->xpt_flags);
  1962 + if (test_bit(XPT_BUSY, &xprt->xpt_flags)) {
  1963 + /* Waiting to be processed, but no threads left,
  1964 + * So just remove it from the waiting list
  1965 + */
  1966 + list_del_init(&xprt->xpt_ready);
  1967 + clear_bit(XPT_BUSY, &xprt->xpt_flags);
  1968 + }
  1969 + svc_close_xprt(xprt);
1973 1970 }
1974   - svc_close_socket(svsk);
1975 1971 }
1976 1972  
1977 1973 /*