sockets: use socket buffer mutexes in struct socket directly

Convert more generic socket code to not use sockbuf compat pointer.
Continuation of 4328318445.
This commit is contained in:
Gleb Smirnoff 2022-06-03 12:55:44 -07:00
parent 70d07b2089
commit a8e286bb5d
2 changed files with 40 additions and 36 deletions

View file

@ -322,17 +322,17 @@ soo_stat(struct file *fp, struct stat *ub, struct ucred *active_cred)
* in the receive buffer, the socket is still readable.
*/
sb = &so->so_rcv;
SOCKBUF_LOCK(sb);
SOCK_RECVBUF_LOCK(so);
if ((sb->sb_state & SBS_CANTRCVMORE) == 0 || sbavail(sb))
ub->st_mode |= S_IRUSR | S_IRGRP | S_IROTH;
ub->st_size = sbavail(sb) - sb->sb_ctl;
SOCKBUF_UNLOCK(sb);
SOCK_RECVBUF_UNLOCK(so);
sb = &so->so_snd;
SOCKBUF_LOCK(sb);
SOCK_SENDBUF_LOCK(so);
if ((sb->sb_state & SBS_CANTSENDMORE) == 0)
ub->st_mode |= S_IWUSR | S_IWGRP | S_IWOTH;
SOCKBUF_UNLOCK(sb);
SOCK_SENDBUF_UNLOCK(so);
}
ub->st_uid = so->so_cred->cr_uid;
ub->st_gid = so->so_cred->cr_gid;
@ -593,10 +593,11 @@ soaio_ready(struct socket *so, struct sockbuf *sb)
}
static void
soaio_process_job(struct socket *so, struct sockbuf *sb, struct kaiocb *job)
soaio_process_job(struct socket *so, sb_which which, struct kaiocb *job)
{
struct ucred *td_savedcred;
struct thread *td;
struct sockbuf *sb = sobuf(so, which);
#ifdef MAC
struct file *fp = job->fd_file;
#endif
@ -604,7 +605,7 @@ soaio_process_job(struct socket *so, struct sockbuf *sb, struct kaiocb *job)
long ru_before;
int error, flags;
SOCKBUF_UNLOCK(sb);
SOCK_BUF_UNLOCK(so, which);
aio_switch_vmspace(job);
td = curthread;
retry:
@ -669,28 +670,28 @@ retry:
* queue to try again when the socket is ready.
*/
MPASS(done != job_total_nbytes);
SOCKBUF_LOCK(sb);
SOCK_BUF_LOCK(so, which);
if (done == 0 || !(so->so_state & SS_NBIO)) {
empty_results++;
if (soaio_ready(so, sb)) {
empty_retries++;
SOCKBUF_UNLOCK(sb);
SOCK_BUF_UNLOCK(so, which);
goto retry;
}
if (!aio_set_cancel_function(job, soo_aio_cancel)) {
SOCKBUF_UNLOCK(sb);
SOCK_BUF_UNLOCK(so, which);
if (done != 0)
aio_complete(job, done, 0);
else
aio_cancel(job);
SOCKBUF_LOCK(sb);
SOCK_BUF_LOCK(so, which);
} else {
TAILQ_INSERT_HEAD(&sb->sb_aiojobq, job, list);
}
return;
}
SOCKBUF_UNLOCK(sb);
SOCK_BUF_UNLOCK(so, which);
}
if (done != 0 && (error == ERESTART || error == EINTR ||
error == EWOULDBLOCK))
@ -699,23 +700,24 @@ retry:
aio_complete(job, -1, error);
else
aio_complete(job, done, 0);
SOCKBUF_LOCK(sb);
SOCK_BUF_LOCK(so, which);
}
static void
soaio_process_sb(struct socket *so, struct sockbuf *sb)
soaio_process_sb(struct socket *so, sb_which which)
{
struct kaiocb *job;
struct sockbuf *sb = sobuf(so, which);
CURVNET_SET(so->so_vnet);
SOCKBUF_LOCK(sb);
SOCK_BUF_LOCK(so, which);
while (!TAILQ_EMPTY(&sb->sb_aiojobq) && soaio_ready(so, sb)) {
job = TAILQ_FIRST(&sb->sb_aiojobq);
TAILQ_REMOVE(&sb->sb_aiojobq, job, list);
if (!aio_clear_cancel_function(job))
continue;
soaio_process_job(so, sb, job);
soaio_process_job(so, which, job);
}
/*
@ -726,7 +728,7 @@ soaio_process_sb(struct socket *so, struct sockbuf *sb)
if (!TAILQ_EMPTY(&sb->sb_aiojobq))
sb->sb_flags |= SB_AIO;
sb->sb_flags &= ~SB_AIO_RUNNING;
SOCKBUF_UNLOCK(sb);
SOCK_BUF_UNLOCK(so, which);
sorele(so);
CURVNET_RESTORE();
@ -738,7 +740,7 @@ soaio_rcv(void *context, int pending)
struct socket *so;
so = context;
soaio_process_sb(so, &so->so_rcv);
soaio_process_sb(so, SO_RCV);
}
void
@ -747,7 +749,7 @@ soaio_snd(void *context, int pending)
struct socket *so;
so = context;
soaio_process_sb(so, &so->so_snd);
soaio_process_sb(so, SO_SND);
}
void

View file

@ -3654,6 +3654,7 @@ soo_kqfilter(struct file *fp, struct knote *kn)
{
struct socket *so = kn->kn_fp->f_data;
struct sockbuf *sb;
sb_which which;
struct knlist *knl;
switch (kn->kn_filter) {
@ -3661,16 +3662,19 @@ soo_kqfilter(struct file *fp, struct knote *kn)
kn->kn_fop = &soread_filtops;
knl = &so->so_rdsel.si_note;
sb = &so->so_rcv;
which = SO_RCV;
break;
case EVFILT_WRITE:
kn->kn_fop = &sowrite_filtops;
knl = &so->so_wrsel.si_note;
sb = &so->so_snd;
which = SO_SND;
break;
case EVFILT_EMPTY:
kn->kn_fop = &soempty_filtops;
knl = &so->so_wrsel.si_note;
sb = &so->so_snd;
which = SO_SND;
break;
default:
return (EINVAL);
@ -3680,10 +3684,10 @@ soo_kqfilter(struct file *fp, struct knote *kn)
if (SOLISTENING(so)) {
knlist_add(knl, kn, 1);
} else {
SOCKBUF_LOCK(sb);
SOCK_BUF_LOCK(so, which);
knlist_add(knl, kn, 1);
sb->sb_flags |= SB_KNOTE;
SOCKBUF_UNLOCK(sb);
SOCK_BUF_UNLOCK(so, which);
}
SOCK_UNLOCK(so);
return (0);
@ -3894,7 +3898,7 @@ filt_soread(struct knote *kn, long hint)
return (!TAILQ_EMPTY(&so->sol_comp));
}
SOCKBUF_LOCK_ASSERT(&so->so_rcv);
SOCK_RECVBUF_LOCK_ASSERT(so);
kn->kn_data = sbavail(&so->so_rcv) - so->so_rcv.sb_ctl;
if (so->so_rcv.sb_state & SBS_CANTRCVMORE) {
@ -3937,7 +3941,7 @@ filt_sowrite(struct knote *kn, long hint)
if (SOLISTENING(so))
return (0);
SOCKBUF_LOCK_ASSERT(&so->so_snd);
SOCK_SENDBUF_LOCK_ASSERT(so);
kn->kn_data = sbspace(&so->so_snd);
hhook_run_socket(so, kn, HHOOK_FILT_SOWRITE);
@ -3967,7 +3971,7 @@ filt_soempty(struct knote *kn, long hint)
if (SOLISTENING(so))
return (1);
SOCKBUF_LOCK_ASSERT(&so->so_snd);
SOCK_SENDBUF_LOCK_ASSERT(so);
kn->kn_data = sbused(&so->so_snd);
if (kn->kn_data == 0)
@ -4079,7 +4083,7 @@ again:
SOCK_UNLOCK(so);
solisten_wakeup(head); /* unlocks */
} else {
SOCKBUF_LOCK(&so->so_rcv);
SOCK_RECVBUF_LOCK(so);
soupcall_set(so, SO_RCV,
head->sol_accept_filter->accf_callback,
head->sol_accept_filter_arg);
@ -4088,10 +4092,10 @@ again:
head->sol_accept_filter_arg, M_NOWAIT);
if (ret == SU_ISCONNECTED) {
soupcall_clear(so, SO_RCV);
SOCKBUF_UNLOCK(&so->so_rcv);
SOCK_RECVBUF_UNLOCK(so);
goto again;
}
SOCKBUF_UNLOCK(&so->so_rcv);
SOCK_RECVBUF_UNLOCK(so);
SOCK_UNLOCK(so);
SOLISTEN_UNLOCK(head);
}
@ -4112,9 +4116,9 @@ soisdisconnecting(struct socket *so)
so->so_state |= SS_ISDISCONNECTING;
if (!SOLISTENING(so)) {
SOCKBUF_LOCK(&so->so_rcv);
SOCK_RECVBUF_LOCK(so);
socantrcvmore_locked(so);
SOCKBUF_LOCK(&so->so_snd);
SOCK_SENDBUF_LOCK(so);
socantsendmore_locked(so);
}
SOCK_UNLOCK(so);
@ -4140,9 +4144,9 @@ soisdisconnected(struct socket *so)
if (!SOLISTENING(so)) {
SOCK_UNLOCK(so);
SOCKBUF_LOCK(&so->so_rcv);
SOCK_RECVBUF_LOCK(so);
socantrcvmore_locked(so);
SOCKBUF_LOCK(&so->so_snd);
SOCK_SENDBUF_LOCK(so);
sbdrop_locked(&so->so_snd, sbused(&so->so_snd));
socantsendmore_locked(so);
} else
@ -4225,10 +4229,8 @@ soupcall_set(struct socket *so, sb_which which, so_upcall_t func, void *arg)
case SO_SND:
sb = &so->so_snd;
break;
default:
panic("soupcall_set: bad which");
}
SOCKBUF_LOCK_ASSERT(sb);
SOCK_BUF_LOCK_ASSERT(so, which);
sb->sb_upcall = func;
sb->sb_upcallarg = arg;
sb->sb_flags |= SB_UPCALL;
@ -4249,7 +4251,7 @@ soupcall_clear(struct socket *so, sb_which which)
sb = &so->so_snd;
break;
}
SOCKBUF_LOCK_ASSERT(sb);
SOCK_BUF_LOCK_ASSERT(so, which);
KASSERT(sb->sb_upcall != NULL,
("%s: so %p no upcall to clear", __func__, so));
sb->sb_upcall = NULL;
@ -4274,7 +4276,7 @@ so_rdknl_lock(void *arg)
if (SOLISTENING(so))
SOCK_LOCK(so);
else
SOCKBUF_LOCK(&so->so_rcv);
SOCK_RECVBUF_LOCK(so);
}
static void
@ -4285,7 +4287,7 @@ so_rdknl_unlock(void *arg)
if (SOLISTENING(so))
SOCK_UNLOCK(so);
else
SOCKBUF_UNLOCK(&so->so_rcv);
SOCK_RECVBUF_UNLOCK(so);
}
static void