On 08 Apr 2015, at 02:31, Philip Guenther <guent...@gmail.com> wrote:

> On Tue, Apr 7, 2015 at 3:57 PM, Kanonenvogel <kanonenvogel....@gmail.com> 
> wrote:
>> I have idea to modify falloc() function and related logic.
>> Now, after successful faclloc call,  we have half-initialized struct file 
>> object, protected by FIF_LARVAL flag.
>> I want to initialise struct file object within falloc() and then put it to 
>> fd_ofiles array and filehead list. This modification
>> permits to avoid half-initialization state and remove FIF_LARVAL flag and 
>> related logic.
> 
> The hard case is blocking opens of fifos, as the underlying operation
> involves a change visible to another process and that therefore cannot
> be rolled back.
> 
> 
> Philip Guenther
Ok, I understood.
And what about make struct file more smp friendly? For example, make operations 
under
f_iflags and f_flags atomic?

Index: kern/kern_descrip.c
===================================================================
RCS file: /cvs/src/sys/kern/kern_descrip.c,v
retrieving revision 1.116
diff -u -p -r1.116 kern_descrip.c
--- kern/kern_descrip.c 19 Jan 2015 01:19:17 -0000      1.116
+++ kern/kern_descrip.c 8 Apr 2015 09:21:19 -0000
@@ -61,6 +61,7 @@
 #include <sys/event.h>
 #include <sys/pool.h>
 #include <sys/ktrace.h>
+#include <sys/atomic.h>
 
 #include <sys/pipe.h>
 
