diff options
author | Alexander Motin <mav@FreeBSD.org> | 2014-01-04 15:51:31 +0000 |
---|---|---|
committer | Alexander Motin <mav@FreeBSD.org> | 2014-01-04 15:51:31 +0000 |
commit | c809a67a722a990f0a69b169bf56eff5a36f0ef2 (patch) | |
tree | 48aaf31009a42278ab34ef1b8546560d3099ebd6 /sys/rpc/svc_vc.c | |
parent | 1dd0c9050133c1b62e64f8cad33f1542632c4146 (diff) | |
download | src-c809a67a722a990f0a69b169bf56eff5a36f0ef2.tar.gz src-c809a67a722a990f0a69b169bf56eff5a36f0ef2.zip |
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.
Notes
Notes:
svn path=/head/; revision=260258
Diffstat (limited to 'sys/rpc/svc_vc.c')
-rw-r--r-- | sys/rpc/svc_vc.c | 18 |
1 files changed, 6 insertions, 12 deletions
diff --git a/sys/rpc/svc_vc.c b/sys/rpc/svc_vc.c index c10224ee58c4..5fe6488a36bb 100644 --- a/sys/rpc/svc_vc.c +++ b/sys/rpc/svc_vc.c @@ -161,7 +161,6 @@ svc_vc_create(SVCPOOL *pool, struct socket *so, size_t sendsize, 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 socket *so, size_t sendsize, 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 socket *so, struct sockaddr *raddr) 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 socket *so, struct sockaddr *raddr) 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_msg *msg, 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); } |