Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 27 Feb 2019 22:56:55 +0000 (UTC)
From:      Mateusz Guzik <mjg@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r344648 - in head: . sys/kern sys/sys
Message-ID:  <201902272256.x1RMutdK085216@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mjg
Date: Wed Feb 27 22:56:55 2019
New Revision: 344648
URL: https://svnweb.freebsd.org/changeset/base/344648

Log:
  Rename seq to seqc to avoid namespace clashes with Linux
  
  Linux generates the content of procfs files using a mechanism prefixed with
  seq_*. This in particular came up with recent gcov import.
  
  Sponsored by:	The FreeBSD Foundation

Added:
  head/sys/sys/seqc.h   (contents, props changed)
Deleted:
  head/sys/sys/seq.h
Modified:
  head/ObsoleteFiles.inc
  head/sys/kern/kern_descrip.c
  head/sys/sys/filedesc.h

Modified: head/ObsoleteFiles.inc
==============================================================================
--- head/ObsoleteFiles.inc	Wed Feb 27 22:42:29 2019	(r344647)
+++ head/ObsoleteFiles.inc	Wed Feb 27 22:56:55 2019	(r344648)
@@ -38,6 +38,8 @@
 #   xargs -n1 | sort | uniq -d;
 # done
 
+# 20190227: rename seq.h to seqc.h
+OLD_FILES+=usr/include/sys/seq.h
 # 20190222: libifconfig made INTERNALLIB
 OLD_FILES+=usr/lib/libprivateifconfig.a
 OLD_FILES+=usr/lib/libprivateifconfig_p.a

Modified: head/sys/kern/kern_descrip.c
==============================================================================
--- head/sys/kern/kern_descrip.c	Wed Feb 27 22:42:29 2019	(r344647)
+++ head/sys/kern/kern_descrip.c	Wed Feb 27 22:56:55 2019	(r344648)
@@ -304,11 +304,11 @@ fdfree(struct filedesc *fdp, int fd)
 
 	fde = &fdp->fd_ofiles[fd];
 #ifdef CAPABILITIES
-	seq_write_begin(&fde->fde_seq);
+	seqc_write_begin(&fde->fde_seqc);
 #endif
 	fde->fde_file = NULL;
 #ifdef CAPABILITIES
-	seq_write_end(&fde->fde_seq);
+	seqc_write_end(&fde->fde_seqc);
 #endif
 	fdefree_last(fde);
 	fdunused(fdp, fd);