@@ -332,6 +333,7 @@ sys_fcntl(struct proc *p, void *v, regis
        int i, tmp, newmin, flg = F_POSIX;
        struct flock fl;
        int error = 0;
+       int oflag, nflag;
 
 restart:
        if ((fp = fd_getfile(fdp, fd)) == NULL)
@@ -384,8 +386,12 @@ restart:
                break;
 
        case F_SETFL:
-               fp->f_flag &= ~FCNTLFLAGS;
-               fp->f_flag |= FFLAGS((long)SCARG(uap, arg)) & FCNTLFLAGS;
+               do {
+                       oflag = fp->f_flag;
+                       nflag = oflag & ~FCNTLFLAGS;
+                       nflag |= FFLAGS((long)SCARG(uap, arg)) & FCNTLFLAGS;
+               } while (atomic_cas_uint(&fp->f_flag, oflag, nflag) != oflag);
+
                tmp = fp->f_flag & FNONBLOCK;
                error = (*fp->f_ops->fo_ioctl)(fp, FIONBIO, (caddr_t)&tmp, p);
                if (error)
@@ -394,7 +400,7 @@ restart:
                error = (*fp->f_ops->fo_ioctl)(fp, FIOASYNC, (caddr_t)&tmp, p);
                if (!error)
                        break;
-               fp->f_flag &= ~FNONBLOCK;
+               atomic_clearbits_int(&fp->f_flag, FNONBLOCK);
                tmp = 0;
                (void) (*fp->f_ops->fo_ioctl)(fp, FIONBIO, (caddr_t)&tmp, p);
                break;
@@ -1160,7 +1166,7 @@ sys_flock(struct proc *p, void *v, regis
        lf.l_len = 0;
        if (how & LOCK_UN) {
                lf.l_type = F_UNLCK;
-               fp->f_iflags &= ~FIF_HASLOCK;
+               atomic_clearbits_int(&fp->f_iflags, FIF_HASLOCK);
                error = VOP_ADVLOCK(vp, (caddr_t)fp, F_UNLCK, &lf, F_FLOCK);
                goto out;
        }
@@ -1172,7 +1178,7 @@ sys_flock(struct proc *p, void *v, regis
                error = EINVAL;
                goto out;
        }
-       fp->f_iflags |= FIF_HASLOCK;
+       atomic_setbits_int(&fp->f_iflags, FIF_HASLOCK);
        if (how & LOCK_NB)
                error = VOP_ADVLOCK(vp, (caddr_t)fp, F_SETLK, &lf, F_FLOCK);
        else
Index: kern/sys_generic.c
===================================================================
RCS file: /cvs/src/sys/kern/sys_generic.c,v
retrieving revision 1.96
diff -u -p -r1.96 sys_generic.c
--- kern/sys_generic.c  12 Feb 2015 22:27:04 -0000      1.96
+++ kern/sys_generic.c  8 Apr 2015 09:21:19 -0000
@@ -52,6 +52,7 @@
 #include <sys/stat.h>
 #include <sys/malloc.h>
 #include <sys/poll.h>
+#include <sys/atomic.h>
 #ifdef KTRACE
 #include <sys/ktrace.h>
 #endif
@@ -456,17 +457,17 @@ sys_ioctl(struct proc *p, void *v, regis
 
        case FIONBIO:
                if ((tmp = *(int *)data) != 0)
-                       fp->f_flag |= FNONBLOCK;
+                       atomic_setbits_int(&fp->f_flag, FNONBLOCK);
                else
-                       fp->f_flag &= ~FNONBLOCK;
+                       atomic_clearbits_int(&fp->f_flag, FNONBLOCK);
                error = (*fp->f_ops->fo_ioctl)(fp, FIONBIO, (caddr_t)&tmp, p);
                break;
 
        case FIOASYNC:
                if ((tmp = *(int *)data) != 0)
-                       fp->f_flag |= FASYNC;
+                       atomic_setbits_int(&fp->f_flag, FASYNC);
                else
-                       fp->f_flag &= ~FASYNC;
+                       atomic_clearbits_int(&fp->f_flag, FASYNC);
                error = (*fp->f_ops->fo_ioctl)(fp, FIOASYNC, (caddr_t)&tmp, p);
                break;
 
Index: kern/uipc_usrreq.c
===================================================================
RCS file: /cvs/src/sys/kern/uipc_usrreq.c,v
retrieving revision 1.79
diff -u -p -r1.79 uipc_usrreq.c
--- kern/uipc_usrreq.c  11 Dec 2014 19:21:57 -0000      1.79
+++ kern/uipc_usrreq.c  8 Apr 2015 09:21:19 -0000
@@ -884,11 +884,11 @@ unp_gc(void)
        unp_gcing = 1;
        unp_defer = 0;
        LIST_FOREACH(fp, &filehead, f_list)
-               fp->f_iflags &= ~(FIF_MARK|FIF_DEFER);
+               atomic_clearbits_int(&fp->f_iflags, FIF_MARK|FIF_DEFER);
        do {
                LIST_FOREACH(fp, &filehead, f_list) {
                        if (fp->f_iflags & FIF_DEFER) {
-                               fp->f_iflags &= ~FIF_DEFER;
+                               atomic_clearbits_int(&fp->f_iflags, FIF_DEFER);
                                unp_defer--;
                        } else {
                                if (fp->f_count == 0)
@@ -898,7 +898,7 @@ unp_gc(void)
                                if (fp->f_count == fp->f_msgcount)
                                        continue;
                        }
-                       fp->f_iflags |= FIF_MARK;
+                       atomic_setbits_int(&fp->f_iflags, FIF_MARK);
 
                        if (fp->f_type != DTYPE_SOCKET ||
                            (so = fp->f_data) == NULL)
@@ -1040,9 +1040,9 @@ unp_mark(struct file *fp)
 
        if (fp->f_type == DTYPE_SOCKET) {
                unp_defer++;
-               fp->f_iflags |= FIF_DEFER;
+               atomic_setbits_int(&fp->f_iflags, FIF_DEFER);
        } else {
-               fp->f_iflags |= FIF_MARK;
+               atomic_setbits_int(&fp->f_iflags, FIF_MARK);
        }
 }
 
Index: kern/vfs_syscalls.c
===================================================================
RCS file: /cvs/src/sys/kern/vfs_syscalls.c,v
retrieving revision 1.216
diff -u -p -r1.216 vfs_syscalls.c
--- kern/vfs_syscalls.c 16 Dec 2014 18:30:04 -0000      1.216
+++ kern/vfs_syscalls.c 8 Apr 2015 09:21:19 -0000
@@ -901,7 +901,7 @@ doopenat(struct proc *p, int fd, const c
                        goto out;
                }
                vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
-               fp->f_iflags |= FIF_HASLOCK;
+               atomic_setbits_int(&fp->f_iflags, FIF_HASLOCK);
        }
        if (localtrunc) {
                if ((fp->f_flag & FWRITE) == 0)
@@ -1083,7 +1083,7 @@ sys_fhopen(struct proc *p, void *v, regi
                        goto bad;
                }
                vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
-               fp->f_iflags |= FIF_HASLOCK;
+               atomic_setbits_int(&fp->f_iflags, FIF_HASLOCK);
        }
        VOP_UNLOCK(vp, 0, p);
        *retval = indx;
Index: sys/file.h
===================================================================
RCS file: /cvs/src/sys/sys/file.h,v
retrieving revision 1.34
diff -u -p -r1.34 file.h
--- sys/file.h  18 Nov 2014 15:16:35 -0000      1.34
+++ sys/file.h  8 Apr 2015 09:21:23 -0000
@@ -63,7 +63,7 @@ struct        fileops {
  */
 struct file {
        LIST_ENTRY(file) f_list;/* list of active files */
-       short   f_flag;         /* see fcntl.h */
+       volatile int f_flag;    /* see fcntl.h */
 #define        DTYPE_VNODE     1       /* file */
 #define        DTYPE_SOCKET    2       /* communications endpoint */
 #define        DTYPE_PIPE      3       /* pipe */
@@ -77,7 +77,7 @@ struct file {
        struct  fileops *f_ops;
        off_t   f_offset;
        void    *f_data;        /* private data */
-       int     f_iflags;       /* internal flags */
+       volatile int f_iflags;  /* internal flags */
        u_int64_t f_rxfer;      /* total number of read transfers */
        u_int64_t f_wxfer;      /* total number of write transfers */
        u_int64_t f_seek;       /* total independent seek operations */
@@ -96,9 +96,9 @@ struct file {
 #define FREF(fp)       do { (fp)->f_count++; } while (0)
 #define FRELE(fp,p)    (--(fp)->f_count == 0 ? fdrop(fp, p) : 0)
 
-#define FILE_SET_MATURE(fp,p) do {                             \
-       (fp)->f_iflags &= ~FIF_LARVAL;                          \
-       FRELE(fp, p);                                           \
+#define FILE_SET_MATURE(_fp, _p) do {                          \
+       atomic_clearbits_int(&(_fp)->f_iflags, FIF_LARVAL);     \
+       FRELE(_fp, _p);                                         \
 } while (0)
 
 int    fdrop(struct file *, struct proc *);





Reply via email to