Date: Sat, 4 Jan 2014 15:51:31 +0000 (UTC) From: Alexander Motin <mav@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r260258 - head/sys/rpc Message-ID: <201401041551.s04FpVUn080145@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: mav Date: Sat Jan 4 15:51:31 2014 New Revision: 260258 URL: http://svnweb.freebsd.org/changeset/base/260258 Log: Replace locks added in r260229 to protect sequence counters with atomics. New algorithm does not create additional lock congestion, while some races it includes should not be a problem. Those races may keep requests in DRC cache for some more time by returning ACK position smaller then actual, but it still should be able to drop thems when proper ACK finally read. Races of the original algorithm based on TCP seq number were worse because they happened when reply sequence number were recorded. After that even correctly read ACKs could not clean DRC sometimes. Modified: head/sys/rpc/svc.h head/sys/rpc/svc_vc.c Modified: head/sys/rpc/svc.h ============================================================================== --- head/sys/rpc/svc.h Sat Jan 4 11:39:59 2014 (r260257) +++ head/sys/rpc/svc.h Sat Jan 4 15:51:31 2014 (r260258) @@ -168,8 +168,8 @@ typedef struct __rpc_svcxprt { time_t xp_lastactive; /* time of last RPC */ u_int64_t xp_sockref; /* set by nfsv4 to identify socket */ int xp_upcallset; /* socket upcall is set up */ - uint32_t xp_snd_cnt; /* # of bytes sent to socket */ - struct sx xp_snd_lock; /* protects xp_snd_cnt & sb_cc */ + uint32_t xp_snd_cnt; /* # of bytes to send to socket */ + uint32_t xp_snt_cnt; /* # of bytes sent to socket */ #else int xp_fd; u_short xp_port; /* associated port number */ @@ -327,7 +327,7 @@ enum svcpool_state { typedef SVCTHREAD *pool_assign_fn(SVCTHREAD *, struct svc_req *); typedef void pool_done_fn(SVCTHREAD *, struct svc_req *); typedef struct __rpc_svcpool { - struct mtx sp_lock; /* protect the transport lists */ + struct mtx_padalign sp_lock; /* protect the transport lists */ const char *sp_name; /* pool name (e.g. "nfsd", "NLM" */ enum svcpool_state sp_state; /* current pool state */ struct proc *sp_proc; /* process which is in svc_run */ Modified: head/sys/rpc/svc_vc.c ============================================================================== --- head/sys/rpc/svc_vc.c Sat Jan 4 11:39:59 2014 (r260257) +++ head/sys/rpc/svc_vc.c Sat Jan 4 15:51:31 2014 (r260258) @@ -161,7 +161,6 @@ svc_vc_create(SVCPOOL *pool, struct sock xprt = svc_xprt_alloc(); sx_init(&xprt->xp_lock, "xprt->xp_lock"); - sx_init(&xprt->xp_snd_lock, "xprt->xp_snd_lock"); xprt->xp_pool = pool; xprt->xp_socket = so; xprt->xp_p1 = NULL; @@ -188,7 +187,6 @@ svc_vc_create(SVCPOOL *pool, struct sock return (xprt); cleanup_svc_vc_create: if (xprt) { - sx_destroy(&xprt->xp_snd_lock); sx_destroy(&xprt->xp_lock); svc_xprt_free(xprt); } @@ -237,7 +235,6 @@ svc_vc_create_conn(SVCPOOL *pool, struct xprt = svc_xprt_alloc(); sx_init(&xprt->xp_lock, "xprt->xp_lock"); - sx_init(&xprt->xp_snd_lock, "xprt->xp_snd_lock"); xprt->xp_pool = pool; xprt->xp_socket = so; xprt->xp_p1 = cd; @@ -277,7 +274,6 @@ svc_vc_create_conn(SVCPOOL *pool, struct return (xprt); cleanup_svc_vc_create: if (xprt) { - sx_destroy(&xprt->xp_snd_lock); sx_destroy(&xprt->xp_lock); svc_xprt_free(xprt); } @@ -300,7 +296,6 @@ svc_vc_create_backchannel(SVCPOOL *pool) xprt = svc_xprt_alloc(); sx_init(&xprt->xp_lock, "xprt->xp_lock"); - sx_init(&xprt->xp_snd_lock, "xprt->xp_snd_lock"); xprt->xp_pool = pool; xprt->xp_socket = NULL; xprt->xp_p1 = cd; @@ -550,9 +545,8 @@ static bool_t svc_vc_ack(SVCXPRT *xprt, uint32_t *ack) { - sx_slock(&xprt->xp_snd_lock); - *ack = xprt->xp_snd_cnt - xprt->xp_socket->so_snd.sb_cc; - sx_sunlock(&xprt->xp_snd_lock); + *ack = atomic_load_acq_32(&xprt->xp_snt_cnt); + *ack -= xprt->xp_socket->so_snd.sb_cc; return (TRUE); } @@ -839,16 +833,16 @@ svc_vc_reply(SVCXPRT *xprt, struct rpc_m len = mrep->m_pkthdr.len; *mtod(mrep, uint32_t *) = htonl(0x80000000 | (len - sizeof(uint32_t))); - sx_xlock(&xprt->xp_snd_lock); + atomic_add_acq_32(&xprt->xp_snd_cnt, len); error = sosend(xprt->xp_socket, NULL, NULL, mrep, NULL, 0, curthread); if (!error) { - xprt->xp_snd_cnt += len; + atomic_add_rel_32(&xprt->xp_snt_cnt, len); if (seq) *seq = xprt->xp_snd_cnt; stat = TRUE; - } - sx_xunlock(&xprt->xp_snd_lock); + } else + atomic_subtract_32(&xprt->xp_snd_cnt, len); } else { m_freem(mrep); }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201401041551.s04FpVUn080145>