sosetstate/soclrstate

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

sosetstate/soclrstate

Martin Pieuchot
Diff below changes the type of `so_state' and `so_error' to int.  It
also introduces two new wrappers to set & clear state bits atomically.

My goal is to prevent a second CPU from reading garbage when looking
at these two fields in filt_soread() and filt_sowrite().  The values
might be outdated though.

This should be the last requirement before unlocking the receiving path.

ok?

Index: kern/uipc_socket.c
===================================================================
RCS file: /cvs/src/sys/kern/uipc_socket.c,v
retrieving revision 1.213
diff -u -p -r1.213 uipc_socket.c
--- kern/uipc_socket.c 2 Jan 2018 12:54:07 -0000 1.213
+++ kern/uipc_socket.c 8 Jan 2018 14:32:33 -0000
@@ -139,7 +139,7 @@ socreate(int dom, struct socket **aso, i
  s = solock(so);
  error = (*prp->pr_attach)(so, proto);
  if (error) {
- so->so_state |= SS_NOFDREF;
+ sosetstate(so, SS_NOFDREF);
  sofree(so);
  sounlock(s);
  return (error);
@@ -275,7 +275,7 @@ drop:
 discard:
  if (so->so_state & SS_NOFDREF)
  panic("soclose NOFDREF: so %p, so_type %d", so, so->so_type);
- so->so_state |= SS_NOFDREF;
+ sosetstate(so, SS_NOFDREF);
  sofree(so);
  sounlock(s);
  return (error);
@@ -299,7 +299,7 @@ soaccept(struct socket *so, struct mbuf
 
  if ((so->so_state & SS_NOFDREF) == 0)
  panic("soaccept !NOFDREF: so %p, so_type %d", so, so->so_type);
- so->so_state &= ~SS_NOFDREF;
+ soclrstate(so, SS_NOFDREF);
  if ((so->so_state & SS_ISDISCONNECTED) == 0 ||
     (so->so_proto->pr_flags & PR_ABRTACPTDIS) == 0)
  error = (*so->so_proto->pr_usrreq)(so, PRU_ACCEPT, NULL,
@@ -425,7 +425,7 @@ sosend(struct socket *so, struct mbuf *a
 restart:
  if ((error = sblock(so, &so->so_snd, SBLOCKWAIT(flags))) != 0)
  goto out;
- so->so_state |= SS_ISSENDING;
+ sosetstate(so, SS_ISSENDING);
  do {
  if (so->so_state & SS_CANTSENDMORE)
  snderr(EPIPE);
@@ -455,7 +455,7 @@ restart:
  snderr(EWOULDBLOCK);
  sbunlock(so, &so->so_snd);
  error = sbwait(so, &so->so_snd);
- so->so_state &= ~SS_ISSENDING;
+ soclrstate(so, SS_ISSENDING);
  if (error)
  goto out;
  goto restart;
@@ -481,7 +481,7 @@ restart:
  top->m_flags |= M_EOR;
  }
  if (resid == 0)
- so->so_state &= ~SS_ISSENDING;
+ soclrstate(so, SS_ISSENDING);
  if (top && so->so_options & SO_ZEROIZE)
  top->m_flags |= M_ZEROIZE;
  error = (*so->so_proto->pr_usrreq)(so,
@@ -496,7 +496,7 @@ restart:
  } while (resid);
 
 release:
- so->so_state &= ~SS_ISSENDING;
+ soclrstate(so, SS_ISSENDING);
  sbunlock(so, &so->so_snd);
 out:
  sounlock(s);
@@ -857,7 +857,7 @@ dontblock:
  panic("receive 3: so %p, so_type %d, m %p, m_type %d",
     so, so->so_type, m, m->m_type);
 #endif
- so->so_state &= ~SS_RCVATMARK;
+ soclrstate(so, SS_RCVATMARK);
  len = uio->uio_resid;
  if (so->so_oobmark && len > so->so_oobmark - offset)
  len = so->so_oobmark - offset;
@@ -932,7 +932,7 @@ dontblock:
  if ((flags & MSG_PEEK) == 0) {
  so->so_oobmark -= len;
  if (so->so_oobmark == 0) {
- so->so_state |= SS_RCVATMARK;
+ sosetstate(so, SS_RCVATMARK);
  break;
  }
  } else {
@@ -1292,7 +1292,7 @@ somove(struct socket *so, int wait)
  goto release;
  len = space;
  }
- sosp->so_state |= SS_ISSENDING;
+ sosetstate(sosp, SS_ISSENDING);
 
  SBLASTRECORDCHK(&so->so_rcv, "somove 1");
  SBLASTMBUFCHK(&so->so_rcv, "somove 1");
@@ -1422,12 +1422,12 @@ somove(struct socket *so, int wait)
 
  /* Receive buffer did shrink by len bytes, adjust oob. */
  state = so->so_state;
- so->so_state &= ~SS_RCVATMARK;
+ soclrstate(so, SS_RCVATMARK);
  oobmark = so->so_oobmark;
  so->so_oobmark = oobmark > len ? oobmark - len : 0;
  if (oobmark) {
  if (oobmark == len)
- so->so_state |= SS_RCVATMARK;
+ sosetstate(so, SS_RCVATMARK);
  if (oobmark >= len)
  oobmark = 0;
  }
@@ -1485,7 +1485,7 @@ somove(struct socket *so, int wait)
 
  /* Append all remaining data to drain socket. */
  if (so->so_rcv.sb_cc == 0 || maxreached)
- sosp->so_state &= ~SS_ISSENDING;
+ soclrstate(sosp, SS_ISSENDING);
  error = (*sosp->so_proto->pr_usrreq)(sosp, PRU_SEND, m, NULL, NULL,
     NULL);
  if (error) {
@@ -1500,7 +1500,7 @@ somove(struct socket *so, int wait)
  goto nextpkt;
 
  release:
- sosp->so_state &= ~SS_ISSENDING;
+ soclrstate(sosp, SS_ISSENDING);
  if (!error && maxreached && so->so_splicemax == so->so_splicelen)
  error = EFBIG;
  if (error)
Index: kern/sys_socket.c
===================================================================
RCS file: /cvs/src/sys/kern/sys_socket.c,v
retrieving revision 1.35
diff -u -p -r1.35 sys_socket.c
--- kern/sys_socket.c 10 Dec 2017 11:31:54 -0000 1.35
+++ kern/sys_socket.c 8 Jan 2018 14:25:21 -0000
@@ -80,20 +80,20 @@ soo_ioctl(struct file *fp, u_long cmd, c
  case FIONBIO:
  s = solock(so);
  if (*(int *)data)
- so->so_state |= SS_NBIO;
+ sosetstate(so, SS_NBIO);
  else
- so->so_state &= ~SS_NBIO;
+ soclrstate(so, SS_NBIO);
  sounlock(s);
  break;
 
  case FIOASYNC:
  s = solock(so);
  if (*(int *)data) {
- so->so_state |= SS_ASYNC;
+ sosetstate(so, SS_ASYNC);
  so->so_rcv.sb_flags |= SB_ASYNC;
  so->so_snd.sb_flags |= SB_ASYNC;
  } else {
- so->so_state &= ~SS_ASYNC;
+ soclrstate(so, SS_ASYNC);
  so->so_rcv.sb_flags &= ~SB_ASYNC;
  so->so_snd.sb_flags &= ~SB_ASYNC;
  }
Index: kern/uipc_usrreq.c
===================================================================
RCS file: /cvs/src/sys/kern/uipc_usrreq.c,v
retrieving revision 1.123
diff -u -p -r1.123 uipc_usrreq.c
--- kern/uipc_usrreq.c 4 Jan 2018 10:45:30 -0000 1.123
+++ kern/uipc_usrreq.c 8 Jan 2018 14:30:45 -0000
@@ -575,7 +575,7 @@ unp_disconnect(struct unpcb *unp)
 
  case SOCK_DGRAM:
  SLIST_REMOVE(&unp2->unp_refs, unp, unpcb, unp_nextref);
- unp->unp_socket->so_state &= ~SS_ISCONNECTED;
+ soclrstate(unp->unp_socket, SS_ISCONNECTED);
  break;
 
  case SOCK_STREAM:
Index: kern/uipc_socket2.c
===================================================================
RCS file: /cvs/src/sys/kern/uipc_socket2.c,v
retrieving revision 1.89
diff -u -p -r1.89 uipc_socket2.c
--- kern/uipc_socket2.c 30 Dec 2017 20:47:00 -0000 1.89
+++ kern/uipc_socket2.c 8 Jan 2018 14:30:01 -0000
@@ -87,8 +87,8 @@ void
 soisconnecting(struct socket *so)
 {
  soassertlocked(so);
- so->so_state &= ~(SS_ISCONNECTED|SS_ISDISCONNECTING);
- so->so_state |= SS_ISCONNECTING;
+ soclrstate(so, SS_ISCONNECTED|SS_ISDISCONNECTING);
+ sosetstate(so, SS_ISCONNECTING);
 }
 
 void
@@ -97,8 +97,8 @@ soisconnected(struct socket *so)
  struct socket *head = so->so_head;
 
  soassertlocked(so);
- so->so_state &= ~(SS_ISCONNECTING|SS_ISDISCONNECTING);
- so->so_state |= SS_ISCONNECTED;
+ soclrstate(so, SS_ISCONNECTING|SS_ISDISCONNECTING);
+ sosetstate(so, SS_ISCONNECTED);
  if (head && soqremque(so, 0)) {
  soqinsque(head, so, 1);
  sorwakeup(head);
@@ -114,8 +114,8 @@ void
 soisdisconnecting(struct socket *so)
 {
  soassertlocked(so);
- so->so_state &= ~SS_ISCONNECTING;
- so->so_state |= (SS_ISDISCONNECTING|SS_CANTRCVMORE|SS_CANTSENDMORE);
+ soclrstate(so, SS_ISCONNECTING);
+ sosetstate(so, SS_ISDISCONNECTING|SS_CANTRCVMORE|SS_CANTSENDMORE);
  wakeup(&so->so_timeo);
  sowwakeup(so);
  sorwakeup(so);
@@ -125,8 +125,8 @@ void
 soisdisconnected(struct socket *so)
 {
  soassertlocked(so);
- so->so_state &= ~(SS_ISCONNECTING|SS_ISCONNECTED|SS_ISDISCONNECTING);
- so->so_state |= (SS_CANTRCVMORE|SS_CANTSENDMORE|SS_ISDISCONNECTED);
+ soclrstate(so, SS_ISCONNECTING|SS_ISCONNECTED|SS_ISDISCONNECTING);
+ sosetstate(so, SS_CANTRCVMORE|SS_CANTSENDMORE|SS_ISDISCONNECTED);
  wakeup(&so->so_timeo);
  sowwakeup(so);
  sorwakeup(so);
@@ -198,7 +198,7 @@ sonewconn(struct socket *head, int conns
  if (connstatus) {
  sorwakeup(head);
  wakeup(&head->so_timeo);
- so->so_state |= connstatus;
+ sosetstate(so, connstatus);
  }
  return (so);
 }
@@ -260,7 +260,7 @@ void
 socantsendmore(struct socket *so)
 {
  soassertlocked(so);
- so->so_state |= SS_CANTSENDMORE;
+ sosetstate(so, SS_CANTSENDMORE);
  sowwakeup(so);
 }
 
@@ -268,7 +268,7 @@ void
 socantrcvmore(struct socket *so)
 {
  soassertlocked(so);
- so->so_state |= SS_CANTRCVMORE;
+ sosetstate(so, SS_CANTRCVMORE);
  sorwakeup(so);
 }
 
Index: kern/uipc_syscalls.c
===================================================================
RCS file: /cvs/src/sys/kern/uipc_syscalls.c,v
retrieving revision 1.161
diff -u -p -r1.161 uipc_syscalls.c
--- kern/uipc_syscalls.c 2 Jan 2018 06:38:45 -0000 1.161
+++ kern/uipc_syscalls.c 8 Jan 2018 14:29:48 -0000
@@ -112,8 +112,8 @@ sys_socket(struct proc *p, void *v, regi
  fdpunlock(fdp);
  } else {
  if (type & SOCK_NONBLOCK)
- so->so_state |= SS_NBIO;
- so->so_state |= ss;
+ sosetstate(so, SS_NBIO);
+ sosetstate(so, ss);
  fp->f_data = so;
  FILE_SET_MATURE(fp, p);
  *retval = fd;
@@ -340,9 +340,9 @@ doaccept(struct proc *p, int sock, struc
  error = copyaddrout(p, nam, name, namelen, anamelen);
  if (!error) {
  if (nflag & FNONBLOCK)
- so->so_state |= SS_NBIO;
+ sosetstate(so, SS_NBIO);
  else
- so->so_state &= ~SS_NBIO;
+ soclrstate(so, SS_NBIO);
  fp->f_data = so;
  FILE_SET_MATURE(fp, p);
  *retval = tmpfd;
@@ -424,7 +424,7 @@ sys_connect(struct proc *p, void *v, reg
  }
 bad:
  if (!interrupted)
- so->so_state &= ~SS_ISCONNECTING;
+ soclrstate(so, SS_ISCONNECTING);
 out:
  sounlock(s);
  FRELE(fp, p);
Index: miscfs/fifofs/fifo_vnops.c
===================================================================
RCS file: /cvs/src/sys/miscfs/fifofs/fifo_vnops.c,v
retrieving revision 1.62
diff -u -p -r1.62 fifo_vnops.c
--- miscfs/fifofs/fifo_vnops.c 2 Jan 2018 06:38:45 -0000 1.62
+++ miscfs/fifofs/fifo_vnops.c 8 Jan 2018 14:31:49 -0000
@@ -158,7 +158,7 @@ fifo_open(void *v)
  return (error);
  }
  fip->fi_readers = fip->fi_writers = 0;
- wso->so_state |= SS_CANTSENDMORE;
+ sosetstate(wso, SS_CANTSENDMORE);
  wso->so_snd.sb_lowat = PIPE_BUF;
  } else {
  rso = fip->fi_readsock;
@@ -168,7 +168,7 @@ fifo_open(void *v)
  if (ap->a_mode & FREAD) {
  fip->fi_readers++;
  if (fip->fi_readers == 1) {
- wso->so_state &= ~SS_CANTSENDMORE;
+ soclrstate(wso, SS_CANTSENDMORE);
  if (fip->fi_writers > 0)
  wakeup(&fip->fi_writers);
  }
@@ -181,7 +181,7 @@ fifo_open(void *v)
  goto bad;
  }
  if (fip->fi_writers == 1) {
- rso->so_state &= ~(SS_CANTRCVMORE|SS_ISDISCONNECTED);
+ soclrstate(rso, (SS_CANTRCVMORE|SS_ISDISCONNECTED));
  if (fip->fi_readers > 0)
  wakeup(&fip->fi_readers);
  }
@@ -231,12 +231,12 @@ fifo_read(void *v)
  if (uio->uio_resid == 0)
  return (0);
  if (ap->a_ioflag & IO_NDELAY)
- rso->so_state |= SS_NBIO;
+ sosetstate(rso, SS_NBIO);
  VOP_UNLOCK(ap->a_vp, p);
  error = soreceive(rso, NULL, uio, NULL, NULL, NULL, 0);
  vn_lock(ap->a_vp, LK_EXCLUSIVE | LK_RETRY, p);
  if (ap->a_ioflag & IO_NDELAY) {
- rso->so_state &= ~SS_NBIO;
+ soclrstate(rso, SS_NBIO);
  if (error == EWOULDBLOCK &&
     ap->a_vp->v_fifoinfo->fi_writers == 0)
  error = 0;
@@ -260,14 +260,13 @@ fifo_write(void *v)
  if (ap->a_uio->uio_rw != UIO_WRITE)
  panic("fifo_write mode");
 #endif
- /* XXXSMP changing state w/o lock isn't safe. */
  if (ap->a_ioflag & IO_NDELAY)
- wso->so_state |= SS_NBIO;
+ sosetstate(wso, SS_NBIO);
  VOP_UNLOCK(ap->a_vp, p);
  error = sosend(wso, NULL, ap->a_uio, NULL, NULL, 0);
  vn_lock(ap->a_vp, LK_EXCLUSIVE | LK_RETRY, p);
  if (ap->a_ioflag & IO_NDELAY)
- wso->so_state &= ~SS_NBIO;
+ soclrstate(wso, SS_NBIO);
  return (error);
 }
 
@@ -387,7 +386,7 @@ fifo_close(void *v)
 
  s = solock(rso);
  /* SS_ISDISCONNECTED will result in POLLHUP */
- rso->so_state |= SS_ISDISCONNECTED;
+ sosetstate(rso, SS_ISDISCONNECTED);
  socantrcvmore(rso);
  sounlock(s);
  }
Index: netinet/tcp_usrreq.c
===================================================================
RCS file: /cvs/src/sys/netinet/tcp_usrreq.c,v
retrieving revision 1.162
diff -u -p -r1.162 tcp_usrreq.c
--- netinet/tcp_usrreq.c 1 Dec 2017 10:33:33 -0000 1.162
+++ netinet/tcp_usrreq.c 8 Jan 2018 14:32:00 -0000
@@ -246,7 +246,7 @@ tcp_usrreq(struct socket *so, int req, s
  break;
  }
 
- so->so_state |= SS_CONNECTOUT;
+ sosetstate(so, SS_CONNECTOUT);
 
  /* Compute window scaling to request.  */
  tcp_rscale(tp, sb_max);
@@ -585,9 +585,9 @@ tcp_attach(struct socket *so, int proto)
  if (tp == NULL) {
  int nofd = so->so_state & SS_NOFDREF; /* XXX */
 
- so->so_state &= ~SS_NOFDREF; /* don't free the socket yet */
+ soclrstate(so, SS_NOFDREF); /* don't free the socket yet */
  in_pcbdetach(inp);
- so->so_state |= nofd;
+ sosetstate(so, nofd);
  return (ENOBUFS);
  }
  tp->t_state = TCPS_CLOSED;
Index: netinet/udp_usrreq.c
===================================================================
RCS file: /cvs/src/sys/netinet/udp_usrreq.c,v
retrieving revision 1.245
diff -u -p -r1.245 udp_usrreq.c
--- netinet/udp_usrreq.c 1 Dec 2017 10:33:33 -0000 1.245
+++ netinet/udp_usrreq.c 8 Jan 2018 14:28:40 -0000
@@ -1144,7 +1144,7 @@ udp_usrreq(struct socket *so, int req, s
  inp->inp_laddr.s_addr = INADDR_ANY;
  in_pcbdisconnect(inp);
 
- so->so_state &= ~SS_ISCONNECTED; /* XXX */
+ soclrstate(so, SS_ISCONNECTED); /* XXX */
  break;
 
  case PRU_SHUTDOWN:
Index: netinet/tcp_input.c
===================================================================
RCS file: /cvs/src/sys/netinet/tcp_input.c,v
retrieving revision 1.354
diff -u -p -r1.354 tcp_input.c
--- netinet/tcp_input.c 4 Dec 2017 13:40:34 -0000 1.354
+++ netinet/tcp_input.c 8 Jan 2018 14:28:45 -0000
@@ -1872,7 +1872,7 @@ step6:
  so->so_oobmark = so->so_rcv.sb_cc +
     (tp->rcv_up - tp->rcv_nxt) - 1;
  if (so->so_oobmark == 0)
- so->so_state |= SS_RCVATMARK;
+ sosetstate(so, SS_RCVATMARK);
  sohasoutofband(so);
  tp->t_oobflags &= ~(TCPOOB_HAVEDATA | TCPOOB_HADDATA);
  }
Index: netinet6/raw_ip6.c
===================================================================
RCS file: /cvs/src/sys/netinet6/raw_ip6.c,v
retrieving revision 1.125
diff -u -p -r1.125 raw_ip6.c
--- netinet6/raw_ip6.c 4 Dec 2017 13:40:35 -0000 1.125
+++ netinet6/raw_ip6.c 8 Jan 2018 14:28:50 -0000
@@ -560,7 +560,7 @@ rip6_usrreq(struct socket *so, int req,
  break;
  }
  in6p->inp_faddr6 = in6addr_any;
- so->so_state &= ~SS_ISCONNECTED; /* XXX */
+ soclrstate(so, SS_ISCONNECTED); /* XXX */
  break;
 
  case PRU_ABORT:
Index: nfs/nfs_socket.c
===================================================================
RCS file: /cvs/src/sys/nfs/nfs_socket.c,v
retrieving revision 1.128
diff -u -p -r1.128 nfs_socket.c
--- nfs/nfs_socket.c 7 Sep 2017 11:35:34 -0000 1.128
+++ nfs/nfs_socket.c 8 Jan 2018 14:28:55 -0000
@@ -319,7 +319,7 @@ nfs_connect(struct nfsmount *nmp, struct
  if ((so->so_state & SS_ISCONNECTING) &&
     so->so_error == 0 && rep &&
     (error = nfs_sigintr(nmp, rep, rep->r_procp)) != 0){
- so->so_state &= ~SS_ISCONNECTING;
+ soclrstate(so, SS_ISCONNECTING);
  goto bad;
  }
  }
Index: sys/socketvar.h
===================================================================
RCS file: /cvs/src/sys/sys/socketvar.h,v
retrieving revision 1.81
diff -u -p -r1.81 socketvar.h
--- sys/socketvar.h 2 Jan 2018 12:54:07 -0000 1.81
+++ sys/socketvar.h 8 Jan 2018 14:20:40 -0000
@@ -51,12 +51,12 @@ TAILQ_HEAD(soqhead, socket);
  * private data and error information.
  */
 struct socket {
+ const struct protosw *so_proto; /* protocol handle */
+ void *so_pcb; /* protocol control block */
+ u_int so_state; /* internal state flags SS_*, below */
  short so_type; /* generic type, see socket.h */
  short so_options; /* from socket call, see socket.h */
  short so_linger; /* time to linger while closing */
- short so_state; /* internal state flags SS_*, below */
- void *so_pcb; /* protocol control block */
- const struct protosw *so_proto; /* protocol handle */
 /*
  * Variables for connection queueing.
  * Socket where accepts occur is so_head in all subsidiary sockets.
@@ -77,7 +77,7 @@ struct socket {
  short so_qlen; /* number of connections on so_q */
  short so_qlimit; /* max number queued connections */
  short so_timeo; /* connection timeout */
- u_short so_error; /* error affecting connection */
+ u_int so_error; /* error affecting connection */
  pid_t so_pgid; /* pgid for signals */
  uid_t so_siguid; /* uid of process who set so_pgid */
  uid_t so_sigeuid; /* euid of process who set so_pgid */
@@ -156,6 +156,7 @@ struct socket {
 
 #ifdef _KERNEL
 
+#include <sys/atomic.h>
 #include <lib/libkern/libkern.h>
 
 void soassertlocked(struct socket *);
@@ -167,6 +168,18 @@ void soassertlocked(struct socket *);
 #define isspliced(so) ((so)->so_sp && (so)->so_sp->ssp_socket)
 #define issplicedback(so) ((so)->so_sp && (so)->so_sp->ssp_soback)
 
+static inline void
+sosetstate(struct socket *so, unsigned int state)
+{
+ atomic_setbits_int(&so->so_state, state);
+}
+
+static inline void
+soclrstate(struct socket *so, unsigned int state)
+{
+ atomic_clearbits_int(&so->so_state, state);
+}
+
 /*
  * Do we need to notify the other side when I/O is possible?
  */
@@ -190,10 +203,6 @@ static inline long
 sbspace(struct socket *so, struct sockbuf *sb)
 {
  KASSERT(sb == &so->so_rcv || sb == &so->so_snd);
-#if 0
- /* XXXSMP kqueue_scan() calling filt_sowrite() cannot sleep. */
- soassertlocked(so);
-#endif
  return lmin(sb->sb_hiwat - sb->sb_cc, sb->sb_mbmax - sb->sb_mbcnt);
 }
 

Reply | Threaded
Open this post in threaded view
|

Re: sosetstate/soclrstate

Alexander Bluhm
On Mon, Jan 08, 2018 at 03:50:14PM +0100, Martin Pieuchot wrote:
> ok?

OK bluhm@ with a few remarks.

> @@ -1422,12 +1422,12 @@ somove(struct socket *so, int wait)
>  
>   /* Receive buffer did shrink by len bytes, adjust oob. */
>   state = so->so_state;
> - so->so_state &= ~SS_RCVATMARK;
> + soclrstate(so, SS_RCVATMARK);
>   oobmark = so->so_oobmark;
>   so->so_oobmark = oobmark > len ? oobmark - len : 0;
>   if (oobmark) {

Can we make the "state" also u_int?

> @@ -198,7 +198,7 @@ sonewconn(struct socket *head, int conns
>   if (connstatus) {
>   sorwakeup(head);
>   wakeup(&head->so_timeo);
> - so->so_state |= connstatus;
> + sosetstate(so, connstatus);
>   }
>   return (so);
>  }

"connstatus" should be u_int.

> @@ -112,8 +112,8 @@ sys_socket(struct proc *p, void *v, regi
>   fdpunlock(fdp);
>   } else {
>   if (type & SOCK_NONBLOCK)
> - so->so_state |= SS_NBIO;
> - so->so_state |= ss;
> + sosetstate(so, SS_NBIO);
> + sosetstate(so, ss);
>   fp->f_data = so;
>   FILE_SET_MATURE(fp, p);
>   *retval = fd;

"ss" should be u_int for consistency.  And pledge_socket() still
takes the state as signed int.

> @@ -181,7 +181,7 @@ fifo_open(void *v)
>   goto bad;
>   }
>   if (fip->fi_writers == 1) {
> - rso->so_state &= ~(SS_CANTRCVMORE|SS_ISDISCONNECTED);
> + soclrstate(rso, (SS_CANTRCVMORE|SS_ISDISCONNECTED));
>   if (fip->fi_readers > 0)
>   wakeup(&fip->fi_readers);
>   }

There are more () than needed.

> @@ -585,9 +585,9 @@ tcp_attach(struct socket *so, int proto)
>   if (tp == NULL) {
>   int nofd = so->so_state & SS_NOFDREF; /* XXX */
>  
> - so->so_state &= ~SS_NOFDREF; /* don't free the socket yet */
> + soclrstate(so, SS_NOFDREF); /* don't free the socket yet */
>   in_pcbdetach(inp);
> - so->so_state |= nofd;
> + sosetstate(so, nofd);
>   return (ENOBUFS);
>   }
>   tp->t_state = TCPS_CLOSED;

nofd should be u_int.

Reply | Threaded
Open this post in threaded view
|

Re: sosetstate/soclrstate

Martin Pieuchot
On 09/01/18(Tue) 00:42, Alexander Bluhm wrote:
> On Mon, Jan 08, 2018 at 03:50:14PM +0100, Martin Pieuchot wrote:
> > ok?
>
> OK bluhm@ with a few remarks.

visa@ pointed out that since all the writes are done under the socket
lock it is enough to use an aligned int32 variable.  So here's an
updated diff that address your comments.

Index: kern/kern_pledge.c
===================================================================
RCS file: /cvs/src/sys/kern/kern_pledge.c,v
retrieving revision 1.227
diff -u -p -r1.227 kern_pledge.c
--- kern/kern_pledge.c 8 Jan 2018 11:54:28 -0000 1.227
+++ kern/kern_pledge.c 9 Jan 2018 10:17:28 -0000
@@ -1337,7 +1337,7 @@ pledge_sockopt(struct proc *p, int set,
 }
 
 int
-pledge_socket(struct proc *p, int domain, int state)
+pledge_socket(struct proc *p, int domain, unsigned int state)
 {
  if (! ISSET(p->p_p->ps_flags, PS_PLEDGE))
  return 0;
Index: kern/uipc_socket.c
===================================================================
RCS file: /cvs/src/sys/kern/uipc_socket.c,v
retrieving revision 1.213
diff -u -p -r1.213 uipc_socket.c
--- kern/uipc_socket.c 2 Jan 2018 12:54:07 -0000 1.213
+++ kern/uipc_socket.c 9 Jan 2018 10:14:21 -0000
@@ -1248,7 +1248,7 @@ somove(struct socket *so, int wait)
  u_long len, off, oobmark;
  long space;
  int error = 0, maxreached = 0;
- short state;
+ unsigned int state;
 
  soassertlocked(so);
 
Index: kern/uipc_syscalls.c
===================================================================
RCS file: /cvs/src/sys/kern/uipc_syscalls.c,v
retrieving revision 1.161
diff -u -p -r1.161 uipc_syscalls.c
--- kern/uipc_syscalls.c 2 Jan 2018 06:38:45 -0000 1.161
+++ kern/uipc_syscalls.c 9 Jan 2018 10:17:39 -0000
@@ -83,7 +83,8 @@ sys_socket(struct proc *p, void *v, regi
  struct file *fp;
  int type = SCARG(uap, type);
  int domain = SCARG(uap, domain);
- int fd, error, ss = 0;
+ int fd, error;
+ unsigned int ss = 0;
 
  if ((type & SOCK_DNS) && !(domain == AF_INET || domain == AF_INET6))
  return (EINVAL);
Index: netinet/tcp_usrreq.c
===================================================================
RCS file: /cvs/src/sys/netinet/tcp_usrreq.c,v
retrieving revision 1.162
diff -u -p -r1.162 tcp_usrreq.c
--- netinet/tcp_usrreq.c 1 Dec 2017 10:33:33 -0000 1.162
+++ netinet/tcp_usrreq.c 9 Jan 2018 10:15:30 -0000
@@ -583,7 +583,7 @@ tcp_attach(struct socket *so, int proto)
  inp = sotoinpcb(so);
  tp = tcp_newtcpcb(inp);
  if (tp == NULL) {
- int nofd = so->so_state & SS_NOFDREF; /* XXX */
+ unsigned int nofd = so->so_state & SS_NOFDREF; /* XXX */
 
  so->so_state &= ~SS_NOFDREF; /* don't free the socket yet */
  in_pcbdetach(inp);
Index: netinet6/ip6_output.c
===================================================================
RCS file: /cvs/src/sys/netinet6/ip6_output.c,v
retrieving revision 1.232
diff -u -p -r1.232 ip6_output.c
--- netinet6/ip6_output.c 1 Sep 2017 15:05:31 -0000 1.232
+++ netinet6/ip6_output.c 9 Jan 2018 10:16:10 -0000
@@ -1033,12 +1033,12 @@ int
 ip6_ctloutput(int op, struct socket *so, int level, int optname,
     struct mbuf *m)
 {
- int privileged, optdatalen, uproto;
+ int optdatalen, uproto;
  void *optdata;
  struct inpcb *inp = sotoinpcb(so);
  int error, optval;
  struct proc *p = curproc; /* For IPSec and rdomain */
- u_int rtid = 0;
+ u_int privileged, rtid = 0;
 
  error = optval = 0;
 
Index: sys/pledge.h
===================================================================
RCS file: /cvs/src/sys/sys/pledge.h,v
retrieving revision 1.33
diff -u -p -r1.33 pledge.h
--- sys/pledge.h 12 Dec 2017 01:12:34 -0000 1.33
+++ sys/pledge.h 9 Jan 2018 10:17:45 -0000
@@ -126,7 +126,7 @@ int pledge_chown(struct proc *p, uid_t,
 int pledge_adjtime(struct proc *p, const void *v);
 int pledge_sendit(struct proc *p, const void *to);
 int pledge_sockopt(struct proc *p, int set, int level, int optname);
-int pledge_socket(struct proc *p, int domain, int state);
+int pledge_socket(struct proc *p, int domain, unsigned int state);
 int pledge_ioctl(struct proc *p, long com, struct file *);
 int pledge_ioctl_drm(struct proc *p, long com, dev_t device);
 int pledge_ioctl_vmm(struct proc *p, long com);
Index: sys/socketvar.h
===================================================================
RCS file: /cvs/src/sys/sys/socketvar.h,v
retrieving revision 1.81
diff -u -p -r1.81 socketvar.h
--- sys/socketvar.h 2 Jan 2018 12:54:07 -0000 1.81
+++ sys/socketvar.h 9 Jan 2018 10:08:53 -0000
@@ -51,12 +51,12 @@ TAILQ_HEAD(soqhead, socket);
  * private data and error information.
  */
 struct socket {
+ const struct protosw *so_proto; /* protocol handle */
+ void *so_pcb; /* protocol control block */
+ u_int so_state; /* internal state flags SS_*, below */
  short so_type; /* generic type, see socket.h */
  short so_options; /* from socket call, see socket.h */
  short so_linger; /* time to linger while closing */
- short so_state; /* internal state flags SS_*, below */
- void *so_pcb; /* protocol control block */
- const struct protosw *so_proto; /* protocol handle */
 /*
  * Variables for connection queueing.
  * Socket where accepts occur is so_head in all subsidiary sockets.
@@ -77,7 +77,7 @@ struct socket {
  short so_qlen; /* number of connections on so_q */
  short so_qlimit; /* max number queued connections */
  short so_timeo; /* connection timeout */
- u_short so_error; /* error affecting connection */
+ u_int so_error; /* error affecting connection */
  pid_t so_pgid; /* pgid for signals */
  uid_t so_siguid; /* uid of process who set so_pgid */
  uid_t so_sigeuid; /* euid of process who set so_pgid */
@@ -190,10 +190,6 @@ static inline long
 sbspace(struct socket *so, struct sockbuf *sb)
 {
  KASSERT(sb == &so->so_rcv || sb == &so->so_snd);
-#if 0
- /* XXXSMP kqueue_scan() calling filt_sowrite() cannot sleep. */
- soassertlocked(so);
-#endif
  return lmin(sb->sb_hiwat - sb->sb_cc, sb->sb_mbmax - sb->sb_mbcnt);
 }
 

Reply | Threaded
Open this post in threaded view
|

Re: sosetstate/soclrstate

Alexander Bluhm
On Tue, Jan 09, 2018 at 11:23:32AM +0100, Martin Pieuchot wrote:

> --- netinet6/ip6_output.c 1 Sep 2017 15:05:31 -0000 1.232
> +++ netinet6/ip6_output.c 9 Jan 2018 10:16:10 -0000
> @@ -1033,12 +1033,12 @@ int
>  ip6_ctloutput(int op, struct socket *so, int level, int optname,
>      struct mbuf *m)
>  {
> - int privileged, optdatalen, uproto;
> + int optdatalen, uproto;
>   void *optdata;
>   struct inpcb *inp = sotoinpcb(so);
>   int error, optval;
>   struct proc *p = curproc; /* For IPSec and rdomain */
> - u_int rtid = 0;
> + u_int privileged, rtid = 0;
>  
>   error = optval = 0;
>  

"privileged" is passed down as an boolean signed int.  So it does
not matter where it is converted.

anyway OK bluhm@