Introduce a mutex into struct sockbuf, sb_mtx, which will be used to
protect fields in the socket buffer. Add accessor macros to use the mutex (SOCKBUF_*()). Initialize the mutex in soalloc(), and destroy it in sodealloc(). Add addition, add SOCK_*() access macros which will protect most remaining fields in the socket; for the time being, use the receive socket buffer mutex to implement socket level locking to reduce memory overhead. Submitted by: sam Sponosored by: FreeBSD Foundation Obtained from: BSD/OS
This commit is contained in:
parent
2653139fd2
commit
f6c0cce6d9
@ -144,6 +144,8 @@ soalloc(int mflags)
|
||||
return so;
|
||||
}
|
||||
#endif
|
||||
SOCKBUF_LOCK_INIT(&so->so_snd, "so_snd");
|
||||
SOCKBUF_LOCK_INIT(&so->so_rcv, "so_rcv");
|
||||
/* XXX race condition for reentrant kernel */
|
||||
so->so_gencnt = ++so_gencnt;
|
||||
/* sx_init(&so->so_sxlock, "socket sxlock"); */
|
||||
@ -245,6 +247,8 @@ sodealloc(struct socket *so)
|
||||
mac_destroy_socket(so);
|
||||
#endif
|
||||
crfree(so->so_cred);
|
||||
SOCKBUF_LOCK_DESTROY(&so->so_snd);
|
||||
SOCKBUF_LOCK_DESTROY(&so->so_rcv);
|
||||
/* sx_destroy(&so->so_sxlock); */
|
||||
uma_zfree(socket_zone, so);
|
||||
--numopensockets;
|
||||
|
@ -35,6 +35,8 @@
|
||||
|
||||
#include <sys/queue.h> /* for TAILQ macros */
|
||||
#include <sys/selinfo.h> /* for struct selinfo */
|
||||
#include <sys/_lock.h>
|
||||
#include <sys/_mutex.h>
|
||||
|
||||
/*
|
||||
* Kernel structure per socket.
|
||||
@ -93,6 +95,7 @@ struct socket {
|
||||
*/
|
||||
struct sockbuf {
|
||||
struct selinfo sb_sel; /* process selecting read/write */
|
||||
struct mtx sb_mtx; /* sockbuf lock */
|
||||
#define sb_startzero sb_mb
|
||||
struct mbuf *sb_mb; /* the mbuf chain */
|
||||
struct mbuf *sb_mbtail; /* the last mbuf in the chain */
|
||||
@ -150,6 +153,30 @@ extern struct mtx accept_mtx;
|
||||
#define ACCEPT_LOCK() mtx_lock(&accept_mtx)
|
||||
#define ACCEPT_UNLOCK() mtx_unlock(&accept_mtx)
|
||||
|
||||
/*
|
||||
* Per-socket buffer mutex used to protect most fields in the socket
|
||||
* buffer.
|
||||
*/
|
||||
#define SOCKBUF_MTX(_sb) (&(_sb)->sb_mtx)
|
||||
#define SOCKBUF_LOCK_INIT(_sb, _name) \
|
||||
mtx_init(SOCKBUF_MTX(_sb), _name, NULL, MTX_DEF)
|
||||
#define SOCKBUF_LOCK_DESTROY(_sb) mtx_destroy(SOCKBUF_MTX(_sb))
|
||||
#define SOCKBUF_LOCK(_sb) mtx_lock(SOCKBUF_MTX(_sb))
|
||||
#define SOCKBUF_OWNED(_sb) mtx_owned(SOCKBUF_MTX(_sb))
|
||||
#define SOCKBUF_UNLOCK(_sb) mtx_unlock(SOCKBUF_MTX(_sb))
|
||||
#define SOCKBUF_LOCK_ASSERT(_sb) mtx_assert(SOCKBUF_MTX(_sb), MA_OWNED)
|
||||
|
||||
/*
|
||||
* Per-socket mutex: we reuse the receive socket buffer mutex for space
|
||||
* efficiency. This decision should probably be revisited as we optimize
|
||||
* locking for the socket code.
|
||||
*/
|
||||
#define SOCK_MTX(_so) SOCKBUF_MTX(&(_so)->so_rcv)
|
||||
#define SOCK_LOCK(_so) SOCKBUF_LOCK(&(_so)->so_rcv)
|
||||
#define SOCK_OWNED(_so) SOCKBUF_OWNED(&(_so)->so_rcv)
|
||||
#define SOCK_UNLOCK(_so) SOCKBUF_UNLOCK(&(_so)->so_rcv)
|
||||
#define SOCK_LOCK_ASSERT(_so) SOCKBUF_LOCK_ASSERT(&(_so)->so_rcv)
|
||||
|
||||
/*
|
||||
* Socket state bits.
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user