@@ -908,7 +908,7 @@ kern_dup(struct thread *td, u_int mode, int flags, int
 	 * Duplicate the source descriptor.
 	 */
 #ifdef CAPABILITIES
-	seq_write_begin(&newfde->fde_seq);
+	seqc_write_begin(&newfde->fde_seqc);
 #endif
 	memcpy(newfde, oldfde, fde_change_size);
 	filecaps_copy_finish(&oldfde->fde_caps, &newfde->fde_caps,
@@ -918,7 +918,7 @@ kern_dup(struct thread *td, u_int mode, int flags, int
 	else
 		newfde->fde_flags = oldfde->fde_flags & ~UF_EXCLOSE;
 #ifdef CAPABILITIES
-	seq_write_end(&newfde->fde_seq);
+	seqc_write_end(&newfde->fde_seqc);
 #endif
 	td->td_retval[0] = new;
 
@@ -1876,7 +1876,7 @@ _finstall(struct filedesc *fdp, struct file *fp, int f
 
 	fde = &fdp->fd_ofiles[fd];
 #ifdef CAPABILITIES
-	seq_write_begin(&fde->fde_seq);
+	seqc_write_begin(&fde->fde_seqc);
 #endif
 	fde->fde_file = fp;
 	fde->fde_flags = (flags & O_CLOEXEC) != 0 ? UF_EXCLOSE : 0;
@@ -1885,7 +1885,7 @@ _finstall(struct filedesc *fdp, struct file *fp, int f
 	else
 		filecaps_fill(&fde->fde_caps);
 #ifdef CAPABILITIES
-	seq_write_end(&fde->fde_seq);
+	seqc_write_end(&fde->fde_seqc);
 #endif
 }
 
@@ -2567,7 +2567,7 @@ fget_cap(struct thread *td, int fd, cap_rights_t *need
 		filecaps_fill(havecapsp);
 #else
 	struct file *fp;
-	seq_t seq;
+	seqc_t seq;
 
 	for (;;) {
 		error = fget_unlocked(fdp, fd, needrightsp, &fp, &seq);
@@ -2602,7 +2602,7 @@ get_locked:
 
 int
 fget_unlocked(struct filedesc *fdp, int fd, cap_rights_t *needrightsp,
-    struct file **fpp, seq_t *seqp)
+    struct file **fpp, seqc_t *seqp)
 {
 #ifdef CAPABILITIES
 	const struct filedescent *fde;
@@ -2611,7 +2611,7 @@ fget_unlocked(struct filedesc *fdp, int fd, cap_rights
 	struct file *fp;
 	u_int count;
 #ifdef CAPABILITIES
-	seq_t seq;
+	seqc_t seq;
 	cap_rights_t haverights;
 	int error;
 #endif
@@ -2629,11 +2629,11 @@ fget_unlocked(struct filedesc *fdp, int fd, cap_rights
 	 */
 	for (;;) {
 #ifdef CAPABILITIES
-		seq = seq_load(fd_seq(fdt, fd));
+		seq = seqc_read(fd_seqc(fdt, fd));
 		fde = &fdt->fdt_ofiles[fd];
 		haverights = *cap_rights_fde_inline(fde);
 		fp = fde->fde_file;
-		if (!seq_consistent(fd_seq(fdt, fd), seq))
+		if (!seqc_consistent(fd_seqc(fdt, fd), seq))
 			continue;
 #else
 		fp = fdt->fdt_ofiles[fd].fde_file;
@@ -2664,7 +2664,7 @@ fget_unlocked(struct filedesc *fdp, int fd, cap_rights
 			goto retry;
 		fdt = fdp->fd_files;
 #ifdef	CAPABILITIES
-		if (seq_consistent_nomb(fd_seq(fdt, fd), seq))
+		if (seqc_consistent_nomb(fd_seqc(fdt, fd), seq))
 #else
 		if (fp == fdt->fdt_ofiles[fd].fde_file)
 #endif
@@ -2695,7 +2695,7 @@ fget_unlocked(struct filedesc *fdp, int fd, cap_rights
  */
 static __inline int
 _fget(struct thread *td, int fd, struct file **fpp, int flags,
-    cap_rights_t *needrightsp, seq_t *seqp)
+    cap_rights_t *needrightsp, seqc_t *seqp)
 {
 	struct filedesc *fdp;
 	struct file *fp;
@@ -2759,7 +2759,7 @@ fget_mmap(struct thread *td, int fd, cap_rights_t *rig
 		*maxprotp = VM_PROT_ALL;
 #else
 	struct filedesc *fdp = td->td_proc->p_fd;
-	seq_t seq;
+	seqc_t seq;
 
 	MPASS(cap_rights_is_set(rightsp, CAP_MMAP));
 	for (;;) {
@@ -2802,7 +2802,7 @@ fget_fcntl(struct thread *td, int fd, cap_rights_t *ri
 	return (fget_unlocked(fdp, fd, rightsp, fpp, NULL));
 #else
 	int error;
-	seq_t seq;
+	seqc_t seq;
 
 	MPASS(cap_rights_is_set(rightsp, CAP_FCNTL));
 	for (;;) {
@@ -3046,13 +3046,13 @@ dupfdopen(struct thread *td, struct filedesc *fdp, int
 		oldfde = &fdp->fd_ofiles[dfd];
 		ioctls = filecaps_copy_prep(&oldfde->fde_caps);
 #ifdef CAPABILITIES
-		seq_write_begin(&newfde->fde_seq);
+		seqc_write_begin(&newfde->fde_seqc);
 #endif
 		memcpy(newfde, oldfde, fde_change_size);
 		filecaps_copy_finish(&oldfde->fde_caps, &newfde->fde_caps,
 		    ioctls);
 #ifdef CAPABILITIES
-		seq_write_end(&newfde->fde_seq);
+		seqc_write_end(&newfde->fde_seqc);
 #endif
 		break;
 	case ENXIO:
@@ -3062,13 +3062,13 @@ dupfdopen(struct thread *td, struct filedesc *fdp, int
 		newfde = &fdp->fd_ofiles[indx];
 		oldfde = &fdp->fd_ofiles[dfd];
 #ifdef CAPABILITIES
-		seq_write_begin(&newfde->fde_seq);
+		seqc_write_begin(&newfde->fde_seqc);
 #endif
 		memcpy(newfde, oldfde, fde_change_size);
 		oldfde->fde_file = NULL;
 		fdunused(fdp, dfd);
 #ifdef CAPABILITIES
-		seq_write_end(&newfde->fde_seq);
+		seqc_write_end(&newfde->fde_seqc);
 #endif
 		break;
 	}

Modified: head/sys/sys/filedesc.h
==============================================================================
--- head/sys/sys/filedesc.h	Wed Feb 27 22:42:29 2019	(r344647)
+++ head/sys/sys/filedesc.h	Wed Feb 27 22:56:55 2019	(r344648)
@@ -40,7 +40,7 @@
 #include <sys/event.h>
 #include <sys/lock.h>
 #include <sys/priority.h>
-#include <sys/seq.h>
+#include <sys/seqc.h>
 #include <sys/sx.h>
 
 #include <machine/_limits.h>
@@ -56,19 +56,19 @@ struct filedescent {
 	struct file	*fde_file;	/* file structure for open file */
 	struct filecaps	 fde_caps;	/* per-descriptor rights */
 	uint8_t		 fde_flags;	/* per-process open file flags */
-	seq_t		 fde_seq;	/* keep file and caps in sync */
+	seqc_t		 fde_seqc;	/* keep file and caps in sync */
 };
 #define	fde_rights	fde_caps.fc_rights
 #define	fde_fcntls	fde_caps.fc_fcntls
 #define	fde_ioctls	fde_caps.fc_ioctls
 #define	fde_nioctls	fde_caps.fc_nioctls
-#define	fde_change_size	(offsetof(struct filedescent, fde_seq))
+#define	fde_change_size	(offsetof(struct filedescent, fde_seqc))
 
 struct fdescenttbl {
 	int	fdt_nfiles;		/* number of open files allocated */
 	struct	filedescent fdt_ofiles[0];	/* open files */
 };
-#define	fd_seq(fdt, fd)	(&(fdt)->fdt_ofiles[(fd)].fde_seq)
+#define	fd_seqc(fdt, fd)	(&(fdt)->fdt_ofiles[(fd)].fde_seqc)
 
 /*
  * This structure is used for the management of descriptors.  It may be
@@ -205,7 +205,7 @@ int	fget_cap(struct thread *td, int fd, cap_rights_t *
 
 /* Return a referenced file from an unlocked descriptor. */
 int	fget_unlocked(struct filedesc *fdp, int fd, cap_rights_t *needrightsp,
-	    struct file **fpp, seq_t *seqp);
+	    struct file **fpp, seqc_t *seqp);
 
 /* Requires a FILEDESC_{S,X}LOCK held and returns without a ref. */
 static __inline struct file *
@@ -239,10 +239,10 @@ fdeget_locked(struct filedesc *fdp, int fd)
 
 #ifdef CAPABILITIES
 static __inline bool
-fd_modified(struct filedesc *fdp, int fd, seq_t seq)
+fd_modified(struct filedesc *fdp, int fd, seqc_t seqc)
 {
 
-	return (!seq_consistent(fd_seq(fdp->fd_files, fd), seq));
+	return (!seqc_consistent(fd_seqc(fdp->fd_files, fd), seqc));
 }
 #endif
 

Added: head/sys/sys/seqc.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/sys/seqc.h	Wed Feb 27 22:56:55 2019	(r344648)
@@ -0,0 +1,156 @@
+/*-
+ * Copyright (c) 2014 Mateusz Guzik <mjg@FreeBSD.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _SYS_SEQC_H_
+#define _SYS_SEQC_H_
+
+#ifdef _KERNEL
+#include <sys/systm.h>
+#endif
+#include <sys/types.h>
+
+/*
+ * seqc_t may be included in structs visible to userspace
+ */
+typedef uint32_t seqc_t;
+
+#ifdef _KERNEL
+
+/*
+ * seqc allows readers and writers to work with a consistent snapshot. Modifying
+ * operations must be enclosed within a transaction delineated by
+ * seqc_write_beg/seqc_write_end. The trick works by having the writer increment
+ * the seqcuence number twice, at the beginning and end of the transaction.
+ * The reader detects that the seqcuence number has not changed between its start
+ * and end, and that the seqcuence number is even, to validate consistency.
+ *
+ * Some fencing (both hard fencing and compiler barriers) may be needed,
+ * depending on the cpu. Modern AMD cpus provide strong enough guarantees to not
+ * require any fencing by the reader or writer.
+ *
+ * Example usage:
+ *
+ * writers:
+ *     lock_exclusive(&obj->lock);
+ *     seqc_write_begin(&obj->seqc);
+ *     obj->var1 = ...;
+ *     obj->var2 = ...;
+ *     seqc_write_end(&obj->seqc);
+ *     unlock_exclusive(&obj->lock);
+ *
+ * readers:
+ *    int var1, var2;
+ *    seqc_t seqc;
+ *
+ *    for (;;) {
+ *    	      seqc = seqc_read(&obj->seqc);
+ *            var1 = obj->var1;
+ *            var2 = obj->var2;
+ *            if (seqc_consistent(&obj->seqc, seqc))
+ *                   break;
+ *    }
+ *    .....
+ *
+ * Writers may not block or sleep in any way.
+ *
+ * There are 2 minor caveats in this implementation:
+ *
+ * 1. There is no guarantee of progress. That is, a large number of writers can
+ * interfere with the execution of the readers and cause the code to live-lock
+ * in a loop trying to acquire a consistent snapshot.
+ *
+ * 2. If the reader loops long enough, the counter may overflow and eventually
+ * wrap back to its initial value, fooling the reader into accepting the
+ * snapshot.  Given that this needs 4 billion transactional writes across a
+ * single contended reader, it is unlikely to ever happen.
+ */		
+
+/* A hack to get MPASS macro */
+#include <sys/lock.h>
+
+#include <machine/cpu.h>
+
+static __inline bool
+seqc_in_modify(seqc_t seqcp)
+{
+
+	return (seqcp & 1);
+}
+
+static __inline void
+seqc_write_begin(seqc_t *seqcp)
+{
+
+	critical_enter();
+	MPASS(!seqc_in_modify(*seqcp));
+	*seqcp += 1;
+	atomic_thread_fence_rel();
+}
+
+static __inline void
+seqc_write_end(seqc_t *seqcp)
+{
+
+	atomic_store_rel_int(seqcp, *seqcp + 1);
+	MPASS(!seqc_in_modify(*seqcp));
+	critical_exit();
+}
+
+static __inline seqc_t
+seqc_read(const seqc_t *seqcp)
+{
+	seqc_t ret;
+
+	for (;;) {
+		ret = atomic_load_acq_int(__DECONST(seqc_t *, seqcp));
+		if (seqc_in_modify(ret)) {
+			cpu_spinwait();
+			continue;
+		}
+		break;
+	}
+
+	return (ret);
+}
+
+static __inline seqc_t
+seqc_consistent_nomb(const seqc_t *seqcp, seqc_t oldseqc)
+{
+
+	return (*seqcp == oldseqc);
+}
+
+static __inline seqc_t
+seqc_consistent(const seqc_t *seqcp, seqc_t oldseqc)
+{
+
+	atomic_thread_fence_acq();
+	return (seqc_consistent_nomb(seqcp, oldseqc));
+}
+
+#endif	/* _KERNEL */
+#endif	/* _SYS_SEQC_H_ */



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201902272256.x1RMutdK085216>