summaryrefslogtreecommitdiffstats
path: root/freebsd/sys/sys
diff options
context:
space:
mode:
Diffstat (limited to 'freebsd/sys/sys')
-rw-r--r--freebsd/sys/sys/_bitset.h58
-rw-r--r--freebsd/sys/sys/_callout.h10
-rw-r--r--freebsd/sys/sys/_cpuset.h50
-rw-r--r--freebsd/sys/sys/_mutex.h26
-rw-r--r--freebsd/sys/sys/_pctrie.h51
-rw-r--r--freebsd/sys/sys/_rmlock.h14
-rw-r--r--freebsd/sys/sys/_rwlock.h26
-rw-r--r--freebsd/sys/sys/_task.h21
-rw-r--r--freebsd/sys/sys/_unrhdr.h51
-rw-r--r--freebsd/sys/sys/acl.h3
-rw-r--r--freebsd/sys/sys/aio.h148
-rw-r--r--freebsd/sys/sys/ata.h392
-rw-r--r--freebsd/sys/sys/bitset.h208
-rw-r--r--freebsd/sys/sys/bitstring.h364
-rw-r--r--freebsd/sys/sys/buf.h117
-rw-r--r--freebsd/sys/sys/buf_ring.h127
-rw-r--r--freebsd/sys/sys/bufobj.h36
-rw-r--r--freebsd/sys/sys/bus.h214
-rw-r--r--freebsd/sys/sys/bus_dma.h29
-rw-r--r--freebsd/sys/sys/callout.h76
-rw-r--r--freebsd/sys/sys/capability.h178
-rw-r--r--freebsd/sys/sys/caprights.h61
-rw-r--r--freebsd/sys/sys/capsicum.h450
-rw-r--r--freebsd/sys/sys/condvar.h21
-rw-r--r--freebsd/sys/sys/conf.h144
-rw-r--r--freebsd/sys/sys/counter.h63
-rw-r--r--freebsd/sys/sys/cpu.h16
-rw-r--r--freebsd/sys/sys/domain.h14
-rw-r--r--freebsd/sys/sys/eventhandler.h31
-rw-r--r--freebsd/sys/sys/eventvar.h1
-rw-r--r--freebsd/sys/sys/fail.h366
-rw-r--r--freebsd/sys/sys/file.h129
-rw-r--r--freebsd/sys/sys/filedesc.h144
-rw-r--r--freebsd/sys/sys/fnv_hash.h2
-rw-r--r--freebsd/sys/sys/gpio.h108
-rw-r--r--freebsd/sys/sys/hash.h13
-rw-r--r--freebsd/sys/sys/hhook.h3
-rw-r--r--freebsd/sys/sys/interrupt.h8
-rw-r--r--freebsd/sys/sys/jail.h34
-rw-r--r--freebsd/sys/sys/kernel.h75
-rw-r--r--freebsd/sys/sys/khelp.h1
-rw-r--r--freebsd/sys/sys/kobj.h12
-rw-r--r--freebsd/sys/sys/kthread.h6
-rw-r--r--freebsd/sys/sys/ktr.h101
-rw-r--r--freebsd/sys/sys/ktr_class.h87
-rw-r--r--freebsd/sys/sys/libkern.h84
-rw-r--r--freebsd/sys/sys/linker.h10
-rw-r--r--freebsd/sys/sys/linker_set.h27
-rw-r--r--freebsd/sys/sys/lockmgr.h12
-rw-r--r--freebsd/sys/sys/lockstat.h225
-rw-r--r--freebsd/sys/sys/loginclass.h3
-rw-r--r--freebsd/sys/sys/malloc.h17
-rw-r--r--freebsd/sys/sys/mbuf.h1077
-rw-r--r--freebsd/sys/sys/module.h58
-rw-r--r--freebsd/sys/sys/mount.h140
-rw-r--r--freebsd/sys/sys/mutex.h191
-rw-r--r--freebsd/sys/sys/nlist_aout.h2
-rw-r--r--freebsd/sys/sys/osd.h8
-rw-r--r--freebsd/sys/sys/pcpu.h56
-rwxr-xr-xfreebsd/sys/sys/pipe.h11
-rw-r--r--freebsd/sys/sys/priv.h32
-rw-r--r--freebsd/sys/sys/proc.h284
-rw-r--r--freebsd/sys/sys/protosw.h34
-rw-r--r--freebsd/sys/sys/racct.h112
-rw-r--r--freebsd/sys/sys/random.h89
-rw-r--r--freebsd/sys/sys/reboot.h1
-rw-r--r--freebsd/sys/sys/refcount.h10
-rw-r--r--freebsd/sys/sys/resourcevar.h39
-rw-r--r--freebsd/sys/sys/rman.h57
-rw-r--r--freebsd/sys/sys/rmlock.h30
-rw-r--r--freebsd/sys/sys/rwlock.h101
-rw-r--r--freebsd/sys/sys/sbuf.h14
-rw-r--r--freebsd/sys/sys/sdt.h4
-rw-r--r--freebsd/sys/sys/seq.h129
-rw-r--r--freebsd/sys/sys/sf_buf.h169
-rw-r--r--freebsd/sys/sys/signalvar.h403
-rw-r--r--freebsd/sys/sys/sleepqueue.h13
-rw-r--r--freebsd/sys/sys/smp.h78
-rw-r--r--freebsd/sys/sys/sockbuf.h158
-rw-r--r--freebsd/sys/sys/socket.h116
-rw-r--r--freebsd/sys/sys/socketvar.h63
-rw-r--r--freebsd/sys/sys/stdint.h13
-rw-r--r--freebsd/sys/sys/sx.h47
-rw-r--r--freebsd/sys/sys/sysctl.h796
-rw-r--r--freebsd/sys/sys/syslog.h4
-rw-r--r--freebsd/sys/sys/sysproto.h324
-rw-r--r--freebsd/sys/sys/systm.h175
-rw-r--r--freebsd/sys/sys/taskqueue.h23
-rw-r--r--freebsd/sys/sys/tree.h86
-rw-r--r--freebsd/sys/sys/tty.h7
-rw-r--r--freebsd/sys/sys/ttydevsw.h41
-rw-r--r--freebsd/sys/sys/ucred.h10
-rw-r--r--freebsd/sys/sys/unpcb.h17
-rw-r--r--freebsd/sys/sys/user.h63
-rw-r--r--freebsd/sys/sys/uuid.h85
-rw-r--r--freebsd/sys/sys/vmmeter.h61
-rw-r--r--freebsd/sys/sys/vnode.h161
97 files changed, 7289 insertions, 2570 deletions
diff --git a/freebsd/sys/sys/_bitset.h b/freebsd/sys/sys/_bitset.h
new file mode 100644
index 00000000..2f5301d5
--- /dev/null
+++ b/freebsd/sys/sys/_bitset.h
@@ -0,0 +1,58 @@
+/*-
+ * Copyright (c) 2008, Jeffrey Roberson <jeff@freebsd.org>
+ * All rights reserved.
+ *
+ * Copyright (c) 2008 Nokia Corporation
+ * All rights reserved.
+ *
+ * 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 unmodified, 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 ``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 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__BITSET_H_
+#define _SYS__BITSET_H_
+
+/*
+ * Macros addressing word and bit within it, tuned to make compiler
+ * optimize cases when SETSIZE fits into single machine word.
+ */
+#define _BITSET_BITS (sizeof(long) * 8)
+
+#define __howmany(x, y) (((x) + ((y) - 1)) / (y))
+
+#define __bitset_words(_s) (__howmany(_s, _BITSET_BITS))
+
+#define BITSET_DEFINE(t, _s) \
+struct t { \
+ long __bits[__bitset_words((_s))]; \
+}
+
+/*
+ * Helper to declare a bitset without it's size being a constant.
+ *
+ * Sadly we cannot declare a bitset struct with '__bits[]', because it's
+ * the only member of the struct and the compiler complains.
+ */
+#define BITSET_DEFINE_VAR(t) BITSET_DEFINE(t, 1)
+
+#endif /* !_SYS__BITSET_H_ */
diff --git a/freebsd/sys/sys/_callout.h b/freebsd/sys/sys/_callout.h
index b8c3ce92..a9134c8d 100644
--- a/freebsd/sys/sys/_callout.h
+++ b/freebsd/sys/sys/_callout.h
@@ -42,19 +42,23 @@
struct lock_object;
-SLIST_HEAD(callout_list, callout);
+LIST_HEAD(callout_list, callout);
+SLIST_HEAD(callout_slist, callout);
TAILQ_HEAD(callout_tailq, callout);
struct callout {
union {
+ LIST_ENTRY(callout) le;
SLIST_ENTRY(callout) sle;
TAILQ_ENTRY(callout) tqe;
} c_links;
- int c_time; /* ticks to the event */
+ sbintime_t c_time; /* ticks to the event */
+ sbintime_t c_precision; /* delta allowed wrt opt */
void *c_arg; /* function argument */
void (*c_func)(void *); /* function to call */
struct lock_object *c_lock; /* lock to handle */
- int c_flags; /* state of this entry */
+ short c_flags; /* User State */
+ short c_iflags; /* Internal State */
volatile int c_cpu; /* CPU we're scheduled on */
};
diff --git a/freebsd/sys/sys/_cpuset.h b/freebsd/sys/sys/_cpuset.h
new file mode 100644
index 00000000..1ddafac2
--- /dev/null
+++ b/freebsd/sys/sys/_cpuset.h
@@ -0,0 +1,50 @@
+/*-
+ * Copyright (c) 2008, Jeffrey Roberson <jeff@freebsd.org>
+ * All rights reserved.
+ *
+ * Copyright (c) 2008 Nokia Corporation
+ * All rights reserved.
+ *
+ * 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 unmodified, 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 ``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 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__CPUSET_H_
+#define _SYS__CPUSET_H_
+
+#include <sys/_bitset.h>
+
+#ifdef _KERNEL
+#define CPU_SETSIZE MAXCPU
+#endif
+
+#define CPU_MAXSIZE 256
+
+#ifndef CPU_SETSIZE
+#define CPU_SETSIZE CPU_MAXSIZE
+#endif
+
+BITSET_DEFINE(_cpuset, CPU_SETSIZE);
+typedef struct _cpuset cpuset_t;
+
+#endif /* !_SYS__CPUSET_H_ */
diff --git a/freebsd/sys/sys/_mutex.h b/freebsd/sys/sys/_mutex.h
index 2f4a674e..96f53238 100644
--- a/freebsd/sys/sys/_mutex.h
+++ b/freebsd/sys/sys/_mutex.h
@@ -34,8 +34,16 @@
#include <machine/rtems-bsd-mutex.h>
#endif /* __rtems__ */
+#include <machine/param.h>
+
/*
* Sleep/spin mutex.
+ *
+ * All mutex implementations must always have a member called mtx_lock.
+ * Other locking primitive structures are not allowed to use this name
+ * for their members.
+ * If this rule needs to change, the bits in the mutex implementation must
+ * be modified appropriately.
*/
struct mtx {
struct lock_object lock_object; /* Common lock properties. */
@@ -46,4 +54,22 @@ struct mtx {
#endif /* __rtems__ */
};
+/*
+ * Members of struct mtx_padalign must mirror members of struct mtx.
+ * mtx_padalign mutexes can use the mtx(9) API transparently without
+ * modification.
+ * Pad-aligned mutexes used within structures should generally be the
+ * first member of the struct. Otherwise, the compiler can generate
+ * additional padding for the struct to keep a correct alignment for
+ * the mutex.
+ */
+#ifndef __rtems__
+struct mtx_padalign {
+ struct lock_object lock_object; /* Common lock properties. */
+ volatile uintptr_t mtx_lock; /* Owner and flags. */
+} __aligned(CACHE_LINE_SIZE);
+#else /* __rtems__ */
+#define mtx_padalign mtx
+#endif /* __rtems__ */
+
#endif /* !_SYS__MUTEX_H_ */
diff --git a/freebsd/sys/sys/_pctrie.h b/freebsd/sys/sys/_pctrie.h
new file mode 100644
index 00000000..45f69b20
--- /dev/null
+++ b/freebsd/sys/sys/_pctrie.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2013 EMC Corp.
+ * Copyright (c) 2011 Jeffrey Roberson <jeff@freebsd.org>
+ * Copyright (c) 2008 Mayur Shardul <mayur.shardul@gmail.com>
+ * All rights reserved.
+ *
+ * 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_PCTRIE_H_
+#define __SYS_PCTRIE_H_
+
+/*
+ * Radix tree root.
+ */
+struct pctrie {
+ uintptr_t pt_root;
+};
+
+#ifdef _KERNEL
+
+static __inline boolean_t
+pctrie_is_empty(struct pctrie *ptree)
+{
+
+ return (ptree->pt_root == 0);
+}
+
+#endif /* _KERNEL */
+#endif /* !__SYS_PCTRIE_H_ */
diff --git a/freebsd/sys/sys/_rmlock.h b/freebsd/sys/sys/_rmlock.h
index 46672bb2..adc2bc56 100644
--- a/freebsd/sys/sys/_rmlock.h
+++ b/freebsd/sys/sys/_rmlock.h
@@ -32,17 +32,17 @@
#ifndef _SYS__RMLOCK_H_
#define _SYS__RMLOCK_H_
-/*
- * XXXUPS remove as soon as we have per cpu variable
- * linker sets and can define rm_queue in _rm_lock.h
-*/
-#include <sys/pcpu.h>
/*
* Mostly reader/occasional writer lock.
*/
LIST_HEAD(rmpriolist,rm_priotracker);
+struct rm_queue {
+ struct rm_queue *volatile rmq_next;
+ struct rm_queue *volatile rmq_prev;
+};
+
#ifndef __rtems__
struct rmlock {
struct lock_object lock_object;
@@ -59,8 +59,8 @@ struct rmlock {
#define rm_lock_mtx _rm_lock._rm_lock_mtx
#define rm_lock_sx _rm_lock._rm_lock_sx
#else /* __rtems__ */
-#include <sys/rwlock.h>
-#define rmlock rwlock
+#include <sys/_rwlock.h>
+#define rmlock rwlock
#endif /* __rtems__ */
struct rm_priotracker {
diff --git a/freebsd/sys/sys/_rwlock.h b/freebsd/sys/sys/_rwlock.h
index 95b21283..029fb98b 100644
--- a/freebsd/sys/sys/_rwlock.h
+++ b/freebsd/sys/sys/_rwlock.h
@@ -32,8 +32,16 @@
#include <machine/rtems-bsd-mutex.h>
#endif /* __rtems__ */
+#include <machine/param.h>
+
/*
* Reader/writer lock.
+ *
+ * All reader/writer lock implementations must always have a member
+ * called rw_lock. Other locking primitive structures are not allowed to
+ * use this name for their members.
+ * If this rule needs to change, the bits in the reader/writer lock
+ * implementation must be modified appropriately.
*/
struct rwlock {
struct lock_object lock_object;
@@ -44,4 +52,22 @@ struct rwlock {
#endif /* __rtems__ */
};
+#ifndef __rtems__
+/*
+ * Members of struct rwlock_padalign must mirror members of struct rwlock.
+ * rwlock_padalign rwlocks can use the rwlock(9) API transparently without
+ * modification.
+ * Pad-aligned rwlocks used within structures should generally be the
+ * first member of the struct. Otherwise, the compiler can generate
+ * additional padding for the struct to keep a correct alignment for
+ * the rwlock.
+ */
+struct rwlock_padalign {
+ struct lock_object lock_object;
+ volatile uintptr_t rw_lock;
+} __aligned(CACHE_LINE_SIZE);
+#else /* __rtems__ */
+#define rwlock_padalign rwlock
+#endif /* __rtems__ */
+
#endif /* !_SYS__RWLOCK_H_ */
diff --git a/freebsd/sys/sys/_task.h b/freebsd/sys/sys/_task.h
index 11fd1bc0..d3be7198 100644
--- a/freebsd/sys/sys/_task.h
+++ b/freebsd/sys/sys/_task.h
@@ -42,13 +42,32 @@
* (q) taskqueue lock
*/
typedef void task_fn_t(void *context, int pending);
+typedef void gtask_fn_t(void *context);
struct task {
STAILQ_ENTRY(task) ta_link; /* (q) link for queue */
- u_short ta_pending; /* (q) count times queued */
+ uint16_t ta_pending; /* (q) count times queued */
u_short ta_priority; /* (c) Priority */
task_fn_t *ta_func; /* (c) task handler */
void *ta_context; /* (c) argument for handler */
};
+struct gtask {
+ STAILQ_ENTRY(gtask) ta_link; /* (q) link for queue */
+ uint16_t ta_flags; /* (q) state flags */
+ u_short ta_priority; /* (c) Priority */
+ gtask_fn_t *ta_func; /* (c) task handler */
+ void *ta_context; /* (c) argument for handler */
+};
+
+struct grouptask {
+ struct gtask gt_task;
+ void *gt_taskqueue;
+ LIST_ENTRY(grouptask) gt_list;
+ void *gt_uniq;
+ char *gt_name;
+ int16_t gt_irq;
+ int16_t gt_cpu;
+};
+
#endif /* !_SYS__TASK_H_ */
diff --git a/freebsd/sys/sys/_unrhdr.h b/freebsd/sys/sys/_unrhdr.h
new file mode 100644
index 00000000..f3c25d16
--- /dev/null
+++ b/freebsd/sys/sys/_unrhdr.h
@@ -0,0 +1,51 @@
+/*-
+ * Copyright (c) 2004 Poul-Henning Kamp
+ * All rights reserved.
+ *
+ * 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_UNRHDR_H
+#define _SYS_UNRHDR_H
+
+#include <sys/queue.h>
+
+struct mtx;
+
+/* Header element for a unr number space. */
+
+struct unrhdr {
+ TAILQ_HEAD(unrhd,unr) head;
+ u_int low; /* Lowest item */
+ u_int high; /* Highest item */
+ u_int busy; /* Count of allocated items */
+ u_int alloc; /* Count of memory allocations */
+ u_int first; /* items in allocated from start */
+ u_int last; /* items free at end */
+ struct mtx *mtx;
+ TAILQ_HEAD(unrfr,unr) ppfree; /* Items to be freed after mtx
+ lock dropped */
+};
+
+#endif
diff --git a/freebsd/sys/sys/acl.h b/freebsd/sys/sys/acl.h
index 77ebf89d..21b3e381 100644
--- a/freebsd/sys/sys/acl.h
+++ b/freebsd/sys/sys/acl.h
@@ -249,11 +249,12 @@ typedef void *acl_t;
#define ACL_ENTRY_INHERIT_ONLY 0x0008
#define ACL_ENTRY_SUCCESSFUL_ACCESS 0x0010
#define ACL_ENTRY_FAILED_ACCESS 0x0020
+#define ACL_ENTRY_INHERITED 0x0080
#define ACL_FLAGS_BITS (ACL_ENTRY_FILE_INHERIT | \
ACL_ENTRY_DIRECTORY_INHERIT | ACL_ENTRY_NO_PROPAGATE_INHERIT | \
ACL_ENTRY_INHERIT_ONLY | ACL_ENTRY_SUCCESSFUL_ACCESS | \
- ACL_ENTRY_FAILED_ACCESS)
+ ACL_ENTRY_FAILED_ACCESS | ACL_ENTRY_INHERITED)
/*
* Undefined value in ae_id field. ae_id should be set to this value
diff --git a/freebsd/sys/sys/aio.h b/freebsd/sys/sys/aio.h
index 02e34a85..ab6f766f 100644
--- a/freebsd/sys/sys/aio.h
+++ b/freebsd/sys/sys/aio.h
@@ -21,6 +21,11 @@
#include <sys/types.h>
#include <sys/signal.h>
+#ifdef _KERNEL
+#include <sys/queue.h>
+#include <sys/event.h>
+#include <sys/signalvar.h>
+#endif
/*
* Returned by aio_cancel:
@@ -37,6 +42,7 @@
#define LIO_READ 0x2
#ifdef _KERNEL
#define LIO_SYNC 0x3
+#define LIO_MLOCK 0x4
#endif
/*
@@ -45,10 +51,30 @@
#define LIO_NOWAIT 0x0
#define LIO_WAIT 0x1
+#ifndef __rtems__
/*
* Maximum number of allowed LIO operations
*/
#define AIO_LISTIO_MAX 16
+#endif /* __rtems__ */
+
+#ifdef _KERNEL
+
+/* Default values of tunables for the AIO worker pool. */
+
+#ifndef MAX_AIO_PROCS
+#define MAX_AIO_PROCS 32
+#endif
+
+#ifndef TARGET_AIO_PROCS
+#define TARGET_AIO_PROCS 4
+#endif
+
+#ifndef AIOD_LIFETIME_DEFAULT
+#define AIOD_LIFETIME_DEFAULT (30 * hz)
+#endif
+
+#endif
/*
* Private members for aiocb -- don't access
@@ -78,7 +104,105 @@ typedef struct aiocb {
#endif
} aiocb_t;
-#ifndef _KERNEL
+#ifdef _KERNEL
+
+typedef void aio_cancel_fn_t(struct kaiocb *);
+typedef void aio_handle_fn_t(struct kaiocb *);
+
+/*
+ * Kernel version of an I/O control block.
+ *
+ * Locking key:
+ * * - need not protected
+ * a - locked by kaioinfo lock
+ * b - locked by backend lock
+ * c - locked by aio_job_mtx
+ */
+struct kaiocb {
+ TAILQ_ENTRY(kaiocb) list; /* (b) backend-specific list of jobs */
+ TAILQ_ENTRY(kaiocb) plist; /* (a) lists of pending / done jobs */
+ TAILQ_ENTRY(kaiocb) allist; /* (a) list of all jobs in proc */
+ int jobflags; /* (a) job flags */
+ int inblock; /* (*) input blocks */
+ int outblock; /* (*) output blocks */
+ int msgsnd; /* (*) messages sent */
+ int msgrcv; /* (*) messages received */
+ struct proc *userproc; /* (*) user process */
+ struct ucred *cred; /* (*) active credential when created */
+ struct file *fd_file; /* (*) pointer to file structure */
+ struct aioliojob *lio; /* (*) optional lio job */
+ struct aiocb *ujob; /* (*) pointer in userspace of aiocb */
+ struct knlist klist; /* (a) list of knotes */
+ struct aiocb uaiocb; /* (*) copy of user I/O control block */
+ ksiginfo_t ksi; /* (a) realtime signal info */
+ uint64_t seqno; /* (*) job number */
+ aio_cancel_fn_t *cancel_fn; /* (a) backend cancel function */
+ aio_handle_fn_t *handle_fn; /* (c) backend handle function */
+ union { /* Backend-specific data fields */
+ struct { /* BIO backend */
+ struct bio *bp; /* (*) BIO pointer */
+ struct buf *pbuf; /* (*) buffer pointer */
+ struct vm_page *pages[btoc(MAXPHYS)+1]; /* (*) */
+ int npages; /* (*) number of pages */
+ };
+ struct { /* fsync() requests */
+ int pending; /* (a) number of pending I/O */
+ };
+ struct {
+ void *backend1;
+ void *backend2;
+ long backend3;
+ int backend4;
+ };
+ };
+};
+
+struct socket;
+struct sockbuf;
+
+/*
+ * AIO backends should permit cancellation of queued requests waiting to
+ * be serviced by installing a cancel routine while the request is
+ * queued. The cancellation routine should dequeue the request if
+ * necessary and cancel it. Care must be used to handle races between
+ * queueing and dequeueing requests and cancellation.
+ *
+ * When queueing a request somewhere such that it can be cancelled, the
+ * caller should:
+ *
+ * 1) Acquire lock that protects the associated queue.
+ * 2) Call aio_set_cancel_function() to install the cancel routine.
+ * 3) If that fails, the request has a pending cancel and should be
+ * cancelled via aio_cancel().
+ * 4) Queue the request.
+ *
+ * When dequeueing a request to service it or hand it off to somewhere else,
+ * the caller should:
+ *
+ * 1) Acquire the lock that protects the associated queue.
+ * 2) Dequeue the request.
+ * 3) Call aio_clear_cancel_function() to clear the cancel routine.
+ * 4) If that fails, the cancel routine is about to be called. The
+ * caller should ignore the request.
+ *
+ * The cancel routine should:
+ *
+ * 1) Acquire the lock that protects the associated queue.
+ * 2) Call aio_cancel_cleared() to determine if the request is already
+ * dequeued due to a race with dequeueing thread.
+ * 3) If that fails, dequeue the request.
+ * 4) Cancel the request via aio_cancel().
+ */
+
+bool aio_cancel_cleared(struct kaiocb *job);
+void aio_cancel(struct kaiocb *job);
+bool aio_clear_cancel_function(struct kaiocb *job);
+void aio_complete(struct kaiocb *job, long status, int error);
+void aio_schedule(struct kaiocb *job, aio_handle_fn_t *func);
+bool aio_set_cancel_function(struct kaiocb *job, aio_cancel_fn_t *func);
+void aio_switch_vmspace(struct kaiocb *job);
+
+#else /* !_KERNEL */
struct timespec;
@@ -99,7 +223,8 @@ int aio_write(struct aiocb *);
* "acb_list" is an array of "nacb_listent" I/O control blocks.
* when all I/Os are complete, the optional signal "sig" is sent.
*/
-int lio_listio(int, struct aiocb * const [], int, struct sigevent *);
+int lio_listio(int, struct aiocb *__restrict const *__restrict, int,
+ struct sigevent *);
/*
* Get completion status
@@ -126,21 +251,18 @@ int aio_cancel(int, struct aiocb *);
*/
int aio_suspend(const struct aiocb * const[], int, const struct timespec *);
+/*
+ * Asynchronous mlock
+ */
+int aio_mlock(struct aiocb *);
+
#ifdef __BSD_VISIBLE
-int aio_waitcomplete(struct aiocb **, struct timespec *);
+ssize_t aio_waitcomplete(struct aiocb **, struct timespec *);
#endif
int aio_fsync(int op, struct aiocb *aiocbp);
__END_DECLS
-#else
+#endif /* !_KERNEL */
-/* Forward declarations for prototypes below. */
-struct socket;
-struct sockbuf;
-
-extern void (*aio_swake)(struct socket *, struct sockbuf *);
-
-#endif
-
-#endif
+#endif /* !_SYS_AIO_H_ */
diff --git a/freebsd/sys/sys/ata.h b/freebsd/sys/sys/ata.h
index f46dd50c..72104140 100644
--- a/freebsd/sys/sys/ata.h
+++ b/freebsd/sys/sys/ata.h
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2000 - 2008 Søren Schmidt <sos@FreeBSD.org>
+ * Copyright (c) 2000 - 2008 Søren Schmidt <sos@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -105,6 +105,10 @@ struct ata_params {
/*069*/ u_int16_t support3;
#define ATA_SUPPORT_RZAT 0x0020
#define ATA_SUPPORT_DRAT 0x4000
+#define ATA_SUPPORT_ZONE_MASK 0x0003
+#define ATA_SUPPORT_ZONE_NR 0x0000
+#define ATA_SUPPORT_ZONE_HOST_AWARE 0x0001
+#define ATA_SUPPORT_ZONE_DEV_MANAGED 0x0002
u_int16_t reserved70;
/*071*/ u_int16_t rlsovlap; /* rel time (us) for overlap */
/*072*/ u_int16_t rlsservice; /* rel time (us) for service */
@@ -228,7 +232,14 @@ struct ata_params {
#define ATA_SUPPORT_RWLOGDMAEXT 0x0008
#define ATA_SUPPORT_MICROCODE3 0x0010
#define ATA_SUPPORT_FREEFALL 0x0020
+#define ATA_SUPPORT_SENSE_REPORT 0x0040
+#define ATA_SUPPORT_EPC 0x0080
/*120*/ u_int16_t enabled2;
+#define ATA_ENABLED_WRITEREADVERIFY 0x0002
+#define ATA_ENABLED_WRITEUNCORREXT 0x0004
+#define ATA_ENABLED_FREEFALL 0x0020
+#define ATA_ENABLED_SENSE_REPORT 0x0040
+#define ATA_ENABLED_EPC 0x0080
u_int16_t reserved121[6];
/*127*/ u_int16_t removable_status;
/*128*/ u_int16_t security_status;
@@ -262,6 +273,8 @@ struct ata_params {
/*215*/ u_int16_t nv_cache_size_1;
u_int16_t nv_cache_size_2;
/*217*/ u_int16_t media_rotation_rate;
+#define ATA_RATE_NOT_REPORTED 0x0000
+#define ATA_RATE_NON_ROTATING 0x0001
u_int16_t reserved218;
/*219*/ u_int16_t nv_cache_opt;
/*220*/ u_int16_t wrv_mode;
@@ -296,8 +309,14 @@ struct ata_params {
#define ATA_MAX_28BIT_LBA 268435455UL
/* ATA Status Register */
-#define ATA_STATUS_ERROR 0x01
-#define ATA_STATUS_DEVICE_FAULT 0x20
+#define ATA_STATUS_ERROR 0x01
+#define ATA_STATUS_SENSE_AVAIL 0x02
+#define ATA_STATUS_ALIGN_ERR 0x04
+#define ATA_STATUS_DATA_REQ 0x08
+#define ATA_STATUS_DEF_WRITE_ERR 0x10
+#define ATA_STATUS_DEVICE_FAULT 0x20
+#define ATA_STATUS_DEVICE_READY 0x40
+#define ATA_STATUS_BUSY 0x80
/* ATA Error Register */
#define ATA_ERROR_ABORT 0x04
@@ -333,6 +352,7 @@ struct ata_params {
#define ATA_UDMA6 0x46
#define ATA_SA150 0x47
#define ATA_SA300 0x48
+#define ATA_SA600 0x49
#define ATA_DMA_MAX 0x4f
@@ -365,13 +385,36 @@ struct ata_params {
#define ATA_WRITE_LOG_EXT 0x3f
#define ATA_READ_VERIFY 0x40
#define ATA_READ_VERIFY48 0x42
+#define ATA_WRITE_UNCORRECTABLE48 0x45 /* write uncorrectable 48bit LBA */
+#define ATA_WU_PSEUDO 0x55 /* pseudo-uncorrectable error */
+#define ATA_WU_FLAGGED 0xaa /* flagged-uncorrectable error */
#define ATA_READ_LOG_DMA_EXT 0x47 /* read log DMA ext - PIO Data-In */
+#define ATA_ZAC_MANAGEMENT_IN 0x4a /* ZAC management in */
+#define ATA_ZM_REPORT_ZONES 0x00 /* report zones */
#define ATA_READ_FPDMA_QUEUED 0x60 /* read DMA NCQ */
#define ATA_WRITE_FPDMA_QUEUED 0x61 /* write DMA NCQ */
+#define ATA_NCQ_NON_DATA 0x63 /* NCQ non-data command */
+#define ATA_ABORT_NCQ_QUEUE 0x00 /* abort NCQ queue */
+#define ATA_DEADLINE_HANDLING 0x01 /* deadline handling */
+#define ATA_SET_FEATURES 0x05 /* set features */
+#define ATA_ZERO_EXT 0x06 /* zero ext */
+#define ATA_NCQ_ZAC_MGMT_OUT 0x07 /* NCQ ZAC mgmt out no data */
#define ATA_SEND_FPDMA_QUEUED 0x64 /* send DMA NCQ */
-#define ATA_RECV_FPDMA_QUEUED 0x65 /* recieve DMA NCQ */
+#define ATA_SFPDMA_DSM 0x00 /* Data set management */
+#define ATA_SFPDMA_DSM_TRIM 0x01 /* Set trim bit in auxiliary */
+#define ATA_SFPDMA_HYBRID_EVICT 0x01 /* Hybrid Evict */
+#define ATA_SFPDMA_WLDMA 0x02 /* Write Log DMA EXT */
+#define ATA_SFPDMA_ZAC_MGMT_OUT 0x03 /* NCQ ZAC mgmt out w/data */
+#define ATA_RECV_FPDMA_QUEUED 0x65 /* receive DMA NCQ */
+#define ATA_RFPDMA_RL_DMA_EXT 0x00 /* Read Log DMA EXT */
+#define ATA_RFPDMA_ZAC_MGMT_IN 0x02 /* NCQ ZAC mgmt in w/data */
#define ATA_SEP_ATTN 0x67 /* SEP request */
#define ATA_SEEK 0x70 /* seek */
+#define ATA_ZAC_MANAGEMENT_OUT 0x9f /* ZAC management out */
+#define ATA_ZM_CLOSE_ZONE 0x01 /* close zone */
+#define ATA_ZM_FINISH_ZONE 0x02 /* finish zone */
+#define ATA_ZM_OPEN_ZONE 0x03 /* open zone */
+#define ATA_ZM_RWP 0x04 /* reset write pointer */
#define ATA_PACKET_CMD 0xa0 /* packet command */
#define ATA_ATAPI_IDENTIFY 0xa1 /* get ATAPI params*/
#define ATA_SERVICE 0xa2 /* service command */
@@ -391,24 +434,36 @@ struct ata_params {
#define ATA_IDLE_CMD 0xe3 /* idle */
#define ATA_READ_BUFFER 0xe4 /* read buffer */
#define ATA_READ_PM 0xe4 /* read portmultiplier */
+#define ATA_CHECK_POWER_MODE 0xe5 /* device power mode */
#define ATA_SLEEP 0xe6 /* sleep */
#define ATA_FLUSHCACHE 0xe7 /* flush cache to disk */
#define ATA_WRITE_PM 0xe8 /* write portmultiplier */
#define ATA_FLUSHCACHE48 0xea /* flush cache to disk */
#define ATA_ATA_IDENTIFY 0xec /* get ATA params */
#define ATA_SETFEATURES 0xef /* features command */
-#define ATA_SF_SETXFER 0x03 /* set transfer mode */
#define ATA_SF_ENAB_WCACHE 0x02 /* enable write cache */
#define ATA_SF_DIS_WCACHE 0x82 /* disable write cache */
+#define ATA_SF_SETXFER 0x03 /* set transfer mode */
+#define ATA_SF_APM 0x05 /* Enable APM feature set */
#define ATA_SF_ENAB_PUIS 0x06 /* enable PUIS */
#define ATA_SF_DIS_PUIS 0x86 /* disable PUIS */
#define ATA_SF_PUIS_SPINUP 0x07 /* PUIS spin-up */
+#define ATA_SF_WRV 0x0b /* Enable Write-Read-Verify */
+#define ATA_SF_DLC 0x0c /* Enable device life control */
+#define ATA_SF_SATA 0x10 /* Enable use of SATA feature */
+#define ATA_SF_FFC 0x41 /* Free-fall Control */
+#define ATA_SF_MHIST 0x43 /* Set Max Host Sect. Times */
+#define ATA_SF_RATE 0x45 /* Set Rate Basis */
+#define ATA_SF_EPC 0x4A /* Extended Power Conditions */
#define ATA_SF_ENAB_RCACHE 0xaa /* enable readahead cache */
#define ATA_SF_DIS_RCACHE 0x55 /* disable readahead cache */
#define ATA_SF_ENAB_RELIRQ 0x5d /* enable release interrupt */
#define ATA_SF_DIS_RELIRQ 0xdd /* disable release interrupt */
#define ATA_SF_ENAB_SRVIRQ 0x5e /* enable service interrupt */
#define ATA_SF_DIS_SRVIRQ 0xde /* disable service interrupt */
+#define ATA_SF_LPSAERC 0x62 /* Long Phys Sect Align ErrRep*/
+#define ATA_SF_DSN 0x63 /* Device Stats Notification */
+#define ATA_CHECK_POWER_MODE 0xe5 /* Check Power Mode */
#define ATA_SECURITY_SET_PASSWORD 0xf1 /* set drive password */
#define ATA_SECURITY_UNLOCK 0xf2 /* unlock drive using passwd */
#define ATA_SECURITY_ERASE_PREPARE 0xf3 /* prepare to erase drive */
@@ -535,6 +590,333 @@ struct atapi_sense {
u_int8_t specific2; /* sense key specific */
} __packed;
+/*
+ * SET FEATURES subcommands
+ */
+
+/*
+ * SET FEATURES command
+ * Extended Power Conditions subcommand -- ATA_SF_EPC (0x4A)
+ * These values go in the LBA 3:0.
+ */
+#define ATA_SF_EPC_RESTORE 0x00 /* Restore Power Condition Settings */
+#define ATA_SF_EPC_GOTO 0x01 /* Go To Power Condition */
+#define ATA_SF_EPC_SET_TIMER 0x02 /* Set Power Condition Timer */
+#define ATA_SF_EPC_SET_STATE 0x03 /* Set Power Condition State */
+#define ATA_SF_EPC_ENABLE 0x04 /* Enable the EPC feature set */
+#define ATA_SF_EPC_DISABLE 0x05 /* Disable the EPC feature set */
+#define ATA_SF_EPC_SET_SOURCE 0x06 /* Set EPC Power Source */
+
+/*
+ * SET FEATURES command
+ * Extended Power Conditions subcommand -- ATA_SF_EPC (0x4A)
+ * Power Condition ID field
+ * These values go in the count register.
+ */
+#define ATA_EPC_STANDBY_Z 0x00 /* Substate of PM2:Standby */
+#define ATA_EPC_STANDBY_Y 0x01 /* Substate of PM2:Standby */
+#define ATA_EPC_IDLE_A 0x81 /* Substate of PM1:Idle */
+#define ATA_EPC_IDLE_B 0x82 /* Substate of PM1:Idle */
+#define ATA_EPC_IDLE_C 0x83 /* Substate of PM1:Idle */
+#define ATA_EPC_ALL 0xff /* All supported power conditions */
+
+/*
+ * SET FEATURES command
+ * Extended Power Conditions subcommand -- ATA_SF_EPC (0x4A)
+ * Restore Power Conditions Settings subcommand
+ * These values go in the LBA register.
+ */
+#define ATA_SF_EPC_RST_DFLT 0x40 /* 1=Rst from Default, 0= from Saved */
+#define ATA_SF_EPC_RST_SAVE 0x10 /* 1=Save on completion */
+
+/*
+ * SET FEATURES command
+ * Extended Power Conditions subcommand -- ATA_SF_EPC (0x4A)
+ * Got To Power Condition subcommand
+ * These values go in the LBA register.
+ */
+#define ATA_SF_EPC_GOTO_DELAY 0x02000000 /* Delayed entry bit */
+#define ATA_SF_EPC_GOTO_HOLD 0x01000000 /* Hold Power Cond bit */
+
+/*
+ * SET FEATURES command
+ * Extended Power Conditions subcommand -- ATA_SF_EPC (0x4A)
+ * Set Power Condition Timer subcommand
+ * These values go in the LBA register.
+ */
+#define ATA_SF_EPC_TIMER_MASK 0x00ffff00 /* Timer field */
+#define ATA_SF_EPC_TIMER_SHIFT 8
+#define ATA_SF_EPC_TIMER_SEC 0x00000080 /* Timer units, 1=sec, 0=.1s */
+#define ATA_SF_EPC_TIMER_EN 0x00000020 /* Enable/disable cond. */
+#define ATA_SF_EPC_TIMER_SAVE 0x00000010 /* Save settings on comp. */
+
+/*
+ * SET FEATURES command
+ * Extended Power Conditions subcommand -- ATA_SF_EPC (0x4A)
+ * Set Power Condition State subcommand
+ * These values go in the LBA register.
+ */
+#define ATA_SF_EPC_SETCON_EN 0x00000020 /* Enable power cond. */
+#define ATA_SF_EPC_SETCON_SAVE 0x00000010 /* Save settings on comp */
+
+/*
+ * SET FEATURES command
+ * Extended Power Conditions subcommand -- ATA_SF_EPC (0x4A)
+ * Set EPC Power Source subcommand
+ * These values go in the count register.
+ */
+#define ATA_SF_EPC_SRC_UNKNOWN 0x0000 /* Unknown source */
+#define ATA_SF_EPC_SRC_BAT 0x0001 /* battery source */
+#define ATA_SF_EPC_SRC_NOT_BAT 0x0002 /* not battery source */
+
+#define ATA_LOG_DIRECTORY 0x00 /* Directory of all logs */
+#define ATA_POWER_COND_LOG 0x08 /* Power Conditions Log */
+#define ATA_PCL_IDLE 0x00 /* Idle Power Conditions Page */
+#define ATA_PCL_STANDBY 0x01 /* Standby Power Conditions Page */
+#define ATA_IDENTIFY_DATA_LOG 0x30 /* Identify Device Data Log */
+#define ATA_IDL_PAGE_LIST 0x00 /* List of supported pages */
+#define ATA_IDL_IDENTIFY_DATA 0x01 /* Copy of Identify Device data */
+#define ATA_IDL_CAPACITY 0x02 /* Capacity */
+#define ATA_IDL_SUP_CAP 0x03 /* Supported Capabilities */
+#define ATA_IDL_CUR_SETTINGS 0x04 /* Current Settings */
+#define ATA_IDL_ATA_STRINGS 0x05 /* ATA Strings */
+#define ATA_IDL_SECURITY 0x06 /* Security */
+#define ATA_IDL_PARALLEL_ATA 0x07 /* Parallel ATA */
+#define ATA_IDL_SERIAL_ATA 0x08 /* Seiral ATA */
+#define ATA_IDL_ZDI 0x09 /* Zoned Device Information */
+
+struct ata_gp_log_dir {
+ uint8_t header[2];
+#define ATA_GP_LOG_DIR_VERSION 0x0001
+ uint8_t num_pages[255*2]; /* Number of log pages at address */
+};
+
+/*
+ * ATA Power Conditions log descriptor
+ */
+struct ata_power_cond_log_desc {
+ uint8_t reserved1;
+ uint8_t flags;
+#define ATA_PCL_COND_SUPPORTED 0x80
+#define ATA_PCL_COND_SAVEABLE 0x40
+#define ATA_PCL_COND_CHANGEABLE 0x20
+#define ATA_PCL_DEFAULT_TIMER_EN 0x10
+#define ATA_PCL_SAVED_TIMER_EN 0x08
+#define ATA_PCL_CURRENT_TIMER_EN 0x04
+#define ATA_PCL_HOLD_PC_NOT_SUP 0x02
+ uint8_t reserved2[2];
+ uint8_t default_timer[4];
+ uint8_t saved_timer[4];
+ uint8_t current_timer[4];
+ uint8_t nom_time_to_active[4];
+ uint8_t min_timer[4];
+ uint8_t max_timer[4];
+ uint8_t num_transitions_to_pc[4];
+ uint8_t hours_in_pc[4];
+ uint8_t reserved3[28];
+};
+
+/*
+ * ATA Power Conditions Log (0x08), Idle power conditions page (0x00)
+ */
+struct ata_power_cond_log_idle {
+ struct ata_power_cond_log_desc idle_a_desc;
+ struct ata_power_cond_log_desc idle_b_desc;
+ struct ata_power_cond_log_desc idle_c_desc;
+ uint8_t reserved[320];
+};
+
+/*
+ * ATA Power Conditions Log (0x08), Standby power conditions page (0x01)
+ */
+struct ata_power_cond_log_standby {
+ uint8_t reserved[384];
+ struct ata_power_cond_log_desc standby_y_desc;
+ struct ata_power_cond_log_desc standby_z_desc;
+};
+
+/*
+ * ATA IDENTIFY DEVICE data log (0x30) page 0x00
+ * List of Supported IDENTIFY DEVICE data pages.
+ */
+struct ata_identify_log_pages {
+ uint8_t header[8];
+#define ATA_IDLOG_REVISION 0x0000000000000001
+ uint8_t entry_count;
+ uint8_t entries[503];
+};
+
+/*
+ * ATA IDENTIFY DEVICE data log (0x30)
+ * Capacity (Page 0x02).
+ */
+struct ata_identify_log_capacity {
+ uint8_t header[8];
+#define ATA_CAP_HEADER_VALID 0x8000000000000000
+#define ATA_CAP_PAGE_NUM_MASK 0x0000000000ff0000
+#define ATA_CAP_PAGE_NUM_SHIFT 16
+#define ATA_CAP_REV_MASK 0x00000000000000ff
+ uint8_t capacity[8];
+#define ATA_CAP_CAPACITY_VALID 0x8000000000000000
+#define ATA_CAP_ACCESSIBLE_CAP 0x0000ffffffffffff
+ uint8_t phys_logical_sect_size[8];
+#define ATA_CAP_PL_VALID 0x8000000000000000
+#define ATA_CAP_LTOP_REL_SUP 0x4000000000000000
+#define ATA_CAP_LOG_SECT_SUP 0x2000000000000000
+#define ATA_CAP_ALIGN_ERR_MASK 0x0000000000300000
+#define ATA_CAP_LTOP_MASK 0x00000000000f0000
+#define ATA_CAP_LOG_SECT_OFF 0x000000000000ffff
+ uint8_t logical_sect_size[8];
+#define ATA_CAP_LOG_SECT_VALID 0x8000000000000000
+#define ATA_CAP_LOG_SECT_SIZE 0x00000000ffffffff
+ uint8_t nominal_buffer_size[8];
+#define ATA_CAP_NOM_BUF_VALID 0x8000000000000000
+#define ATA_CAP_NOM_BUF_SIZE 0x7fffffffffffffff
+ uint8_t reserved[472];
+};
+
+/*
+ * ATA IDENTIFY DEVICE data log (0x30)
+ * Supported Capabilities (Page 0x03).
+ */
+
+struct ata_identify_log_sup_cap {
+ uint8_t header[8];
+#define ATA_SUP_CAP_HEADER_VALID 0x8000000000000000
+#define ATA_SUP_CAP_PAGE_NUM_MASK 0x0000000000ff0000
+#define ATA_SUP_CAP_PAGE_NUM_SHIFT 16
+#define ATA_SUP_CAP_REV_MASK 0x00000000000000ff
+ uint8_t sup_cap[8];
+#define ATA_SUP_CAP_VALID 0x8000000000000000
+#define ATA_SC_SET_SECT_CONFIG_SUP 0x0002000000000000 /* Set Sect Conf*/
+#define ATA_SC_ZERO_EXT_SUP 0x0001000000000000 /* Zero EXT */
+#define ATA_SC_SUCC_NCQ_SENSE_SUP 0x0000800000000000 /* Succ. NCQ Sns */
+#define ATA_SC_DLC_SUP 0x0000400000000000 /* DLC */
+#define ATA_SC_RQSN_DEV_FAULT_SUP 0x0000200000000000 /* Req Sns Dev Flt*/
+#define ATA_SC_DSN_SUP 0x0000100000000000 /* DSN */
+#define ATA_SC_LP_STANDBY_SUP 0x0000080000000000 /* LP Standby */
+#define ATA_SC_SET_EPC_PS_SUP 0x0000040000000000 /* Set EPC PS */
+#define ATA_SC_AMAX_ADDR_SUP 0x0000020000000000 /* AMAX Addr */
+#define ATA_SC_DRAT_SUP 0x0000008000000000 /* DRAT */
+#define ATA_SC_LPS_MISALGN_SUP 0x0000004000000000 /* LPS Misalign */
+#define ATA_SC_RB_DMA_SUP 0x0000001000000000 /* Read Buf DMA */
+#define ATA_SC_WB_DMA_SUP 0x0000000800000000 /* Write Buf DMA */
+#define ATA_SC_DNLD_MC_DMA_SUP 0x0000000200000000 /* DL MCode DMA */
+#define ATA_SC_28BIT_SUP 0x0000000100000000 /* 28-bit */
+#define ATA_SC_RZAT_SUP 0x0000000080000000 /* RZAT */
+#define ATA_SC_NOP_SUP 0x0000000020000000 /* NOP */
+#define ATA_SC_READ_BUFFER_SUP 0x0000000010000000 /* Read Buffer */
+#define ATA_SC_WRITE_BUFFER_SUP 0x0000000008000000 /* Write Buffer */
+#define ATA_SC_READ_LOOK_AHEAD_SUP 0x0000000002000000 /* Read Look-Ahead*/
+#define ATA_SC_VOLATILE_WC_SUP 0x0000000001000000 /* Volatile WC */
+#define ATA_SC_SMART_SUP 0x0000000000800000 /* SMART */
+#define ATA_SC_FLUSH_CACHE_EXT_SUP 0x0000000000400000 /* Flush Cache Ext */
+#define ATA_SC_48BIT_SUP 0x0000000000100000 /* 48-Bit */
+#define ATA_SC_SPINUP_SUP 0x0000000000040000 /* Spin-Up */
+#define ATA_SC_PUIS_SUP 0x0000000000020000 /* PUIS */
+#define ATA_SC_APM_SUP 0x0000000000010000 /* APM */
+#define ATA_SC_DL_MICROCODE_SUP 0x0000000000004000 /* DL Microcode */
+#define ATA_SC_UNLOAD_SUP 0x0000000000002000 /* Unload */
+#define ATA_SC_WRITE_FUA_EXT_SUP 0x0000000000001000 /* Write FUA EXT */
+#define ATA_SC_GPL_SUP 0x0000000000000800 /* GPL */
+#define ATA_SC_STREAMING_SUP 0x0000000000000400 /* Streaming */
+#define ATA_SC_SMART_SELFTEST_SUP 0x0000000000000100 /* SMART self-test */
+#define ATA_SC_SMART_ERR_LOG_SUP 0x0000000000000080 /* SMART Err Log */
+#define ATA_SC_EPC_SUP 0x0000000000000040 /* EPC */
+#define ATA_SC_SENSE_SUP 0x0000000000000020 /* Sense data */
+#define ATA_SC_FREEFALL_SUP 0x0000000000000010 /* Free-Fall */
+#define ATA_SC_DM_MODE3_SUP 0x0000000000000008 /* DM Mode 3 */
+#define ATA_SC_GPL_DMA_SUP 0x0000000000000004 /* GPL DMA */
+#define ATA_SC_WRITE_UNCOR_SUP 0x0000000000000002 /* Write uncorr. */
+#define ATA_SC_WRV_SUP 0x0000000000000001 /* WRV */
+ uint8_t download_code_cap[8];
+#define ATA_DL_CODE_VALID 0x8000000000000000
+#define ATA_DLC_DM_OFFSETS_DEFER_SUP 0x0000000400000000
+#define ATA_DLC_DM_IMMED_SUP 0x0000000200000000
+#define ATA_DLC_DM_OFF_IMMED_SUP 0x0000000100000000
+#define ATA_DLC_DM_MAX_XFER_SIZE_MASK 0x00000000ffff0000
+#define ATA_DLC_DM_MAX_XFER_SIZE_SHIFT 16
+#define ATA_DLC_DM_MIN_XFER_SIZE_MASK 0x000000000000ffff
+ uint8_t nom_media_rotation_rate[8];
+#define ATA_NOM_MEDIA_ROTATION_VALID 0x8000000000000000
+#define ATA_ROTATION_MASK 0x000000000000ffff
+ uint8_t form_factor[8];
+#define ATA_FORM_FACTOR_VALID 0x8000000000000000
+#define ATA_FF_MASK 0x000000000000000f
+#define ATA_FF_NOT_REPORTED 0x0000000000000000 /* Not reported */
+#define ATA_FF_525_IN 0x0000000000000001 /* 5.25 inch */
+#define ATA_FF_35_IN 0x0000000000000002 /* 3.5 inch */
+#define ATA_FF_25_IN 0x0000000000000003 /* 2.5 inch */
+#define ATA_FF_18_IN 0x0000000000000004 /* 1.8 inch */
+#define ATA_FF_LT_18_IN 0x0000000000000005 /* < 1.8 inch */
+#define ATA_FF_MSATA 0x0000000000000006 /* mSATA */
+#define ATA_FF_M2 0x0000000000000007 /* M.2 */
+#define ATA_FF_MICROSSD 0x0000000000000008 /* MicroSSD */
+#define ATA_FF_CFAST 0x0000000000000009 /* CFast */
+ uint8_t wrv_sec_cnt_mode3[8];
+#define ATA_WRV_MODE3_VALID 0x8000000000000000
+#define ATA_WRV_MODE3_COUNT 0x00000000ffffffff
+ uint8_t wrv_sec_cnt_mode2[8];
+#define ATA_WRV_MODE2_VALID 0x8000000000000000
+#define ATA_WRV_MODE2_COUNT 0x00000000ffffffff
+ uint8_t wwn[16];
+ /* XXX KDM need to figure out how to handle 128-bit fields */
+ uint8_t dsm[8];
+#define ATA_DSM_VALID 0x8000000000000000
+#define ATA_LB_MARKUP_SUP 0x000000000000ff00
+#define ATA_TRIM_SUP 0x0000000000000001
+ uint8_t util_per_unit_time[16];
+ /* XXX KDM need to figure out how to handle 128-bit fields */
+ uint8_t util_usage_rate_sup[8];
+#define ATA_UTIL_USAGE_RATE_VALID 0x8000000000000000
+#define ATA_SETTING_RATE_SUP 0x0000000000800000
+#define ATA_SINCE_POWERON_SUP 0x0000000000000100
+#define ATA_POH_RATE_SUP 0x0000000000000010
+#define ATA_DATE_TIME_RATE_SUP 0x0000000000000001
+ uint8_t zoned_cap[8];
+#define ATA_ZONED_VALID 0x8000000000000000
+#define ATA_ZONED_MASK 0x0000000000000003
+ uint8_t sup_zac_cap[8];
+#define ATA_SUP_ZAC_CAP_VALID 0x8000000000000000
+#define ATA_ND_RWP_SUP 0x0000000000000010 /* Reset Write Ptr*/
+#define ATA_ND_FINISH_ZONE_SUP 0x0000000000000008 /* Finish Zone */
+#define ATA_ND_CLOSE_ZONE_SUP 0x0000000000000004 /* Close Zone */
+#define ATA_ND_OPEN_ZONE_SUP 0x0000000000000002 /* Open Zone */
+#define ATA_REPORT_ZONES_SUP 0x0000000000000001 /* Report Zones */
+ uint8_t reserved[392];
+};
+
+/*
+ * ATA Identify Device Data Log Zoned Device Information Page (0x09).
+ * Current as of ZAC r04a, August 25, 2015.
+ */
+struct ata_zoned_info_log {
+ uint8_t header[8];
+#define ATA_ZDI_HEADER_VALID 0x8000000000000000
+#define ATA_ZDI_PAGE_NUM_MASK 0x0000000000ff0000
+#define ATA_ZDI_PAGE_NUM_SHIFT 16
+#define ATA_ZDI_REV_MASK 0x00000000000000ff
+ uint8_t zoned_cap[8];
+#define ATA_ZDI_CAP_VALID 0x8000000000000000
+#define ATA_ZDI_CAP_URSWRZ 0x0000000000000001
+ uint8_t zoned_settings[8];
+#define ATA_ZDI_SETTINGS_VALID 0x8000000000000000
+ uint8_t optimal_seq_zones[8];
+#define ATA_ZDI_OPT_SEQ_VALID 0x8000000000000000
+#define ATA_ZDI_OPT_SEQ_MASK 0x00000000ffffffff
+ uint8_t optimal_nonseq_zones[8];
+#define ATA_ZDI_OPT_NS_VALID 0x8000000000000000
+#define ATA_ZDI_OPT_NS_MASK 0x00000000ffffffff
+ uint8_t max_seq_req_zones[8];
+#define ATA_ZDI_MAX_SEQ_VALID 0x8000000000000000
+#define ATA_ZDI_MAX_SEQ_MASK 0x00000000ffffffff
+ uint8_t version_info[8];
+#define ATA_ZDI_VER_VALID 0x8000000000000000
+#define ATA_ZDI_VER_ZAC_SUP 0x0100000000000000
+#define ATA_ZDI_VER_ZAC_MASK 0x00000000000000ff
+ uint8_t reserved[456];
+};
+
struct ata_ioc_request {
union {
struct {
diff --git a/freebsd/sys/sys/bitset.h b/freebsd/sys/sys/bitset.h
new file mode 100644
index 00000000..723c39b0
--- /dev/null
+++ b/freebsd/sys/sys/bitset.h
@@ -0,0 +1,208 @@
+/*-
+ * Copyright (c) 2008, Jeffrey Roberson <jeff@freebsd.org>
+ * All rights reserved.
+ *
+ * Copyright (c) 2008 Nokia Corporation
+ * All rights reserved.
+ *
+ * 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 unmodified, 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 ``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 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_BITSET_H_
+#define _SYS_BITSET_H_
+
+#define __bitset_mask(_s, n) \
+ (1L << ((__bitset_words((_s)) == 1) ? \
+ (__size_t)(n) : ((n) % _BITSET_BITS)))
+
+#define __bitset_word(_s, n) \
+ ((__bitset_words((_s)) == 1) ? 0 : ((n) / _BITSET_BITS))
+
+#define BIT_CLR(_s, n, p) \
+ ((p)->__bits[__bitset_word(_s, n)] &= ~__bitset_mask((_s), (n)))
+
+#define BIT_COPY(_s, f, t) (void)(*(t) = *(f))
+
+#define BIT_ISSET(_s, n, p) \
+ ((((p)->__bits[__bitset_word(_s, n)] & __bitset_mask((_s), (n))) != 0))
+
+#define BIT_SET(_s, n, p) \
+ ((p)->__bits[__bitset_word(_s, n)] |= __bitset_mask((_s), (n)))
+
+#define BIT_ZERO(_s, p) do { \
+ __size_t __i; \
+ for (__i = 0; __i < __bitset_words((_s)); __i++) \
+ (p)->__bits[__i] = 0L; \
+} while (0)
+
+#define BIT_FILL(_s, p) do { \
+ __size_t __i; \
+ for (__i = 0; __i < __bitset_words((_s)); __i++) \
+ (p)->__bits[__i] = -1L; \
+} while (0)
+
+#define BIT_SETOF(_s, n, p) do { \
+ BIT_ZERO(_s, p); \
+ (p)->__bits[__bitset_word(_s, n)] = __bitset_mask((_s), (n)); \
+} while (0)
+
+/* Is p empty. */
+#define BIT_EMPTY(_s, p) __extension__ ({ \
+ __size_t __i; \
+ for (__i = 0; __i < __bitset_words((_s)); __i++) \
+ if ((p)->__bits[__i]) \
+ break; \
+ __i == __bitset_words((_s)); \
+})
+
+/* Is p full set. */
+#define BIT_ISFULLSET(_s, p) __extension__ ({ \
+ __size_t __i; \
+ for (__i = 0; __i < __bitset_words((_s)); __i++) \
+ if ((p)->__bits[__i] != (long)-1) \
+ break; \
+ __i == __bitset_words((_s)); \
+})
+
+/* Is c a subset of p. */
+#define BIT_SUBSET(_s, p, c) __extension__ ({ \
+ __size_t __i; \
+ for (__i = 0; __i < __bitset_words((_s)); __i++) \
+ if (((c)->__bits[__i] & \
+ (p)->__bits[__i]) != \
+ (c)->__bits[__i]) \
+ break; \
+ __i == __bitset_words((_s)); \
+})
+
+/* Are there any common bits between b & c? */
+#define BIT_OVERLAP(_s, p, c) __extension__ ({ \
+ __size_t __i; \
+ for (__i = 0; __i < __bitset_words((_s)); __i++) \
+ if (((c)->__bits[__i] & \
+ (p)->__bits[__i]) != 0) \
+ break; \
+ __i != __bitset_words((_s)); \
+})
+
+/* Compare two sets, returns 0 if equal 1 otherwise. */
+#define BIT_CMP(_s, p, c) __extension__ ({ \
+ __size_t __i; \
+ for (__i = 0; __i < __bitset_words((_s)); __i++) \
+ if (((c)->__bits[__i] != \
+ (p)->__bits[__i])) \
+ break; \
+ __i != __bitset_words((_s)); \
+})
+
+#define BIT_OR(_s, d, s) do { \
+ __size_t __i; \
+ for (__i = 0; __i < __bitset_words((_s)); __i++) \
+ (d)->__bits[__i] |= (s)->__bits[__i]; \
+} while (0)
+
+#define BIT_AND(_s, d, s) do { \
+ __size_t __i; \
+ for (__i = 0; __i < __bitset_words((_s)); __i++) \
+ (d)->__bits[__i] &= (s)->__bits[__i]; \
+} while (0)
+
+#define BIT_NAND(_s, d, s) do { \
+ __size_t __i; \
+ for (__i = 0; __i < __bitset_words((_s)); __i++) \
+ (d)->__bits[__i] &= ~(s)->__bits[__i]; \
+} while (0)
+
+#define BIT_CLR_ATOMIC(_s, n, p) \
+ atomic_clear_long(&(p)->__bits[__bitset_word(_s, n)], \
+ __bitset_mask((_s), n))
+
+#define BIT_SET_ATOMIC(_s, n, p) \
+ atomic_set_long(&(p)->__bits[__bitset_word(_s, n)], \
+ __bitset_mask((_s), n))
+
+#define BIT_SET_ATOMIC_ACQ(_s, n, p) \
+ atomic_set_acq_long(&(p)->__bits[__bitset_word(_s, n)], \
+ __bitset_mask((_s), n))
+
+/* Convenience functions catering special cases. */
+#define BIT_AND_ATOMIC(_s, d, s) do { \
+ __size_t __i; \
+ for (__i = 0; __i < __bitset_words((_s)); __i++) \
+ atomic_clear_long(&(d)->__bits[__i], \
+ ~(s)->__bits[__i]); \
+} while (0)
+
+#define BIT_OR_ATOMIC(_s, d, s) do { \
+ __size_t __i; \
+ for (__i = 0; __i < __bitset_words((_s)); __i++) \
+ atomic_set_long(&(d)->__bits[__i], \
+ (s)->__bits[__i]); \
+} while (0)
+
+#define BIT_COPY_STORE_REL(_s, f, t) do { \
+ __size_t __i; \
+ for (__i = 0; __i < __bitset_words((_s)); __i++) \
+ atomic_store_rel_long(&(t)->__bits[__i], \
+ (f)->__bits[__i]); \
+} while (0)
+
+#define BIT_FFS(_s, p) __extension__ ({ \
+ __size_t __i; \
+ int __bit; \
+ \
+ __bit = 0; \
+ for (__i = 0; __i < __bitset_words((_s)); __i++) { \
+ if ((p)->__bits[__i] != 0) { \
+ __bit = ffsl((p)->__bits[__i]); \
+ __bit += __i * _BITSET_BITS; \
+ break; \
+ } \
+ } \
+ __bit; \
+})
+
+#define BIT_COUNT(_s, p) __extension__ ({ \
+ __size_t __i; \
+ int __count; \
+ \
+ __count = 0; \
+ for (__i = 0; __i < __bitset_words((_s)); __i++) \
+ __count += __bitcountl((p)->__bits[__i]); \
+ __count; \
+})
+
+#define BITSET_T_INITIALIZER(x) \
+ { .__bits = { x } }
+
+#define BITSET_FSET(n) \
+ [ 0 ... ((n) - 1) ] = (-1L)
+
+/*
+ * Dynamically allocate a bitset.
+ */
+#define BITSET_ALLOC(_s, mt, mf) \
+ malloc(__bitset_words(_s) * sizeof(long), mt, (mf))
+
+#endif /* !_SYS_BITSET_H_ */
diff --git a/freebsd/sys/sys/bitstring.h b/freebsd/sys/sys/bitstring.h
index 125ef51d..32465d11 100644
--- a/freebsd/sys/sys/bitstring.h
+++ b/freebsd/sys/sys/bitstring.h
@@ -29,118 +29,274 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
+ * Copyright (c) 2014 Spectra Logic Corporation
+ * All rights reserved.
+ *
+ * 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,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * substantially similar to the "NO WARRANTY" disclaimer below
+ * ("Disclaimer") and any redistribution must be conditioned upon
+ * including a substantially similar Disclaimer requirement for further
+ * binary redistribution.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR 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 DAMAGES.
+ *
* $FreeBSD$
*/
-
#ifndef _SYS_BITSTRING_H_
#define _SYS_BITSTRING_H_
-typedef unsigned char bitstr_t;
+#ifdef _KERNEL
+#include <sys/libkern.h>
+#include <sys/malloc.h>
+#endif
+
+#include <sys/types.h>
-/* internal macros */
- /* byte of the bitstring bit is in */
-#define _bit_byte(bit) \
- ((bit) >> 3)
+typedef unsigned long bitstr_t;
- /* mask for the bit within its byte */
-#define _bit_mask(bit) \
- (1 << ((bit)&0x7))
+/*---------------------- Private Implementation Details ----------------------*/
+#define _BITSTR_MASK (~0UL)
+#define _BITSTR_BITS (sizeof(bitstr_t) * 8)
-/* external macros */
- /* bytes in a bitstring of nbits bits */
-#define bitstr_size(nbits) \
- (((nbits) + 7) >> 3)
+#ifdef roundup2
+#define _bit_roundup2 roundup2
+#else
+#define _bit_roundup2(x, y) (((x)+((y)-1))&(~((y)-1))) /* if y is powers of two */
+#endif
- /* allocate a bitstring */
-#define bit_alloc(nbits) \
- (bitstr_t *)calloc((size_t)bitstr_size(nbits), sizeof(bitstr_t))
+/* bitstr_t in bit string containing the bit. */
+static inline int
+_bit_idx(int _bit)
+{
+ return (_bit / _BITSTR_BITS);
+}
- /* allocate a bitstring on the stack */
+/* bit number within bitstr_t at _bit_idx(_bit). */
+static inline int
+_bit_offset(int _bit)
+{
+ return (_bit % _BITSTR_BITS);
+}
+
+/* Mask for the bit within its long. */
+static inline bitstr_t
+_bit_mask(int _bit)
+{
+ return (1UL << _bit_offset(_bit));
+}
+
+static inline bitstr_t
+_bit_make_mask(int _start, int _stop)
+{
+ return ((_BITSTR_MASK << _bit_offset(_start)) &
+ (_BITSTR_MASK >> (_BITSTR_BITS - _bit_offset(_stop) - 1)));
+}
+
+/*----------------------------- Public Interface -----------------------------*/
+/* Number of bytes allocated for a bit string of nbits bits */
+#define bitstr_size(_nbits) (_bit_roundup2(_nbits, _BITSTR_BITS) / 8)
+
+/* Allocate a bit string initialized with no bits set. */
+#ifdef _KERNEL
+static inline bitstr_t *
+bit_alloc(int _nbits, struct malloc_type *type, int flags)
+{
+ return ((bitstr_t *)malloc(bitstr_size(_nbits), type, flags | M_ZERO));
+}
+#else
+static inline bitstr_t *
+bit_alloc(int _nbits)
+{
+ return ((bitstr_t *)calloc(bitstr_size(_nbits), 1));
+}
+#endif
+
+/* Allocate a bit string on the stack */
#define bit_decl(name, nbits) \
- ((name)[bitstr_size(nbits)])
-
- /* is bit N of bitstring name set? */
-#define bit_test(name, bit) \
- ((name)[_bit_byte(bit)] & _bit_mask(bit))
-
- /* set bit N of bitstring name */
-#define bit_set(name, bit) \
- ((name)[_bit_byte(bit)] |= _bit_mask(bit))
-
- /* clear bit N of bitstring name */
-#define bit_clear(name, bit) \
- ((name)[_bit_byte(bit)] &= ~_bit_mask(bit))
-
- /* clear bits start ... stop in bitstring */
-#define bit_nclear(name, start, stop) do { \
- register bitstr_t *_name = (name); \
- register int _start = (start), _stop = (stop); \
- register int _startbyte = _bit_byte(_start); \
- register int _stopbyte = _bit_byte(_stop); \
- if (_startbyte == _stopbyte) { \
- _name[_startbyte] &= ((0xff >> (8 - (_start&0x7))) | \
- (0xff << ((_stop&0x7) + 1))); \
- } else { \
- _name[_startbyte] &= 0xff >> (8 - (_start&0x7)); \
- while (++_startbyte < _stopbyte) \
- _name[_startbyte] = 0; \
- _name[_stopbyte] &= 0xff << ((_stop&0x7) + 1); \
- } \
-} while (0)
-
- /* set bits start ... stop in bitstring */
-#define bit_nset(name, start, stop) do { \
- register bitstr_t *_name = (name); \
- register int _start = (start), _stop = (stop); \
- register int _startbyte = _bit_byte(_start); \
- register int _stopbyte = _bit_byte(_stop); \
- if (_startbyte == _stopbyte) { \
- _name[_startbyte] |= ((0xff << (_start&0x7)) & \
- (0xff >> (7 - (_stop&0x7)))); \
- } else { \
- _name[_startbyte] |= 0xff << ((_start)&0x7); \
- while (++_startbyte < _stopbyte) \
- _name[_startbyte] = 0xff; \
- _name[_stopbyte] |= 0xff >> (7 - (_stop&0x7)); \
- } \
-} while (0)
-
- /* find first bit clear in name */
-#define bit_ffc(name, nbits, value) do { \
- register bitstr_t *_name = (name); \
- register int _byte, _nbits = (nbits); \
- register int _stopbyte = _bit_byte(_nbits - 1), _value = -1; \
- if (_nbits > 0) \
- for (_byte = 0; _byte <= _stopbyte; ++_byte) \
- if (_name[_byte] != 0xff) { \
- bitstr_t _lb; \
- _value = _byte << 3; \
- for (_lb = _name[_byte]; (_lb&0x1); \
- ++_value, _lb >>= 1); \
- break; \
- } \
- if (_value >= nbits) \
- _value = -1; \
- *(value) = _value; \
-} while (0)
-
- /* find first bit set in name */
-#define bit_ffs(name, nbits, value) do { \
- register bitstr_t *_name = (name); \
- register int _byte, _nbits = (nbits); \
- register int _stopbyte = _bit_byte(_nbits - 1), _value = -1; \
- if (_nbits > 0) \
- for (_byte = 0; _byte <= _stopbyte; ++_byte) \
- if (_name[_byte]) { \
- bitstr_t _lb; \
- _value = _byte << 3; \
- for (_lb = _name[_byte]; !(_lb&0x1); \
- ++_value, _lb >>= 1); \
- break; \
- } \
- if (_value >= nbits) \
- _value = -1; \
- *(value) = _value; \
-} while (0)
-
-#endif /* !_SYS_BITSTRING_H_ */
+ ((name)[bitstr_size(nbits) / sizeof(bitstr_t)])
+
+/* Is bit N of bit string set? */
+static inline int
+bit_test(const bitstr_t *_bitstr, int _bit)
+{
+ return ((_bitstr[_bit_idx(_bit)] & _bit_mask(_bit)) != 0);
+}
+
+/* Set bit N of bit string. */
+static inline void
+bit_set(bitstr_t *_bitstr, int _bit)
+{
+ _bitstr[_bit_idx(_bit)] |= _bit_mask(_bit);
+}
+
+/* clear bit N of bit string name */
+static inline void
+bit_clear(bitstr_t *_bitstr, int _bit)
+{
+ _bitstr[_bit_idx(_bit)] &= ~_bit_mask(_bit);
+}
+
+/* Set bits start ... stop inclusive in bit string. */
+static inline void
+bit_nset(bitstr_t *_bitstr, int _start, int _stop)
+{
+ bitstr_t *_stopbitstr;
+
+ _stopbitstr = _bitstr + _bit_idx(_stop);
+ _bitstr += _bit_idx(_start);
+
+ if (_bitstr == _stopbitstr) {
+ *_bitstr |= _bit_make_mask(_start, _stop);
+ } else {
+ *_bitstr |= _bit_make_mask(_start, _BITSTR_BITS - 1);
+ while (++_bitstr < _stopbitstr)
+ *_bitstr = _BITSTR_MASK;
+ *_stopbitstr |= _bit_make_mask(0, _stop);
+ }
+}
+
+/* Clear bits start ... stop inclusive in bit string. */
+static inline void
+bit_nclear(bitstr_t *_bitstr, int _start, int _stop)
+{
+ bitstr_t *_stopbitstr;
+
+ _stopbitstr = _bitstr + _bit_idx(_stop);
+ _bitstr += _bit_idx(_start);
+
+ if (_bitstr == _stopbitstr) {
+ *_bitstr &= ~_bit_make_mask(_start, _stop);
+ } else {
+ *_bitstr &= ~_bit_make_mask(_start, _BITSTR_BITS - 1);
+ while (++_bitstr < _stopbitstr)
+ *_bitstr = 0;
+ *_stopbitstr &= ~_bit_make_mask(0, _stop);
+ }
+}
+
+/* Find the first bit set in bit string at or after bit start. */
+static inline void
+bit_ffs_at(bitstr_t *_bitstr, int _start, int _nbits, int *_result)
+{
+ bitstr_t *_curbitstr;
+ bitstr_t *_stopbitstr;
+ bitstr_t _test;
+ int _value, _offset;
+
+ if (_nbits > 0) {
+ _curbitstr = _bitstr + _bit_idx(_start);
+ _stopbitstr = _bitstr + _bit_idx(_nbits - 1);
+
+ _test = *_curbitstr;
+ if (_bit_offset(_start) != 0)
+ _test &= _bit_make_mask(_start, _BITSTR_BITS - 1);
+ while (_test == 0 && _curbitstr < _stopbitstr)
+ _test = *(++_curbitstr);
+
+ _offset = ffsl(_test);
+ _value = ((_curbitstr - _bitstr) * _BITSTR_BITS) + _offset - 1;
+ if (_offset == 0 || _value >= _nbits)
+ _value = -1;
+ } else {
+ _value = -1;
+ }
+ *_result = _value;
+}
+
+/* Find the first bit clear in bit string at or after bit start. */
+static inline void
+bit_ffc_at(bitstr_t *_bitstr, int _start, int _nbits, int *_result)
+{
+ bitstr_t *_curbitstr;
+ bitstr_t *_stopbitstr;
+ bitstr_t _test;
+ int _value, _offset;
+
+ if (_nbits > 0) {
+ _curbitstr = _bitstr + _bit_idx(_start);
+ _stopbitstr = _bitstr + _bit_idx(_nbits - 1);
+
+ _test = *_curbitstr;
+ if (_bit_offset(_start) != 0)
+ _test |= _bit_make_mask(0, _start - 1);
+ while (_test == _BITSTR_MASK && _curbitstr < _stopbitstr)
+ _test = *(++_curbitstr);
+
+ _offset = ffsl(~_test);
+ _value = ((_curbitstr - _bitstr) * _BITSTR_BITS) + _offset - 1;
+ if (_offset == 0 || _value >= _nbits)
+ _value = -1;
+ } else {
+ _value = -1;
+ }
+ *_result = _value;
+}
+
+/* Find the first bit set in bit string. */
+static inline void
+bit_ffs(bitstr_t *_bitstr, int _nbits, int *_result)
+{
+ bit_ffs_at(_bitstr, /*start*/0, _nbits, _result);
+}
+
+/* Find the first bit clear in bit string. */
+static inline void
+bit_ffc(bitstr_t *_bitstr, int _nbits, int *_result)
+{
+ bit_ffc_at(_bitstr, /*start*/0, _nbits, _result);
+}
+
+/* Count the number of bits set in a bitstr of size _nbits at or after _start */
+static inline void
+bit_count(bitstr_t *_bitstr, int _start, int _nbits, int *_result)
+{
+ bitstr_t *_curbitstr, mask;
+ int _value = 0, curbitstr_len;
+
+ if (_start >= _nbits)
+ goto out;
+
+ _curbitstr = _bitstr + _bit_idx(_start);
+ _nbits -= _BITSTR_BITS * _bit_idx(_start);
+ _start -= _BITSTR_BITS * _bit_idx(_start);
+
+ if (_start > 0) {
+ curbitstr_len = (int)_BITSTR_BITS < _nbits ?
+ (int)_BITSTR_BITS : _nbits;
+ mask = _bit_make_mask(_start, _bit_offset(curbitstr_len - 1));
+ _value += __bitcountl(*_curbitstr & mask);
+ _curbitstr++;
+ _nbits -= _BITSTR_BITS;
+ }
+ while (_nbits >= (int)_BITSTR_BITS) {
+ _value += __bitcountl(*_curbitstr);
+ _curbitstr++;
+ _nbits -= _BITSTR_BITS;
+ }
+ if (_nbits > 0) {
+ mask = _bit_make_mask(0, _bit_offset(_nbits - 1));
+ _value += __bitcountl(*_curbitstr & mask);
+ }
+
+out:
+ *_result = _value;
+}
+
+#endif /* _SYS_BITSTRING_H_ */
diff --git a/freebsd/sys/sys/buf.h b/freebsd/sys/sys/buf.h
index e87fd420..f32c6ca1 100644
--- a/freebsd/sys/sys/buf.h
+++ b/freebsd/sys/sys/buf.h
@@ -98,37 +98,37 @@ struct buf {
void *b_caller1;
caddr_t b_data;
int b_error;
- uint8_t b_iocmd;
- uint8_t b_ioflags;
+ uint16_t b_iocmd; /* BIO_* bio_cmd from bio.h */
+ uint16_t b_ioflags; /* BIO_* bio_flags from bio.h */
off_t b_iooffset;
long b_resid;
void (*b_iodone)(struct buf *);
daddr_t b_blkno; /* Underlying physical block number. */
off_t b_offset; /* Offset into file. */
TAILQ_ENTRY(buf) b_bobufs; /* (V) Buffer's associated vnode. */
- struct buf *b_left; /* (V) splay tree link */
- struct buf *b_right; /* (V) splay tree link */
uint32_t b_vflags; /* (V) BV_* flags */
- TAILQ_ENTRY(buf) b_freelist; /* (Q) Free list position inactive. */
unsigned short b_qindex; /* (Q) buffer queue index */
uint32_t b_flags; /* B_* flags. */
b_xflags_t b_xflags; /* extra flags */
struct lock b_lock; /* Buffer lock */
long b_bufsize; /* Allocated buffer size. */
- long b_runningbufspace; /* when I/O is running, pipelining */
- caddr_t b_kvabase; /* base kva for buffer */
- caddr_t b_kvaalloc; /* allocated kva for B_KVAALLOC */
+ int b_runningbufspace; /* when I/O is running, pipelining */
int b_kvasize; /* size of kva for buffer */
- daddr_t b_lblkno; /* Logical block number. */
- struct vnode *b_vp; /* Device vnode. */
int b_dirtyoff; /* Offset in buffer of dirty region. */
int b_dirtyend; /* Offset of end of dirty region. */
+ caddr_t b_kvabase; /* base kva for buffer */
+ daddr_t b_lblkno; /* Logical block number. */
+ struct vnode *b_vp; /* Device vnode. */
struct ucred *b_rcred; /* Read credentials reference. */
struct ucred *b_wcred; /* Write credentials reference. */
- void *b_saveaddr; /* Original b_addr for physio. */
- union pager_info {
- int pg_reqpage;
- } b_pager;
+ union {
+ TAILQ_ENTRY(buf) b_freelist; /* (Q) */
+ struct {
+ void (*b_pgiodone)(void *, vm_page_t *, int, int);
+ int b_pgbefore;
+ int b_pgafter;
+ };
+ };
union cluster_info {
TAILQ_HEAD(cluster_list_head, buf) cluster_head;
TAILQ_ENTRY(buf) cluster_entry;
@@ -139,7 +139,6 @@ struct buf {
void *b_fsprivate1;
void *b_fsprivate2;
void *b_fsprivate3;
- int b_pin_count;
};
#define b_object b_bufobj->bo_object
@@ -200,24 +199,24 @@ struct buf {
#define B_CACHE 0x00000020 /* Bread found us in the cache. */
#define B_VALIDSUSPWRT 0x00000040 /* Valid write during suspension. */
#define B_DELWRI 0x00000080 /* Delay I/O until buffer reused. */
-#define B_PERSISTENT 0x00000100 /* Perm. ref'ed while EXT2FS mounted. */
+#define B_00000100 0x00000100 /* Available flag. */
#define B_DONE 0x00000200 /* I/O completed. */
#define B_EINTR 0x00000400 /* I/O was interrupted */
-#define B_UNMAPPED 0x00000800 /* KVA is not mapped. */
-#define B_KVAALLOC 0x00001000 /* But allocated. */
+#define B_NOREUSE 0x00000800 /* Contents not reused once released. */
+#define B_00001000 0x00001000 /* Available flag. */
#define B_INVAL 0x00002000 /* Does not contain valid info. */
-#define B_BARRIER 0x00004000 /* Write this and all preceeding first. */
+#define B_BARRIER 0x00004000 /* Write this and all preceding first. */
#define B_NOCACHE 0x00008000 /* Do not cache block after use. */
#define B_MALLOC 0x00010000 /* malloced b_data */
#define B_CLUSTEROK 0x00020000 /* Pagein op, so swap() can count it. */
-#define B_000400000 0x00040000 /* Available flag. */
-#define B_000800000 0x00080000 /* Available flag. */
+#define B_00040000 0x00040000 /* Available flag. */
+#define B_00080000 0x00080000 /* Available flag. */
#define B_00100000 0x00100000 /* Available flag. */
-#define B_DIRTY 0x00200000 /* Needs writing later (in EXT2FS). */
+#define B_00200000 0x00200000 /* Available flag. */
#define B_RELBUF 0x00400000 /* Release VMIO buffer. */
-#define B_00800000 0x00800000 /* Available flag. */
+#define B_FS_FLAG1 0x00800000 /* Available flag for FS use. */
#define B_NOCOPY 0x01000000 /* Don't copy-on-write this buf. */
-#define B_NEEDSGIANT 0x02000000 /* Buffer's vnode needs giant. */
+#define B_INFREECNT 0x02000000 /* buf is counted in numfreebufs */
#define B_PAGING 0x04000000 /* volatile paging I/O -- bypass VMIO */
#define B_MANAGED 0x08000000 /* Managed by FS. */
#define B_RAM 0x10000000 /* Read ahead mark (flag) */
@@ -226,10 +225,10 @@ struct buf {
#define B_REMFREE 0x80000000 /* Delayed bremfree */
#define PRINT_BUF_FLAGS "\20\40remfree\37cluster\36vmio\35ram\34managed" \
- "\33paging\32needsgiant\31nocopy\30b23\27relbuf\26dirty\25b20" \
+ "\33paging\32infreecnt\31nocopy\30b23\27relbuf\26b21\25b20" \
"\24b19\23b18\22clusterok\21malloc\20nocache\17b14\16inval" \
- "\15b12\14b11\13eintr\12done\11persist\10delwri\7validsuspwrt" \
- "\6cache\5deferred\4direct\3async\2needcommit\1age"
+ "\15b12\14noreuse\13eintr\12done\11b8\10delwri" \
+ "\7validsuspwrt\6cache\5deferred\4direct\3async\2needcommit\1age"
/*
* These flags are kept in b_xflags.
@@ -250,9 +249,9 @@ struct buf {
#define BV_SCANNED 0x00000001 /* VOP_FSYNC funcs mark written bufs */
#define BV_BKGRDINPROG 0x00000002 /* Background write in progress */
#define BV_BKGRDWAIT 0x00000004 /* Background write waiting */
-#define BV_INFREECNT 0x80000000 /* buf is counted in numfreebufs */
+#define BV_BKGRDERR 0x00000008 /* Error from background write */
-#define PRINT_BUF_VFLAGS "\20\40infreecnt\3bkgrdwait\2bkgrdinprog\1scanned"
+#define PRINT_BUF_VFLAGS "\20\4bkgrderr\3bkgrdwait\2bkgrdinprog\1scanned"
#ifdef _KERNEL
/*
@@ -273,7 +272,7 @@ extern const char *buf_wmesg; /* Default buffer lock message */
* Get a lock sleeping non-interruptably until it becomes available.
*/
#define BUF_LOCK(bp, locktype, interlock) \
- _lockmgr_args(&(bp)->b_lock, (locktype), (interlock), \
+ _lockmgr_args_rw(&(bp)->b_lock, (locktype), (interlock), \
LK_WMESG_DEFAULT, LK_PRIO_DEFAULT, LK_TIMO_DEFAULT, \
LOCK_FILE, LOCK_LINE)
@@ -281,7 +280,7 @@ extern const char *buf_wmesg; /* Default buffer lock message */
* Get a lock sleeping with specified interruptably and timeout.
*/
#define BUF_TIMELOCK(bp, locktype, interlock, wmesg, catch, timo) \
- _lockmgr_args(&(bp)->b_lock, (locktype) | LK_TIMELOCK, \
+ _lockmgr_args_rw(&(bp)->b_lock, (locktype) | LK_TIMELOCK, \
(interlock), (wmesg), (PRIBIO + 4) | (catch), (timo), \
LOCK_FILE, LOCK_LINE)
@@ -355,12 +354,6 @@ extern const char *buf_wmesg; /* Default buffer lock message */
_lockmgr_disown(&(bp)->b_lock, LOCK_FILE, LOCK_LINE)
#endif
-/*
- * Find out if the lock has waiters or not.
- */
-#define BUF_LOCKWAITERS(bp) \
- lockmgr_waiters(&(bp)->b_lock)
-
#endif /* _KERNEL */
struct buf_queue_head {
@@ -371,15 +364,11 @@ struct buf_queue_head {
};
/*
- * This structure describes a clustered I/O. It is stored in the b_saveaddr
- * field of the buffer on which I/O is done. At I/O completion, cluster
- * callback uses the structure to parcel I/O's to individual buffers, and
- * then free's this structure.
+ * This structure describes a clustered I/O.
*/
struct cluster_save {
long bs_bcount; /* Saved b_bcount. */
long bs_bufsize; /* Saved b_bufsize. */
- void *bs_saveaddr; /* Saved b_addr. */
int bs_nchildren; /* Number of associated buffers. */
struct buf **bs_children; /* List of associated buffers. */
};
@@ -428,7 +417,6 @@ buf_deallocate(struct buf *bp)
{
if (bioops.io_deallocate)
(*bioops.io_deallocate)(bp);
- BUF_LOCKFREE(bp);
}
static __inline int
@@ -469,33 +457,40 @@ extern int dirtybufthresh;
extern int bdwriteskip;
extern int dirtybufferflushes;
extern int altbufferflushes;
-extern int buf_maxio; /* nominal maximum I/O for buffer */
-extern struct buf *buf; /* The buffer headers. */
-extern char *buffers; /* The buffer contents. */
-extern int bufpages; /* Number of memory pages in the buffer pool. */
-extern struct buf *swbuf; /* Swap I/O buffer headers. */
extern int nswbuf; /* Number of swap I/O buffer headers. */
extern int cluster_pbuf_freecnt; /* Number of pbufs for clusters */
extern int vnode_pbuf_freecnt; /* Number of pbufs for vnode pager */
-extern caddr_t unmapped_buf;
+extern int vnode_async_pbuf_freecnt; /* Number of pbufs for vnode pager,
+ asynchronous reads */
+extern caddr_t unmapped_buf; /* Data address for unmapped buffers. */
+
+static inline int
+buf_mapped(struct buf *bp)
+{
+
+ return (bp->b_data != unmapped_buf);
+}
void runningbufwakeup(struct buf *);
void waitrunningbufspace(void);
caddr_t kern_vfs_bio_buffer_alloc(caddr_t v, long physmem_est);
void bufinit(void);
+void bufshutdown(int);
void bdata2bio(struct buf *bp, struct bio *bip);
void bwillwrite(void);
int buf_dirty_count_severe(void);
void bremfree(struct buf *);
void bremfreef(struct buf *); /* XXX Force bremfree, only for nfs. */
-int bread(struct vnode *, daddr_t, int, struct ucred *, struct buf **);
-int bread_gb(struct vnode *, daddr_t, int, struct ucred *,
- int gbflags, struct buf **);
-void breada(struct vnode *, daddr_t *, int *, int, struct ucred *);
-int breadn(struct vnode *, daddr_t, int, daddr_t *, int *, int,
- struct ucred *, struct buf **);
+#define bread(vp, blkno, size, cred, bpp) \
+ breadn_flags(vp, blkno, size, NULL, NULL, 0, cred, 0, bpp)
+#define bread_gb(vp, blkno, size, cred, gbflags, bpp) \
+ breadn_flags(vp, blkno, size, NULL, NULL, 0, cred, \
+ gbflags, bpp)
+#define breadn(vp, blkno, size, rablkno, rabsize, cnt, cred, bpp) \
+ breadn_flags(vp, blkno, size, rablkno, rabsize, cnt, cred, 0, bpp)
int breadn_flags(struct vnode *, daddr_t, int, daddr_t *, int *, int,
struct ucred *, int, struct buf **);
+void breada(struct vnode *, daddr_t *, int *, int, struct ucred *);
void bdwrite(struct buf *);
void bawrite(struct buf *);
void babarrierwrite(struct buf *);
@@ -506,6 +501,7 @@ void bufstrategy(struct bufobj *, struct buf *);
void brelse(struct buf *);
void bqrelse(struct buf *);
int vfs_bio_awrite(struct buf *);
+void vfs_drain_busy_pages(struct buf *bp);
struct buf * getpbuf(int *);
struct buf *incore(struct bufobj *, daddr_t);
struct buf *gbincore(struct bufobj *, daddr_t);
@@ -518,13 +514,9 @@ void bufdone_finish(struct buf *);
void bd_speedup(void);
int cluster_read(struct vnode *, u_quad_t, daddr_t, long,
- struct ucred *, long, int, struct buf **);
-int cluster_wbuild(struct vnode *, long, daddr_t, int);
-void cluster_write(struct vnode *, struct buf *, u_quad_t, int);
-int cluster_read_gb(struct vnode *, u_quad_t, daddr_t, long,
struct ucred *, long, int, int, struct buf **);
-int cluster_wbuild_gb(struct vnode *, long, daddr_t, int, int);
-void cluster_write_gb(struct vnode *, struct buf *, u_quad_t, int, int);
+int cluster_wbuild(struct vnode *, long, daddr_t, int, int);
+void cluster_write(struct vnode *, struct buf *, u_quad_t, int, int);
void vfs_bio_bzero_buf(struct buf *bp, int base, int size);
void vfs_bio_set_valid(struct buf *, int base, int size);
void vfs_bio_clrbuf(struct buf *);
@@ -544,9 +536,6 @@ void reassignbuf(struct buf *);
struct buf *trypbuf(int *);
void bwait(struct buf *, u_char, const char *);
void bdone(struct buf *);
-void bpin(struct buf *);
-void bunpin(struct buf *);
-void bunpin_wait(struct buf *);
#endif /* _KERNEL */
diff --git a/freebsd/sys/sys/buf_ring.h b/freebsd/sys/sys/buf_ring.h
index ee7a48ce..4fa72824 100644
--- a/freebsd/sys/sys/buf_ring.h
+++ b/freebsd/sys/sys/buf_ring.h
@@ -47,25 +47,14 @@ struct buf_ring {
int br_prod_size;
int br_prod_mask;
uint64_t br_drops;
- uint64_t br_prod_bufs;
- /*
- * Pad out to next L2 cache line
- */
- uint64_t _pad0[11];
-
- volatile uint32_t br_cons_head;
+ volatile uint32_t br_cons_head __aligned(CACHE_LINE_SIZE);
volatile uint32_t br_cons_tail;
int br_cons_size;
int br_cons_mask;
-
- /*
- * Pad out to next L2 cache line
- */
- uint64_t _pad1[14];
#ifdef DEBUG_BUFRING
struct mtx *br_lock;
#endif
- void *br_ring[0];
+ void *br_ring[0] __aligned(CACHE_LINE_SIZE);
};
/*
@@ -75,9 +64,7 @@ struct buf_ring {
static __inline int
buf_ring_enqueue(struct buf_ring *br, void *buf)
{
- uint32_t prod_head, prod_next;
- uint32_t cons_tail;
- int success;
+ uint32_t prod_head, prod_next, cons_tail;
#ifdef DEBUG_BUFRING
int i;
for (i = br->br_cons_head; i != br->br_prod_head;
@@ -89,35 +76,34 @@ buf_ring_enqueue(struct buf_ring *br, void *buf)
critical_enter();
do {
prod_head = br->br_prod_head;
+ prod_next = (prod_head + 1) & br->br_prod_mask;
cons_tail = br->br_cons_tail;
- prod_next = (prod_head + 1) & br->br_prod_mask;
-
if (prod_next == cons_tail) {
- br->br_drops++;
- critical_exit();
- return (ENOBUFS);
+ rmb();
+ if (prod_head == br->br_prod_head &&
+ cons_tail == br->br_cons_tail) {
+ br->br_drops++;
+ critical_exit();
+ return (ENOBUFS);
+ }
+ continue;
}
-
- success = atomic_cmpset_int((volatile int *)&br->br_prod_head, prod_head,
- prod_next);
- } while (success == 0);
+ } while (!atomic_cmpset_acq_int(&br->br_prod_head, prod_head, prod_next));
#ifdef DEBUG_BUFRING
if (br->br_ring[prod_head] != NULL)
panic("dangling value in enqueue");
#endif
br->br_ring[prod_head] = buf;
- wmb();
/*
* If there are other enqueues in progress
- * that preceeded us, we need to wait for them
+ * that preceded us, we need to wait for them
* to complete
*/
while (br->br_prod_tail != prod_head)
cpu_spinwait();
- br->br_prod_bufs++;
- br->br_prod_tail = prod_next;
+ atomic_store_rel_int(&br->br_prod_tail, prod_next);
critical_exit();
return (0);
}
@@ -130,41 +116,32 @@ static __inline void *
buf_ring_dequeue_mc(struct buf_ring *br)
{
uint32_t cons_head, cons_next;
- uint32_t prod_tail;
void *buf;
- int success;
critical_enter();
do {
cons_head = br->br_cons_head;
- prod_tail = br->br_prod_tail;
-
cons_next = (cons_head + 1) & br->br_cons_mask;
-
- if (cons_head == prod_tail) {
+
+ if (cons_head == br->br_prod_tail) {
critical_exit();
return (NULL);
}
-
- success = atomic_cmpset_int((volatile int *)&br->br_cons_head, cons_head,
- cons_next);
- } while (success == 0);
+ } while (!atomic_cmpset_acq_int(&br->br_cons_head, cons_head, cons_next));
buf = br->br_ring[cons_head];
#ifdef DEBUG_BUFRING
br->br_ring[cons_head] = NULL;
#endif
- rmb();
-
/*
* If there are other dequeues in progress
- * that preceeded us, we need to wait for them
+ * that preceded us, we need to wait for them
* to complete
*/
while (br->br_cons_tail != cons_head)
cpu_spinwait();
- br->br_cons_tail = cons_next;
+ atomic_store_rel_int(&br->br_cons_tail, cons_next);
critical_exit();
return (buf);
@@ -184,9 +161,38 @@ buf_ring_dequeue_sc(struct buf_ring *br)
#endif
uint32_t prod_tail;
void *buf;
-
+
+ /*
+ * This is a workaround to allow using buf_ring on ARM and ARM64.
+ * ARM64TODO: Fix buf_ring in a generic way.
+ * REMARKS: It is suspected that br_cons_head does not require
+ * load_acq operation, but this change was extensively tested
+ * and confirmed it's working. To be reviewed once again in
+ * FreeBSD-12.
+ *
+ * Preventing following situation:
+
+ * Core(0) - buf_ring_enqueue() Core(1) - buf_ring_dequeue_sc()
+ * ----------------------------------------- ----------------------------------------------
+ *
+ * cons_head = br->br_cons_head;
+ * atomic_cmpset_acq_32(&br->br_prod_head, ...));
+ * buf = br->br_ring[cons_head]; <see <1>>
+ * br->br_ring[prod_head] = buf;
+ * atomic_store_rel_32(&br->br_prod_tail, ...);
+ * prod_tail = br->br_prod_tail;
+ * if (cons_head == prod_tail)
+ * return (NULL);
+ * <condition is false and code uses invalid(old) buf>`
+ *
+ * <1> Load (on core 1) from br->br_ring[cons_head] can be reordered (speculative readed) by CPU.
+ */
+#if defined(__arm__) || defined(__aarch64__)
+ cons_head = atomic_load_acq_32(&br->br_cons_head);
+#else
cons_head = br->br_cons_head;
- prod_tail = br->br_prod_tail;
+#endif
+ prod_tail = atomic_load_acq_32(&br->br_prod_tail);
cons_next = (cons_head + 1) & br->br_cons_mask;
#ifdef PREFETCH_DEFINED
@@ -291,6 +297,37 @@ buf_ring_peek(struct buf_ring *br)
return (br->br_ring[br->br_cons_head]);
}
+static __inline void *
+buf_ring_peek_clear_sc(struct buf_ring *br)
+{
+#ifdef DEBUG_BUFRING
+ void *ret;
+
+ if (!mtx_owned(br->br_lock))
+ panic("lock not held on single consumer dequeue");
+#endif
+ /*
+ * I believe it is safe to not have a memory barrier
+ * here because we control cons and tail is worst case
+ * a lagging indicator so we worst case we might
+ * return NULL immediately after a buffer has been enqueued
+ */
+ if (br->br_cons_head == br->br_prod_tail)
+ return (NULL);
+
+#ifdef DEBUG_BUFRING
+ /*
+ * Single consumer, i.e. cons_head will not move while we are
+ * running, so atomic_swap_ptr() is not necessary here.
+ */
+ ret = br->br_ring[br->br_cons_head];
+ br->br_ring[br->br_cons_head] = NULL;
+ return (ret);
+#else
+ return (br->br_ring[br->br_cons_head]);
+#endif
+}
+
static __inline int
buf_ring_full(struct buf_ring *br)
{
diff --git a/freebsd/sys/sys/bufobj.h b/freebsd/sys/sys/bufobj.h
index 916b2565..0fa6c8ce 100644
--- a/freebsd/sys/sys/bufobj.h
+++ b/freebsd/sys/sys/bufobj.h
@@ -53,7 +53,8 @@
#include <sys/queue.h>
#include <sys/_lock.h>
-#include <sys/_mutex.h>
+#include <sys/_rwlock.h>
+#include <sys/_pctrie.h>
struct bufobj;
struct buf_ops;
@@ -62,10 +63,10 @@ extern struct buf_ops buf_ops_bio;
TAILQ_HEAD(buflists, buf);
-/* A Buffer splay list */
+/* A Buffer list & trie */
struct bufv {
struct buflists bv_hd; /* Sorted blocklist */
- struct buf *bv_root; /* Buf splay tree */
+ struct pctrie bv_root; /* Buf trie */
int bv_cnt; /* Number of buffers */
};
@@ -88,13 +89,8 @@ struct buf_ops {
#define BO_BDFLUSH(bo, bp) ((bo)->bo_ops->bop_bdflush((bo), (bp)))
struct bufobj {
- struct mtx bo_mtx; /* Mutex which protects "i" things */
- struct bufv bo_clean; /* i Clean buffers */
- struct bufv bo_dirty; /* i Dirty buffers */
- long bo_numoutput; /* i Writes in progress */
- u_int bo_flag; /* i Flags */
+ struct rwlock bo_lock; /* Lock which protects "i" things */
struct buf_ops *bo_ops; /* - Buffer operations */
- int bo_bsize; /* - Block size for i/o */
struct vm_object *bo_object; /* v Place to store VM object */
LIST_ENTRY(bufobj) bo_synclist; /* S dirty vnode list */
void *bo_private; /* private pointer */
@@ -103,6 +99,11 @@ struct bufobj {
* XXX: only to keep the syncer working
* XXX: for now.
*/
+ struct bufv bo_clean; /* i Clean buffers */
+ struct bufv bo_dirty; /* i Dirty buffers */
+ long bo_numoutput; /* i Writes in progress */
+ u_int bo_flag; /* i Flags */
+ int bo_bsize; /* - Block size for i/o */
};
/*
@@ -111,13 +112,16 @@ struct bufobj {
*/
#define BO_ONWORKLST (1 << 0) /* On syncer work-list */
#define BO_WWAIT (1 << 1) /* Wait for output to complete */
-#define BO_NEEDSGIANT (1 << 2) /* Require giant for child buffers. */
-
-#define BO_MTX(bo) (&(bo)->bo_mtx)
-#define BO_LOCK(bo) mtx_lock(BO_MTX((bo)))
-#define BO_UNLOCK(bo) mtx_unlock(BO_MTX((bo)))
-#define ASSERT_BO_LOCKED(bo) mtx_assert(BO_MTX((bo)), MA_OWNED)
-#define ASSERT_BO_UNLOCKED(bo) mtx_assert(BO_MTX((bo)), MA_NOTOWNED)
+#define BO_DEAD (1 << 2) /* Dead; only with INVARIANTS */
+
+#define BO_LOCKPTR(bo) (&(bo)->bo_lock)
+#define BO_LOCK(bo) rw_wlock(BO_LOCKPTR((bo)))
+#define BO_UNLOCK(bo) rw_wunlock(BO_LOCKPTR((bo)))
+#define BO_RLOCK(bo) rw_rlock(BO_LOCKPTR((bo)))
+#define BO_RUNLOCK(bo) rw_runlock(BO_LOCKPTR((bo)))
+#define ASSERT_BO_WLOCKED(bo) rw_assert(BO_LOCKPTR((bo)), RA_WLOCKED)
+#define ASSERT_BO_LOCKED(bo) rw_assert(BO_LOCKPTR((bo)), RA_LOCKED)
+#define ASSERT_BO_UNLOCKED(bo) rw_assert(BO_LOCKPTR((bo)), RA_UNLOCKED)
void bufobj_wdrop(struct bufobj *bo);
void bufobj_wref(struct bufobj *bo);
diff --git a/freebsd/sys/sys/bus.h b/freebsd/sys/sys/bus.h
index f0406732..6e356e9c 100644
--- a/freebsd/sys/sys/bus.h
+++ b/freebsd/sys/sys/bus.h
@@ -30,7 +30,9 @@
#define _SYS_BUS_H_
#include <machine/_limits.h>
+#include <machine/_bus.h>
#include <sys/_bus_dma.h>
+#include <sys/ioccom.h>
/**
* @defgroup NEWBUS newbus - a generic framework for managing devices
@@ -70,14 +72,66 @@ struct u_device {
char dv_pnpinfo[128]; /**< @brief Plug and play info */
char dv_location[128]; /**< @brief Where is the device? */
uint32_t dv_devflags; /**< @brief API Flags for device */
- uint16_t dv_flags; /**< @brief flags for dev date */
+ uint16_t dv_flags; /**< @brief flags for dev state */
device_state_t dv_state; /**< @brief State of attachment */
/* XXX more driver info? */
};
+/* Flags exported via dv_flags. */
+#define DF_ENABLED 0x01 /* device should be probed/attached */
+#define DF_FIXEDCLASS 0x02 /* devclass specified at create time */
+#define DF_WILDCARD 0x04 /* unit was originally wildcard */
+#define DF_DESCMALLOCED 0x08 /* description was malloced */
+#define DF_QUIET 0x10 /* don't print verbose attach message */
+#define DF_DONENOMATCH 0x20 /* don't execute DEVICE_NOMATCH again */
+#define DF_EXTERNALSOFTC 0x40 /* softc not allocated by us */
+#define DF_REBID 0x80 /* Can rebid after attach */
+#define DF_SUSPENDED 0x100 /* Device is suspended. */
+
+/**
+ * @brief Device request structure used for ioctl's.
+ *
+ * Used for ioctl's on /dev/devctl2. All device ioctl's
+ * must have parameter definitions which begin with dr_name.
+ */
+struct devreq_buffer {
+ void *buffer;
+ size_t length;
+};
+
+struct devreq {
+ char dr_name[128];
+ int dr_flags; /* request-specific flags */
+ union {
+ struct devreq_buffer dru_buffer;
+ void *dru_data;
+ } dr_dru;
+#define dr_buffer dr_dru.dru_buffer /* variable-sized buffer */
+#define dr_data dr_dru.dru_data /* fixed-size buffer */
+};
+
+#define DEV_ATTACH _IOW('D', 1, struct devreq)
+#define DEV_DETACH _IOW('D', 2, struct devreq)
+#define DEV_ENABLE _IOW('D', 3, struct devreq)
+#define DEV_DISABLE _IOW('D', 4, struct devreq)
+#define DEV_SUSPEND _IOW('D', 5, struct devreq)
+#define DEV_RESUME _IOW('D', 6, struct devreq)
+#define DEV_SET_DRIVER _IOW('D', 7, struct devreq)
+#define DEV_RESCAN _IOW('D', 9, struct devreq)
+#define DEV_DELETE _IOW('D', 10, struct devreq)
+
+/* Flags for DEV_DETACH and DEV_DISABLE. */
+#define DEVF_FORCE_DETACH 0x0000001
+
+/* Flags for DEV_SET_DRIVER. */
+#define DEVF_SET_DRIVER_DETACH 0x0000001 /* Detach existing driver. */
+
+/* Flags for DEV_DELETE. */
+#define DEVF_FORCE_DELETE 0x0000001
+
#ifdef _KERNEL
-#include <sys/queue.h>
+#include <sys/eventhandler.h>
#include <sys/kobj.h>
/**
@@ -92,6 +146,15 @@ void devctl_notify(const char *__system, const char *__subsystem,
const char *__type, const char *__data);
void devctl_queue_data_f(char *__data, int __flags);
void devctl_queue_data(char *__data);
+void devctl_safe_quote(char *__dst, const char *__src, size_t len);
+
+/**
+ * Device name parsers. Hook to allow device enumerators to map
+ * scheme-specific names to a device.
+ */
+typedef void (*dev_lookup_fn)(void *arg, const char *name,
+ device_t *result);
+EVENTHANDLER_DECLARE(dev_lookup, dev_lookup_fn);
/**
* @brief A device driver (included mainly for compatibility with
@@ -122,8 +185,7 @@ typedef struct kobj_class driver_t;
typedef struct devclass *devclass_t;
/**
- * @brief A device method (included mainly for compatibility with
- * FreeBSD 4.x).
+ * @brief A device method
*/
#define device_method_t kobj_method_t
@@ -178,11 +240,8 @@ typedef void driver_intr_t(void*);
* spls implicit in names like INTR_TYPE_TTY. In the meantime, don't
* confuse things by renaming them (Grog, 18 July 2000).
*
- * We define this in terms of bits because some devices may belong
- * to multiple classes (and therefore need to be included in
- * multiple interrupt masks, which is what this really serves to
- * indicate. Buses which do interrupt remapping will want to
- * change their type to reflect what sort of devices are underneath.
+ * Buses which do interrupt remapping will want to change their type
+ * to reflect what sort of devices are underneath.
*/
enum intr_type {
INTR_TYPE_TTY = 1,
@@ -213,6 +272,16 @@ enum intr_polarity {
INTR_POLARITY_LOW = 2
};
+/**
+ * CPU sets supported by bus_get_cpus(). Note that not all sets may be
+ * supported for a given device. If a request is not supported by a
+ * device (or its parents), then bus_get_cpus() will fail with EINVAL.
+ */
+enum cpu_sets {
+ LOCAL_CPUS = 0,
+ INTR_CPUS
+};
+
typedef int (*devop_t)(void);
/**
@@ -225,6 +294,31 @@ struct driver {
KOBJ_CLASS_FIELDS;
};
+/**
+ * @brief A resource mapping.
+ */
+struct resource_map {
+ bus_space_tag_t r_bustag;
+ bus_space_handle_t r_bushandle;
+ bus_size_t r_size;
+ void *r_vaddr;
+};
+
+/**
+ * @brief Optional properties of a resource mapping request.
+ */
+struct resource_map_request {
+ size_t size;
+ rman_res_t offset;
+ rman_res_t length;
+ vm_memattr_t memattr;
+};
+
+void resource_init_map_request_impl(struct resource_map_request *_args,
+ size_t _sz);
+#define resource_init_map_request(rmr) \
+ resource_init_map_request_impl((rmr), sizeof(*(rmr)))
+
/*
* Definitions for drivers which need to keep simple lists of resources
* for their child devices.
@@ -240,9 +334,9 @@ struct resource_list_entry {
int rid; /**< @brief resource identifier */
int flags; /**< @brief resource flags */
struct resource *res; /**< @brief the real resource when allocated */
- u_long start; /**< @brief start of resource range */
- u_long end; /**< @brief end of resource range */
- u_long count; /**< @brief count within range */
+ rman_res_t start; /**< @brief start of resource range */
+ rman_res_t end; /**< @brief end of resource range */
+ rman_res_t count; /**< @brief count within range */
};
STAILQ_HEAD(resource_list, resource_list_entry);
@@ -255,10 +349,10 @@ void resource_list_free(struct resource_list *rl);
struct resource_list_entry *
resource_list_add(struct resource_list *rl,
int type, int rid,
- u_long start, u_long end, u_long count);
+ rman_res_t start, rman_res_t end, rman_res_t count);
int resource_list_add_next(struct resource_list *rl,
int type,
- u_long start, u_long end, u_long count);
+ rman_res_t start, rman_res_t end, rman_res_t count);
int resource_list_busy(struct resource_list *rl,
int type, int rid);
int resource_list_reserved(struct resource_list *rl, int type, int rid);
@@ -271,17 +365,20 @@ struct resource *
resource_list_alloc(struct resource_list *rl,
device_t bus, device_t child,
int type, int *rid,
- u_long start, u_long end,
- u_long count, u_int flags);
+ rman_res_t start, rman_res_t end,
+ rman_res_t count, u_int flags);
int resource_list_release(struct resource_list *rl,
device_t bus, device_t child,
int type, int rid, struct resource *res);
+int resource_list_release_active(struct resource_list *rl,
+ device_t bus, device_t child,
+ int type);
struct resource *
resource_list_reserve(struct resource_list *rl,
device_t bus, device_t child,
int type, int *rid,
- u_long start, u_long end,
- u_long count, u_int flags);
+ rman_res_t start, rman_res_t end,
+ rman_res_t count, u_int flags);
int resource_list_unreserve(struct resource_list *rl,
device_t bus, device_t child,
int type, int rid);
@@ -307,12 +404,12 @@ device_t
bus_generic_add_child(device_t dev, u_int order, const char *name,
int unit);
int bus_generic_adjust_resource(device_t bus, device_t child, int type,
- struct resource *r, u_long start,
- u_long end);
+ struct resource *r, rman_res_t start,
+ rman_res_t end);
struct resource *
bus_generic_alloc_resource(device_t bus, device_t child, int type,
- int *rid, u_long start, u_long end,
- u_long count, u_int flags);
+ int *rid, rman_res_t start, rman_res_t end,
+ rman_res_t count, u_int flags);
int bus_generic_attach(device_t dev);
int bus_generic_bind_intr(device_t dev, device_t child,
struct resource *irq, int cpu);
@@ -326,12 +423,22 @@ int bus_generic_deactivate_resource(device_t dev, device_t child, int type,
int rid, struct resource *r);
int bus_generic_detach(device_t dev);
void bus_generic_driver_added(device_t dev, driver_t *driver);
+int bus_generic_get_cpus(device_t dev, device_t child, enum cpu_sets op,
+ size_t setsize, struct _cpuset *cpuset);
bus_dma_tag_t
bus_generic_get_dma_tag(device_t dev, device_t child);
+bus_space_tag_t
+ bus_generic_get_bus_tag(device_t dev, device_t child);
+int bus_generic_get_domain(device_t dev, device_t child, int *domain);
struct resource_list *
bus_generic_get_resource_list (device_t, device_t);
+int bus_generic_map_resource(device_t dev, device_t child, int type,
+ struct resource *r,
+ struct resource_map_request *args,
+ struct resource_map *map);
void bus_generic_new_pass(device_t dev);
int bus_print_child_header(device_t dev, device_t child);
+int bus_print_child_domain(device_t dev, device_t child);
int bus_print_child_footer(device_t dev, device_t child);
int bus_generic_print_child(device_t dev, device_t child);
int bus_generic_probe(device_t dev);
@@ -340,6 +447,7 @@ int bus_generic_read_ivar(device_t dev, device_t child, int which,
int bus_generic_release_resource(device_t bus, device_t child,
int type, int rid, struct resource *r);
int bus_generic_resume(device_t dev);
+int bus_generic_resume_child(device_t dev, device_t child);
int bus_generic_setup_intr(device_t dev, device_t child,
struct resource *irq, int flags,
driver_filter_t *filter, driver_intr_t *intr,
@@ -347,21 +455,26 @@ int bus_generic_setup_intr(device_t dev, device_t child,
struct resource *
bus_generic_rl_alloc_resource (device_t, device_t, int, int *,
- u_long, u_long, u_long, u_int);
+ rman_res_t, rman_res_t, rman_res_t, u_int);
void bus_generic_rl_delete_resource (device_t, device_t, int, int);
-int bus_generic_rl_get_resource (device_t, device_t, int, int, u_long *,
- u_long *);
-int bus_generic_rl_set_resource (device_t, device_t, int, int, u_long,
- u_long);
+int bus_generic_rl_get_resource (device_t, device_t, int, int, rman_res_t *,
+ rman_res_t *);
+int bus_generic_rl_set_resource (device_t, device_t, int, int, rman_res_t,
+ rman_res_t);
int bus_generic_rl_release_resource (device_t, device_t, int, int,
struct resource *);
int bus_generic_shutdown(device_t dev);
int bus_generic_suspend(device_t dev);
+int bus_generic_suspend_child(device_t dev, device_t child);
int bus_generic_teardown_intr(device_t dev, device_t child,
struct resource *irq, void *cookie);
+int bus_generic_unmap_resource(device_t dev, device_t child, int type,
+ struct resource *r,
+ struct resource_map *map);
int bus_generic_write_ivar(device_t dev, device_t child, int which,
uintptr_t value);
+int bus_null_rescan(device_t dev);
/*
* Wrapper functions for the BUS_*_RESOURCE methods to make client code
@@ -380,15 +493,24 @@ void bus_release_resources(device_t dev, const struct resource_spec *rs,
struct resource **res);
int bus_adjust_resource(device_t child, int type, struct resource *r,
- u_long start, u_long end);
+ rman_res_t start, rman_res_t end);
struct resource *bus_alloc_resource(device_t dev, int type, int *rid,
- u_long start, u_long end, u_long count,
- u_int flags);
+ rman_res_t start, rman_res_t end,
+ rman_res_t count, u_int flags);
int bus_activate_resource(device_t dev, int type, int rid,
struct resource *r);
int bus_deactivate_resource(device_t dev, int type, int rid,
struct resource *r);
+int bus_map_resource(device_t dev, int type, struct resource *r,
+ struct resource_map_request *args,
+ struct resource_map *map);
+int bus_unmap_resource(device_t dev, int type, struct resource *r,
+ struct resource_map *map);
+int bus_get_cpus(device_t dev, enum cpu_sets op, size_t setsize,
+ struct _cpuset *cpuset);
bus_dma_tag_t bus_get_dma_tag(device_t dev);
+bus_space_tag_t bus_get_bus_tag(device_t dev);
+int bus_get_domain(device_t dev, int *domain);
int bus_release_resource(device_t dev, int type, int rid,
struct resource *r);
int bus_free_resource(device_t dev, int type, struct resource *r);
@@ -398,13 +520,13 @@ int bus_setup_intr(device_t dev, struct resource *r, int flags,
int bus_teardown_intr(device_t dev, struct resource *r, void *cookie);
int bus_bind_intr(device_t dev, struct resource *r, int cpu);
int bus_describe_intr(device_t dev, struct resource *irq, void *cookie,
- const char *fmt, ...);
+ const char *fmt, ...) __printflike(4, 5);
int bus_set_resource(device_t dev, int type, int rid,
- u_long start, u_long count);
+ rman_res_t start, rman_res_t count);
int bus_get_resource(device_t dev, int type, int rid,
- u_long *startp, u_long *countp);
-u_long bus_get_resource_start(device_t dev, int type, int rid);
-u_long bus_get_resource_count(device_t dev, int type, int rid);
+ rman_res_t *startp, rman_res_t *countp);
+rman_res_t bus_get_resource_start(device_t dev, int type, int rid);
+rman_res_t bus_get_resource_count(device_t dev, int type, int rid);
void bus_delete_resource(device_t dev, int type, int rid);
int bus_child_present(device_t child);
int bus_child_pnpinfo_str(device_t child, char *buf, size_t buflen);
@@ -414,7 +536,14 @@ void bus_enumerate_hinted_children(device_t bus);
static __inline struct resource *
bus_alloc_resource_any(device_t dev, int type, int *rid, u_int flags)
{
- return (bus_alloc_resource(dev, type, rid, 0ul, ~0ul, 1, flags));
+ return (bus_alloc_resource(dev, type, rid, 0, ~0, 1, flags));
+}
+
+static __inline struct resource *
+bus_alloc_resource_anywhere(device_t dev, int type, int *rid,
+ rman_res_t count, u_int flags)
+{
+ return (bus_alloc_resource(dev, type, rid, 0, ~0, count, flags));
}
/*
@@ -450,7 +579,9 @@ struct sysctl_oid *device_get_sysctl_tree(device_t dev);
int device_is_alive(device_t dev); /* did probe succeed? */
int device_is_attached(device_t dev); /* did attach succeed? */
int device_is_enabled(device_t dev);
+int device_is_suspended(device_t dev);
int device_is_quiet(device_t dev);
+device_t device_lookup_by_name(const char *name);
int device_print_prettyname(device_t dev);
int device_printf(device_t dev, const char *, ...) __printflike(2, 3);
int device_probe(device_t dev);
@@ -461,6 +592,7 @@ void device_quiet(device_t dev);
void device_set_desc(device_t dev, const char* desc);
void device_set_desc_copy(device_t dev, const char* desc);
int device_set_devclass(device_t dev, const char *classname);
+int device_set_devclass_fixed(device_t dev, const char *classname);
int device_set_driver(device_t dev, driver_t *driver);
void device_set_flags(device_t dev, u_int32_t flags);
void device_set_softc(device_t dev, void *softc);
@@ -513,6 +645,8 @@ int resource_set_long(const char *name, int unit, const char *resname,
long value);
int resource_set_string(const char *name, int unit, const char *resname,
const char *value);
+int resource_unset_value(const char *name, int unit, const char *resname);
+
/*
* Functions for maintaining and checking consistency of
* bus information exported to userspace.
@@ -548,7 +682,7 @@ void bus_data_generation_update(void);
#define BUS_PROBE_DEFAULT (-20) /* Base OS default driver */
#define BUS_PROBE_LOW_PRIORITY (-40) /* Older, less desirable drivers */
#define BUS_PROBE_GENERIC (-100) /* generic driver for dev */
-#define BUS_PROBE_HOOVER (-500) /* Generic dev for all devs on bus */
+#define BUS_PROBE_HOOVER (-1000000) /* Driver for any dev on bus */
#define BUS_PROBE_NOWILDCARD (-2000000000) /* No wildcard device matches */
/**
@@ -569,6 +703,12 @@ void bus_data_generation_update(void);
#define BUS_PASS_SCHEDULER 60 /* Start scheduler. */
#define BUS_PASS_DEFAULT __INT_MAX /* Everything else. */
+#define BUS_PASS_ORDER_FIRST 0
+#define BUS_PASS_ORDER_EARLY 2
+#define BUS_PASS_ORDER_MIDDLE 5
+#define BUS_PASS_ORDER_LATE 7
+#define BUS_PASS_ORDER_LAST 9
+
extern int bus_current_pass;
void bus_set_pass(int pass);
diff --git a/freebsd/sys/sys/bus_dma.h b/freebsd/sys/sys/bus_dma.h
index 6e91a012..1a2ecd6b 100644
--- a/freebsd/sys/sys/bus_dma.h
+++ b/freebsd/sys/sys/bus_dma.h
@@ -168,7 +168,7 @@ void busdma_lock_mutex(void *arg, bus_dma_lock_op_t op);
*/
/* XXX Should probably allow specification of alignment */
int bus_dma_tag_create(bus_dma_tag_t parent, bus_size_t alignment,
- bus_size_t boundary, bus_addr_t lowaddr,
+ bus_addr_t boundary, bus_addr_t lowaddr,
bus_addr_t highaddr, bus_dma_filter_t *filtfunc,
void *filtfuncarg, bus_size_t maxsize, int nsegments,
bus_size_t maxsegsz, int flags, bus_dma_lock_t *lockfunc,
@@ -240,6 +240,15 @@ int bus_dmamap_load_mem(bus_dma_tag_t dmat, bus_dmamap_t map,
void *callback_arg, int flags);
/*
+ * Placeholder for use by busdma implementations which do not benefit
+ * from optimized procedure to load an array of vm_page_t. Falls back
+ * to do _bus_dmamap_load_phys() in loop.
+ */
+int bus_dmamap_load_ma_triv(bus_dma_tag_t dmat, bus_dmamap_t map,
+ struct vm_page **ma, bus_size_t tlen, int ma_offs, int flags,
+ bus_dma_segment_t *segs, int *segp);
+
+/*
* XXX sparc64 uses the same interface, but a much different implementation.
* <machine/bus_dma.h> for the sparc64 arch contains the equivalent
* declarations.
@@ -273,13 +282,25 @@ int bus_dmamem_alloc(bus_dma_tag_t dmat, void** vaddr, int flags,
void bus_dmamem_free(bus_dma_tag_t dmat, void *vaddr, bus_dmamap_t map);
/*
- * Perform a synchronization operation on the given map.
+ * Perform a synchronization operation on the given map. If the map
+ * is NULL we have a fully IO-coherent system. On every ARM architecture
+ * there must be a memory barrier placed to ensure that all data
+ * accesses are visible before going any further.
*/
void _bus_dmamap_sync(bus_dma_tag_t, bus_dmamap_t, bus_dmasync_op_t);
+#if defined(__arm__)
+ #define __BUS_DMAMAP_SYNC_DEFAULT mb()
+#elif defined(__aarch64__)
+ #define __BUS_DMAMAP_SYNC_DEFAULT dmb(sy)
+#else
+ #define __BUS_DMAMAP_SYNC_DEFAULT do {} while (0)
+#endif
#define bus_dmamap_sync(dmat, dmamap, op) \
do { \
if ((dmamap) != NULL) \
_bus_dmamap_sync(dmat, dmamap, op); \
+ else \
+ __BUS_DMAMAP_SYNC_DEFAULT; \
} while (0)
/*
@@ -317,6 +338,10 @@ int _bus_dmamap_load_phys(bus_dma_tag_t dmat, bus_dmamap_t map,
vm_paddr_t paddr, bus_size_t buflen,
int flags, bus_dma_segment_t *segs, int *segp);
+int _bus_dmamap_load_ma(bus_dma_tag_t dmat, bus_dmamap_t map,
+ struct vm_page **ma, bus_size_t tlen, int ma_offs, int flags,
+ bus_dma_segment_t *segs, int *segp);
+
bus_dma_segment_t *_bus_dmamap_complete(bus_dma_tag_t dmat,
bus_dmamap_t map,
bus_dma_segment_t *segs,
diff --git a/freebsd/sys/sys/callout.h b/freebsd/sys/sys/callout.h
index 95b9a32b..f58fa587 100644
--- a/freebsd/sys/sys/callout.h
+++ b/freebsd/sys/sys/callout.h
@@ -43,45 +43,95 @@
#define CALLOUT_LOCAL_ALLOC 0x0001 /* was allocated from callfree */
#define CALLOUT_ACTIVE 0x0002 /* callout is currently active */
#define CALLOUT_PENDING 0x0004 /* callout is waiting for timeout */
-#define CALLOUT_MPSAFE 0x0008 /* callout handler is mp safe */
+#define CALLOUT_MPSAFE 0x0008 /* deprecated */
#define CALLOUT_RETURNUNLOCKED 0x0010 /* handler returns with mtx unlocked */
#define CALLOUT_SHAREDLOCK 0x0020 /* callout lock held in shared mode */
#define CALLOUT_DFRMIGRATION 0x0040 /* callout in deferred migration mode */
+#define CALLOUT_PROCESSED 0x0080 /* callout in wheel or processing list? */
+#define CALLOUT_DIRECT 0x0100 /* allow exec from hw int context */
+
+#define C_DIRECT_EXEC 0x0001 /* direct execution of callout */
+#define C_PRELBITS 7
+#define C_PRELRANGE ((1 << C_PRELBITS) - 1)
+#define C_PREL(x) (((x) + 1) << 1)
+#define C_PRELGET(x) (int)((((x) >> 1) & C_PRELRANGE) - 1)
+#define C_HARDCLOCK 0x0100 /* align to hardclock() calls */
+#define C_ABSOLUTE 0x0200 /* event time is absolute. */
+#define C_PRECALC 0x0400 /* event time is pre-calculated. */
struct callout_handle {
struct callout *callout;
};
-#ifdef _KERNEL
-extern int ncallout;
+/* Flags for callout_stop_safe() */
+#define CS_DRAIN 0x0001 /* callout_drain(), wait allowed */
+#define CS_EXECUTING 0x0002 /* Positive return value indicates that
+ the callout was executing */
+#ifdef _KERNEL
+/*
+ * Note the flags field is actually *two* fields. The c_flags
+ * field is the one that caller operations that may, or may not have
+ * a lock touches i.e. callout_deactivate(). The other, the c_iflags,
+ * is the internal flags that *must* be kept correct on which the
+ * callout system depend on e.g. callout_pending().
+ * The c_iflag is used internally by the callout system to determine which
+ * list the callout is on and track internal state. Callers *should not*
+ * use the c_flags field directly but should use the macros provided.
+ *
+ * The c_iflags field holds internal flags that are protected by internal
+ * locks of the callout subsystem. The c_flags field holds external flags.
+ * The caller must hold its own lock while manipulating or reading external
+ * flags via callout_active(), callout_deactivate(), callout_reset*(), or
+ * callout_stop() to avoid races.
+ */
#define callout_active(c) ((c)->c_flags & CALLOUT_ACTIVE)
#define callout_deactivate(c) ((c)->c_flags &= ~CALLOUT_ACTIVE)
-#define callout_drain(c) _callout_stop_safe(c, 1)
+#define callout_drain(c) _callout_stop_safe(c, CS_DRAIN, NULL)
void callout_init(struct callout *, int);
void _callout_init_lock(struct callout *, struct lock_object *, int);
#define callout_init_mtx(c, mtx, flags) \
_callout_init_lock((c), ((mtx) != NULL) ? &(mtx)->lock_object : \
NULL, (flags))
+#define callout_init_rm(c, rm, flags) \
+ _callout_init_lock((c), ((rm) != NULL) ? &(rm)->lock_object : \
+ NULL, (flags))
#define callout_init_rw(c, rw, flags) \
_callout_init_lock((c), ((rw) != NULL) ? &(rw)->lock_object : \
NULL, (flags))
-#define callout_pending(c) ((c)->c_flags & CALLOUT_PENDING)
-int callout_reset_on(struct callout *, int, void (*)(void *), void *, int);
+#define callout_pending(c) ((c)->c_iflags & CALLOUT_PENDING)
+int callout_reset_sbt_on(struct callout *, sbintime_t, sbintime_t,
+ void (*)(void *), void *, int, int);
+#define callout_reset_sbt(c, sbt, pr, fn, arg, flags) \
+ callout_reset_sbt_on((c), (sbt), (pr), (fn), (arg), -1, (flags))
+#define callout_reset_sbt_curcpu(c, sbt, pr, fn, arg, flags) \
+ callout_reset_sbt_on((c), (sbt), (pr), (fn), (arg), PCPU_GET(cpuid),\
+ (flags))
+#define callout_reset_on(c, to_ticks, fn, arg, cpu) \
+ callout_reset_sbt_on((c), tick_sbt * (to_ticks), 0, (fn), (arg), \
+ (cpu), C_HARDCLOCK)
#define callout_reset(c, on_tick, fn, arg) \
- callout_reset_on((c), (on_tick), (fn), (arg), (c)->c_cpu)
+ callout_reset_on((c), (on_tick), (fn), (arg), -1)
#define callout_reset_curcpu(c, on_tick, fn, arg) \
callout_reset_on((c), (on_tick), (fn), (arg), PCPU_GET(cpuid))
+#define callout_schedule_sbt_on(c, sbt, pr, cpu, flags) \
+ callout_reset_sbt_on((c), (sbt), (pr), (c)->c_func, (c)->c_arg, \
+ (cpu), (flags))
+#define callout_schedule_sbt(c, sbt, pr, flags) \
+ callout_schedule_sbt_on((c), (sbt), (pr), -1, (flags))
+#define callout_schedule_sbt_curcpu(c, sbt, pr, flags) \
+ callout_schedule_sbt_on((c), (sbt), (pr), PCPU_GET(cpuid), (flags))
int callout_schedule(struct callout *, int);
int callout_schedule_on(struct callout *, int, int);
#define callout_schedule_curcpu(c, on_tick) \
callout_schedule_on((c), (on_tick), PCPU_GET(cpuid))
-#define callout_stop(c) _callout_stop_safe(c, 0)
-int _callout_stop_safe(struct callout *, int);
-void callout_tick(void);
-int callout_tickstofirst(int limit);
-extern void (*callout_new_inserted)(int cpu, int ticks);
-
+#define callout_stop(c) _callout_stop_safe(c, 0, NULL)
+int _callout_stop_safe(struct callout *, int, void (*)(void *));
+void callout_process(sbintime_t now);
+#define callout_async_drain(c, d) \
+ _callout_stop_safe(c, 0, d)
+void callout_when(sbintime_t sbt, sbintime_t precision, int flags,
+ sbintime_t *sbt_res, sbintime_t *prec_res);
#endif
#endif /* _SYS_CALLOUT_H_ */
diff --git a/freebsd/sys/sys/capability.h b/freebsd/sys/sys/capability.h
index 81446a28..8b1c229f 100644
--- a/freebsd/sys/sys/capability.h
+++ b/freebsd/sys/sys/capability.h
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2008-2010 Robert N. M. Watson
+ * Copyright (c) 2014 Robert N. M. Watson
* All rights reserved.
*
* This software was developed at the University of Cambridge Computer
@@ -30,180 +30,14 @@
*/
/*
- * Definitions for FreeBSD capabilities facility.
+ * Historically, the key userspace and kernel Capsicum definitions were found
+ * in this file. However, it conflicted with POSIX.1e's capability.h, so has
+ * been renamed capsicum.h. The file remains for backwards compatibility
+ * reasons as a nested include.
*/
#ifndef _SYS_CAPABILITY_H_
#define _SYS_CAPABILITY_H_
-#include <sys/cdefs.h>
-#include <sys/types.h>
-
-#include <sys/file.h>
-
-/*
- * Possible rights on capabilities.
- *
- * Notes:
- * Some system calls don't require a capability in order to perform an
- * operation on an fd. These include: close, dup, dup2.
- *
- * sendfile is authorized using CAP_READ on the file and CAP_WRITE on the
- * socket.
- *
- * mmap() and aio*() system calls will need special attention as they may
- * involve reads or writes depending a great deal on context.
- */
-
-/* General file I/O. */
-#define CAP_READ 0x0000000000000001ULL /* read/recv */
-#define CAP_WRITE 0x0000000000000002ULL /* write/send */
-#define CAP_MMAP 0x0000000000000004ULL /* mmap */
-#define CAP_MAPEXEC 0x0000000000000008ULL /* mmap(2) as exec */
-#define CAP_FEXECVE 0x0000000000000010ULL
-#define CAP_FSYNC 0x0000000000000020ULL
-#define CAP_FTRUNCATE 0x0000000000000040ULL
-#define CAP_SEEK 0x0000000000000080ULL
-
-/* VFS methods. */
-#define CAP_FCHFLAGS 0x0000000000000100ULL
-#define CAP_FCHDIR 0x0000000000000200ULL
-#define CAP_FCHMOD 0x0000000000000400ULL
-#define CAP_FCHOWN 0x0000000000000800ULL
-#define CAP_FCNTL 0x0000000000001000ULL
-#define CAP_FPATHCONF 0x0000000000002000ULL
-#define CAP_FLOCK 0x0000000000004000ULL
-#define CAP_FSCK 0x0000000000008000ULL
-#define CAP_FSTAT 0x0000000000010000ULL
-#define CAP_FSTATFS 0x0000000000020000ULL
-#define CAP_FUTIMES 0x0000000000040000ULL
-#define CAP_CREATE 0x0000000000080000ULL
-#define CAP_DELETE 0x0000000000100000ULL
-#define CAP_MKDIR 0x0000000000200000ULL
-#define CAP_RMDIR 0x0000000000400000ULL
-#define CAP_MKFIFO 0x0000000000800000ULL
-
-/* Lookups - used to constrain *at() calls. */
-#define CAP_LOOKUP 0x0000000001000000ULL
-
-/* Extended attributes. */
-#define CAP_EXTATTR_DELETE 0x0000000002000000ULL
-#define CAP_EXTATTR_GET 0x0000000004000000ULL
-#define CAP_EXTATTR_LIST 0x0000000008000000ULL
-#define CAP_EXTATTR_SET 0x0000000010000000ULL
-
-/* Access Control Lists. */
-#define CAP_ACL_CHECK 0x0000000020000000ULL
-#define CAP_ACL_DELETE 0x0000000040000000ULL
-#define CAP_ACL_GET 0x0000000080000000ULL
-#define CAP_ACL_SET 0x0000000100000000ULL
-
-/* Socket operations. */
-#define CAP_ACCEPT 0x0000000200000000ULL
-#define CAP_BIND 0x0000000400000000ULL
-#define CAP_CONNECT 0x0000000800000000ULL
-#define CAP_GETPEERNAME 0x0000001000000000ULL
-#define CAP_GETSOCKNAME 0x0000002000000000ULL
-#define CAP_GETSOCKOPT 0x0000004000000000ULL
-#define CAP_LISTEN 0x0000008000000000ULL
-#define CAP_PEELOFF 0x0000010000000000ULL
-#define CAP_SETSOCKOPT 0x0000020000000000ULL
-#define CAP_SHUTDOWN 0x0000040000000000ULL
-
-#define CAP_SOCK_ALL \
- (CAP_ACCEPT | CAP_BIND | CAP_CONNECT \
- | CAP_GETPEERNAME | CAP_GETSOCKNAME | CAP_GETSOCKOPT \
- | CAP_LISTEN | CAP_PEELOFF | CAP_SETSOCKOPT | CAP_SHUTDOWN)
-
-/* Mandatory Access Control. */
-#define CAP_MAC_GET 0x0000080000000000ULL
-#define CAP_MAC_SET 0x0000100000000000ULL
-
-/* Methods on semaphores. */
-#define CAP_SEM_GETVALUE 0x0000200000000000ULL
-#define CAP_SEM_POST 0x0000400000000000ULL
-#define CAP_SEM_WAIT 0x0000800000000000ULL
-
-/* kqueue events. */
-#define CAP_POLL_EVENT 0x0001000000000000ULL
-#define CAP_POST_EVENT 0x0002000000000000ULL
-
-/* Strange and powerful rights that should not be given lightly. */
-#define CAP_IOCTL 0x0004000000000000ULL
-#define CAP_TTYHOOK 0x0008000000000000ULL
-
-/* Process management via process descriptors. */
-#define CAP_PDGETPID 0x0010000000000000ULL
-#define CAP_PDWAIT 0x0020000000000000ULL
-#define CAP_PDKILL 0x0040000000000000ULL
-
-/* The mask of all valid method rights. */
-#define CAP_MASK_VALID 0x007fffffffffffffULL
-
-#ifdef _KERNEL
-
-#define IN_CAPABILITY_MODE(td) (td->td_ucred->cr_flags & CRED_FLAG_CAPMODE)
-
-/*
- * Create a capability to wrap a file object.
- */
-int kern_capwrap(struct thread *td, struct file *fp, cap_rights_t rights,
- int *capfd);
-
-/*
- * Unwrap a capability if its rights mask is a superset of 'rights'.
- *
- * Unwrapping a non-capability is effectively a no-op; the value of fp_cap
- * is simply copied into fpp.
- */
-int cap_funwrap(struct file *fp_cap, cap_rights_t rights,
- struct file **fpp);
-int cap_funwrap_mmap(struct file *fp_cap, cap_rights_t rights,
- u_char *maxprotp, struct file **fpp);
-
-/*
- * For the purposes of procstat(1) and similar tools, allow kern_descrip.c to
- * extract the rights from a capability. However, this should not be used by
- * kernel code generally, instead cap_funwrap() should be used in order to
- * keep all access control in one place.
- */
-cap_rights_t cap_rights(struct file *fp_cap);
-
-#else /* !_KERNEL */
-
-__BEGIN_DECLS
-
-/*
- * cap_enter(): Cause the process to enter capability mode, which will
- * prevent it from directly accessing global namespaces. System calls will
- * be limited to process-local, process-inherited, or file descriptor
- * operations. If already in capability mode, a no-op.
- *
- * Currently, process-inherited operations are not properly handled -- in
- * particular, we're interested in things like waitpid(2), kill(2), etc,
- * being properly constrained. One possible solution is to introduce process
- * descriptors.
- */
-int cap_enter(void);
-
-/*
- * cap_getmode(): Are we in capability mode?
- */
-int cap_getmode(u_int* modep);
-
-/*
- * cap_new(): Create a new capability derived from an existing file
- * descriptor with the specified rights. If the existing file descriptor is
- * a capability, then the new rights must be a subset of the existing rights.
- */
-int cap_new(int fd, cap_rights_t rights);
-
-/*
- * cap_getrights(): Query the rights on a capability.
- */
-int cap_getrights(int fd, cap_rights_t *rightsp);
-
-__END_DECLS
-
-#endif /* !_KERNEL */
+#include <sys/capsicum.h>
#endif /* !_SYS_CAPABILITY_H_ */
diff --git a/freebsd/sys/sys/caprights.h b/freebsd/sys/sys/caprights.h
new file mode 100644
index 00000000..eb8e454f
--- /dev/null
+++ b/freebsd/sys/sys/caprights.h
@@ -0,0 +1,61 @@
+/*-
+ * Copyright (c) 2013 FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Pawel Jakub Dawidek under sponsorship from
+ * the FreeBSD Foundation.
+ *
+ * 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_CAPRIGHTS_H_
+#define _SYS_CAPRIGHTS_H_
+
+/*
+ * The top two bits in the first element of the cr_rights[] array contain
+ * total number of elements in the array - 2. This means if those two bits are
+ * equal to 0, we have 2 array elements.
+ * The top two bits in all remaining array elements should be 0.
+ * The next five bits contain array index. Only one bit is used and bit position
+ * in this five-bits range defines array index. This means there can be at most
+ * five array elements.
+ */
+#define CAP_RIGHTS_VERSION_00 0
+/*
+#define CAP_RIGHTS_VERSION_01 1
+#define CAP_RIGHTS_VERSION_02 2
+#define CAP_RIGHTS_VERSION_03 3
+*/
+#define CAP_RIGHTS_VERSION CAP_RIGHTS_VERSION_00
+
+struct cap_rights {
+ uint64_t cr_rights[CAP_RIGHTS_VERSION + 2];
+};
+
+#ifndef _CAP_RIGHTS_T_DECLARED
+#define _CAP_RIGHTS_T_DECLARED
+typedef struct cap_rights cap_rights_t;
+#endif
+
+#endif /* !_SYS_CAPRIGHTS_H_ */
diff --git a/freebsd/sys/sys/capsicum.h b/freebsd/sys/sys/capsicum.h
new file mode 100644
index 00000000..af4da032
--- /dev/null
+++ b/freebsd/sys/sys/capsicum.h
@@ -0,0 +1,450 @@
+/*-
+ * Copyright (c) 2008-2010, 2015 Robert N. M. Watson
+ * Copyright (c) 2012 FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed at the University of Cambridge Computer
+ * Laboratory with support from a grant from Google, Inc.
+ *
+ * Portions of this software were developed by Pawel Jakub Dawidek under
+ * sponsorship from the FreeBSD Foundation.
+ *
+ * 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$
+ */
+
+/*
+ * Definitions for FreeBSD capabilities facility.
+ */
+#ifndef _SYS_CAPSICUM_H_
+#define _SYS_CAPSICUM_H_
+
+#include <sys/cdefs.h>
+#include <rtems/bsd/sys/param.h>
+
+#include <sys/caprights.h>
+#include <sys/file.h>
+#include <sys/fcntl.h>
+
+#ifndef _KERNEL
+#include <stdbool.h>
+#endif
+
+#define CAPRIGHT(idx, bit) ((1ULL << (57 + (idx))) | (bit))
+
+/*
+ * Possible rights on capabilities.
+ *
+ * Notes:
+ * Some system calls don't require a capability in order to perform an
+ * operation on an fd. These include: close, dup, dup2.
+ *
+ * sendfile is authorized using CAP_READ on the file and CAP_WRITE on the
+ * socket.
+ *
+ * mmap() and aio*() system calls will need special attention as they may
+ * involve reads or writes depending a great deal on context.
+ */
+
+/* INDEX 0 */
+
+/*
+ * General file I/O.
+ */
+/* Allows for openat(O_RDONLY), read(2), readv(2). */
+#define CAP_READ CAPRIGHT(0, 0x0000000000000001ULL)
+/* Allows for openat(O_WRONLY | O_APPEND), write(2), writev(2). */
+#define CAP_WRITE CAPRIGHT(0, 0x0000000000000002ULL)
+/* Allows for lseek(fd, 0, SEEK_CUR). */
+#define CAP_SEEK_TELL CAPRIGHT(0, 0x0000000000000004ULL)
+/* Allows for lseek(2). */
+#define CAP_SEEK (CAP_SEEK_TELL | 0x0000000000000008ULL)
+/* Allows for aio_read(2), pread(2), preadv(2). */
+#define CAP_PREAD (CAP_SEEK | CAP_READ)
+/*
+ * Allows for aio_write(2), openat(O_WRONLY) (without O_APPEND), pwrite(2),
+ * pwritev(2).
+ */
+#define CAP_PWRITE (CAP_SEEK | CAP_WRITE)
+/* Allows for mmap(PROT_NONE). */
+#define CAP_MMAP CAPRIGHT(0, 0x0000000000000010ULL)
+/* Allows for mmap(PROT_READ). */
+#define CAP_MMAP_R (CAP_MMAP | CAP_SEEK | CAP_READ)
+/* Allows for mmap(PROT_WRITE). */
+#define CAP_MMAP_W (CAP_MMAP | CAP_SEEK | CAP_WRITE)
+/* Allows for mmap(PROT_EXEC). */
+#define CAP_MMAP_X (CAP_MMAP | CAP_SEEK | 0x0000000000000020ULL)
+/* Allows for mmap(PROT_READ | PROT_WRITE). */
+#define CAP_MMAP_RW (CAP_MMAP_R | CAP_MMAP_W)
+/* Allows for mmap(PROT_READ | PROT_EXEC). */
+#define CAP_MMAP_RX (CAP_MMAP_R | CAP_MMAP_X)
+/* Allows for mmap(PROT_WRITE | PROT_EXEC). */
+#define CAP_MMAP_WX (CAP_MMAP_W | CAP_MMAP_X)
+/* Allows for mmap(PROT_READ | PROT_WRITE | PROT_EXEC). */
+#define CAP_MMAP_RWX (CAP_MMAP_R | CAP_MMAP_W | CAP_MMAP_X)
+/* Allows for openat(O_CREAT). */
+#define CAP_CREATE CAPRIGHT(0, 0x0000000000000040ULL)
+/* Allows for openat(O_EXEC) and fexecve(2) in turn. */
+#define CAP_FEXECVE CAPRIGHT(0, 0x0000000000000080ULL)
+/* Allows for openat(O_SYNC), openat(O_FSYNC), fsync(2), aio_fsync(2). */
+#define CAP_FSYNC CAPRIGHT(0, 0x0000000000000100ULL)
+/* Allows for openat(O_TRUNC), ftruncate(2). */
+#define CAP_FTRUNCATE CAPRIGHT(0, 0x0000000000000200ULL)
+
+/* Lookups - used to constrain *at() calls. */
+#define CAP_LOOKUP CAPRIGHT(0, 0x0000000000000400ULL)
+
+/* VFS methods. */
+/* Allows for fchdir(2). */
+#define CAP_FCHDIR CAPRIGHT(0, 0x0000000000000800ULL)
+/* Allows for fchflags(2). */
+#define CAP_FCHFLAGS CAPRIGHT(0, 0x0000000000001000ULL)
+/* Allows for fchflags(2) and chflagsat(2). */
+#define CAP_CHFLAGSAT (CAP_FCHFLAGS | CAP_LOOKUP)
+/* Allows for fchmod(2). */
+#define CAP_FCHMOD CAPRIGHT(0, 0x0000000000002000ULL)
+/* Allows for fchmod(2) and fchmodat(2). */
+#define CAP_FCHMODAT (CAP_FCHMOD | CAP_LOOKUP)
+/* Allows for fchown(2). */
+#define CAP_FCHOWN CAPRIGHT(0, 0x0000000000004000ULL)
+/* Allows for fchown(2) and fchownat(2). */
+#define CAP_FCHOWNAT (CAP_FCHOWN | CAP_LOOKUP)
+/* Allows for fcntl(2). */
+#define CAP_FCNTL CAPRIGHT(0, 0x0000000000008000ULL)
+/*
+ * Allows for flock(2), openat(O_SHLOCK), openat(O_EXLOCK),
+ * fcntl(F_SETLK_REMOTE), fcntl(F_SETLKW), fcntl(F_SETLK), fcntl(F_GETLK).
+ */
+#define CAP_FLOCK CAPRIGHT(0, 0x0000000000010000ULL)
+/* Allows for fpathconf(2). */
+#define CAP_FPATHCONF CAPRIGHT(0, 0x0000000000020000ULL)
+/* Allows for UFS background-fsck operations. */
+#define CAP_FSCK CAPRIGHT(0, 0x0000000000040000ULL)
+/* Allows for fstat(2). */
+#define CAP_FSTAT CAPRIGHT(0, 0x0000000000080000ULL)
+/* Allows for fstat(2), fstatat(2) and faccessat(2). */
+#define CAP_FSTATAT (CAP_FSTAT | CAP_LOOKUP)
+/* Allows for fstatfs(2). */
+#define CAP_FSTATFS CAPRIGHT(0, 0x0000000000100000ULL)
+/* Allows for futimens(2) and futimes(2). */
+#define CAP_FUTIMES CAPRIGHT(0, 0x0000000000200000ULL)
+/* Allows for futimens(2), futimes(2), futimesat(2) and utimensat(2). */
+#define CAP_FUTIMESAT (CAP_FUTIMES | CAP_LOOKUP)
+/* Allows for linkat(2) (target directory descriptor). */
+#define CAP_LINKAT_TARGET (CAP_LOOKUP | 0x0000000000400000ULL)
+/* Allows for mkdirat(2). */
+#define CAP_MKDIRAT (CAP_LOOKUP | 0x0000000000800000ULL)
+/* Allows for mkfifoat(2). */
+#define CAP_MKFIFOAT (CAP_LOOKUP | 0x0000000001000000ULL)
+/* Allows for mknodat(2). */
+#define CAP_MKNODAT (CAP_LOOKUP | 0x0000000002000000ULL)
+/* Allows for renameat(2) (source directory descriptor). */
+#define CAP_RENAMEAT_SOURCE (CAP_LOOKUP | 0x0000000004000000ULL)
+/* Allows for symlinkat(2). */
+#define CAP_SYMLINKAT (CAP_LOOKUP | 0x0000000008000000ULL)
+/*
+ * Allows for unlinkat(2) and renameat(2) if destination object exists and
+ * will be removed.
+ */
+#define CAP_UNLINKAT (CAP_LOOKUP | 0x0000000010000000ULL)
+
+/* Socket operations. */
+/* Allows for accept(2) and accept4(2). */
+#define CAP_ACCEPT CAPRIGHT(0, 0x0000000020000000ULL)
+/* Allows for bind(2). */
+#define CAP_BIND CAPRIGHT(0, 0x0000000040000000ULL)
+/* Allows for connect(2). */
+#define CAP_CONNECT CAPRIGHT(0, 0x0000000080000000ULL)
+/* Allows for getpeername(2). */
+#define CAP_GETPEERNAME CAPRIGHT(0, 0x0000000100000000ULL)
+/* Allows for getsockname(2). */
+#define CAP_GETSOCKNAME CAPRIGHT(0, 0x0000000200000000ULL)
+/* Allows for getsockopt(2). */
+#define CAP_GETSOCKOPT CAPRIGHT(0, 0x0000000400000000ULL)
+/* Allows for listen(2). */
+#define CAP_LISTEN CAPRIGHT(0, 0x0000000800000000ULL)
+/* Allows for sctp_peeloff(2). */
+#define CAP_PEELOFF CAPRIGHT(0, 0x0000001000000000ULL)
+#define CAP_RECV CAP_READ
+#define CAP_SEND CAP_WRITE
+/* Allows for setsockopt(2). */
+#define CAP_SETSOCKOPT CAPRIGHT(0, 0x0000002000000000ULL)
+/* Allows for shutdown(2). */
+#define CAP_SHUTDOWN CAPRIGHT(0, 0x0000004000000000ULL)
+
+/* Allows for bindat(2) on a directory descriptor. */
+#define CAP_BINDAT (CAP_LOOKUP | 0x0000008000000000ULL)
+/* Allows for connectat(2) on a directory descriptor. */
+#define CAP_CONNECTAT (CAP_LOOKUP | 0x0000010000000000ULL)
+
+/* Allows for linkat(2) (source directory descriptor). */
+#define CAP_LINKAT_SOURCE (CAP_LOOKUP | 0x0000020000000000ULL)
+/* Allows for renameat(2) (target directory descriptor). */
+#define CAP_RENAMEAT_TARGET (CAP_LOOKUP | 0x0000040000000000ULL)
+
+#define CAP_SOCK_CLIENT \
+ (CAP_CONNECT | CAP_GETPEERNAME | CAP_GETSOCKNAME | CAP_GETSOCKOPT | \
+ CAP_PEELOFF | CAP_RECV | CAP_SEND | CAP_SETSOCKOPT | CAP_SHUTDOWN)
+#define CAP_SOCK_SERVER \
+ (CAP_ACCEPT | CAP_BIND | CAP_GETPEERNAME | CAP_GETSOCKNAME | \
+ CAP_GETSOCKOPT | CAP_LISTEN | CAP_PEELOFF | CAP_RECV | CAP_SEND | \
+ CAP_SETSOCKOPT | CAP_SHUTDOWN)
+
+/* All used bits for index 0. */
+#define CAP_ALL0 CAPRIGHT(0, 0x000007FFFFFFFFFFULL)
+
+/* Available bits for index 0. */
+#define CAP_UNUSED0_44 CAPRIGHT(0, 0x0000080000000000ULL)
+/* ... */
+#define CAP_UNUSED0_57 CAPRIGHT(0, 0x0100000000000000ULL)
+
+/* INDEX 1 */
+
+/* Mandatory Access Control. */
+/* Allows for mac_get_fd(3). */
+#define CAP_MAC_GET CAPRIGHT(1, 0x0000000000000001ULL)
+/* Allows for mac_set_fd(3). */
+#define CAP_MAC_SET CAPRIGHT(1, 0x0000000000000002ULL)
+
+/* Methods on semaphores. */
+#define CAP_SEM_GETVALUE CAPRIGHT(1, 0x0000000000000004ULL)
+#define CAP_SEM_POST CAPRIGHT(1, 0x0000000000000008ULL)
+#define CAP_SEM_WAIT CAPRIGHT(1, 0x0000000000000010ULL)
+
+/* Allows select(2) and poll(2) on descriptor. */
+#define CAP_EVENT CAPRIGHT(1, 0x0000000000000020ULL)
+/* Allows for kevent(2) on kqueue descriptor with eventlist != NULL. */
+#define CAP_KQUEUE_EVENT CAPRIGHT(1, 0x0000000000000040ULL)
+
+/* Strange and powerful rights that should not be given lightly. */
+/* Allows for ioctl(2). */
+#define CAP_IOCTL CAPRIGHT(1, 0x0000000000000080ULL)
+#define CAP_TTYHOOK CAPRIGHT(1, 0x0000000000000100ULL)
+
+/* Process management via process descriptors. */
+/* Allows for pdgetpid(2). */
+#define CAP_PDGETPID CAPRIGHT(1, 0x0000000000000200ULL)
+/* Allows for pdwait4(2). */
+#define CAP_PDWAIT CAPRIGHT(1, 0x0000000000000400ULL)
+/* Allows for pdkill(2). */
+#define CAP_PDKILL CAPRIGHT(1, 0x0000000000000800ULL)
+
+/* Extended attributes. */
+/* Allows for extattr_delete_fd(2). */
+#define CAP_EXTATTR_DELETE CAPRIGHT(1, 0x0000000000001000ULL)
+/* Allows for extattr_get_fd(2). */
+#define CAP_EXTATTR_GET CAPRIGHT(1, 0x0000000000002000ULL)
+/* Allows for extattr_list_fd(2). */
+#define CAP_EXTATTR_LIST CAPRIGHT(1, 0x0000000000004000ULL)
+/* Allows for extattr_set_fd(2). */
+#define CAP_EXTATTR_SET CAPRIGHT(1, 0x0000000000008000ULL)
+
+/* Access Control Lists. */
+/* Allows for acl_valid_fd_np(3). */
+#define CAP_ACL_CHECK CAPRIGHT(1, 0x0000000000010000ULL)
+/* Allows for acl_delete_fd_np(3). */
+#define CAP_ACL_DELETE CAPRIGHT(1, 0x0000000000020000ULL)
+/* Allows for acl_get_fd(3) and acl_get_fd_np(3). */
+#define CAP_ACL_GET CAPRIGHT(1, 0x0000000000040000ULL)
+/* Allows for acl_set_fd(3) and acl_set_fd_np(3). */
+#define CAP_ACL_SET CAPRIGHT(1, 0x0000000000080000ULL)
+
+/* Allows for kevent(2) on kqueue descriptor with changelist != NULL. */
+#define CAP_KQUEUE_CHANGE CAPRIGHT(1, 0x0000000000100000ULL)
+
+#define CAP_KQUEUE (CAP_KQUEUE_EVENT | CAP_KQUEUE_CHANGE)
+
+/* All used bits for index 1. */
+#define CAP_ALL1 CAPRIGHT(1, 0x00000000001FFFFFULL)
+
+/* Available bits for index 1. */
+#define CAP_UNUSED1_22 CAPRIGHT(1, 0x0000000000200000ULL)
+/* ... */
+#define CAP_UNUSED1_57 CAPRIGHT(1, 0x0100000000000000ULL)
+
+/* Backward compatibility. */
+#define CAP_POLL_EVENT CAP_EVENT
+
+#define CAP_ALL(rights) do { \
+ (rights)->cr_rights[0] = \
+ ((uint64_t)CAP_RIGHTS_VERSION << 62) | CAP_ALL0; \
+ (rights)->cr_rights[1] = CAP_ALL1; \
+} while (0)
+
+#define CAP_NONE(rights) do { \
+ (rights)->cr_rights[0] = \
+ ((uint64_t)CAP_RIGHTS_VERSION << 62) | CAPRIGHT(0, 0ULL); \
+ (rights)->cr_rights[1] = CAPRIGHT(1, 0ULL); \
+} while (0)
+
+#define CAPRVER(right) ((int)((right) >> 62))
+#define CAPVER(rights) CAPRVER((rights)->cr_rights[0])
+#define CAPARSIZE(rights) (CAPVER(rights) + 2)
+#define CAPIDXBIT(right) ((int)(((right) >> 57) & 0x1F))
+
+/*
+ * Allowed fcntl(2) commands.
+ */
+#define CAP_FCNTL_GETFL (1 << F_GETFL)
+#define CAP_FCNTL_SETFL (1 << F_SETFL)
+#define CAP_FCNTL_GETOWN (1 << F_GETOWN)
+#define CAP_FCNTL_SETOWN (1 << F_SETOWN)
+#define CAP_FCNTL_ALL (CAP_FCNTL_GETFL | CAP_FCNTL_SETFL | \
+ CAP_FCNTL_GETOWN | CAP_FCNTL_SETOWN)
+
+#define CAP_IOCTLS_ALL SSIZE_MAX
+
+__BEGIN_DECLS
+
+#ifndef __rtems__
+#define cap_rights_init(...) \
+ __cap_rights_init(CAP_RIGHTS_VERSION, __VA_ARGS__, 0ULL)
+cap_rights_t *__cap_rights_init(int version, cap_rights_t *rights, ...);
+
+#define cap_rights_set(...) \
+ __cap_rights_set(__VA_ARGS__, 0ULL)
+cap_rights_t *__cap_rights_set(cap_rights_t *rights, ...);
+
+#define cap_rights_clear(...) \
+ __cap_rights_clear(__VA_ARGS__, 0ULL)
+cap_rights_t *__cap_rights_clear(cap_rights_t *rights, ...);
+#else /* __rtems__ */
+#define cap_rights_init(...) (void)0
+#define cap_rights_set(...) (void)0
+#define cap_rights_clear(...) (void)0
+#endif /* __rtems__ */
+
+#define cap_rights_is_set(...) \
+ __cap_rights_is_set(__VA_ARGS__, 0ULL)
+bool __cap_rights_is_set(const cap_rights_t *rights, ...);
+
+bool cap_rights_is_valid(const cap_rights_t *rights);
+cap_rights_t *cap_rights_merge(cap_rights_t *dst, const cap_rights_t *src);
+cap_rights_t *cap_rights_remove(cap_rights_t *dst, const cap_rights_t *src);
+bool cap_rights_contains(const cap_rights_t *big, const cap_rights_t *little);
+
+__END_DECLS
+
+#ifdef _KERNEL
+
+#include <sys/systm.h>
+
+#define IN_CAPABILITY_MODE(td) (((td)->td_ucred->cr_flags & CRED_FLAG_CAPMODE) != 0)
+
+struct filedesc;
+struct filedescent;
+
+/*
+ * Test whether a capability grants the requested rights.
+ */
+int cap_check(const cap_rights_t *havep, const cap_rights_t *needp);
+/*
+ * Convert capability rights into VM access flags.
+ */
+u_char cap_rights_to_vmprot(cap_rights_t *havep);
+
+/*
+ * For the purposes of procstat(1) and similar tools, allow kern_descrip.c to
+ * extract the rights from a capability.
+ */
+cap_rights_t *cap_rights_fde(struct filedescent *fde);
+cap_rights_t *cap_rights(struct filedesc *fdp, int fd);
+
+int cap_ioctl_check(struct filedesc *fdp, int fd, u_long cmd);
+int cap_fcntl_check_fde(struct filedescent *fde, int cmd);
+int cap_fcntl_check(struct filedesc *fdp, int fd, int cmd);
+
+#else /* !_KERNEL */
+
+__BEGIN_DECLS
+/*
+ * cap_enter(): Cause the process to enter capability mode, which will
+ * prevent it from directly accessing global namespaces. System calls will
+ * be limited to process-local, process-inherited, or file descriptor
+ * operations. If already in capability mode, a no-op.
+ */
+#ifndef __rtems__
+int cap_enter(void);
+#else /* __rtems__ */
+static inline int
+cap_enter(void)
+{
+
+ return (0);
+}
+#endif /* __rtems__ */
+
+/*
+ * Are we sandboxed (in capability mode)?
+ * This is a libc wrapper around the cap_getmode(2) system call.
+ */
+bool cap_sandboxed(void);
+
+/*
+ * cap_getmode(): Are we in capability mode?
+ */
+int cap_getmode(u_int *modep);
+
+/*
+ * Limits capability rights for the given descriptor (CAP_*).
+ */
+#ifndef __rtems__
+int cap_rights_limit(int fd, const cap_rights_t *rights);
+#else /* __rtems__ */
+static inline int
+cap_rights_limit(int fd, const cap_rights_t *rights)
+{
+
+ return (0);
+}
+#endif /* __rtems__ */
+/*
+ * Returns capability rights for the given descriptor.
+ */
+#define cap_rights_get(fd, rights) \
+ __cap_rights_get(CAP_RIGHTS_VERSION, (fd), (rights))
+int __cap_rights_get(int version, int fd, cap_rights_t *rights);
+/*
+ * Limits allowed ioctls for the given descriptor.
+ */
+int cap_ioctls_limit(int fd, const cap_ioctl_t *cmds, size_t ncmds);
+/*
+ * Returns array of allowed ioctls for the given descriptor.
+ * If all ioctls are allowed, the cmds array is not populated and
+ * the function returns CAP_IOCTLS_ALL.
+ */
+ssize_t cap_ioctls_get(int fd, cap_ioctl_t *cmds, size_t maxcmds);
+/*
+ * Limits allowed fcntls for the given descriptor (CAP_FCNTL_*).
+ */
+int cap_fcntls_limit(int fd, uint32_t fcntlrights);
+/*
+ * Returns bitmask of allowed fcntls for the given descriptor.
+ */
+int cap_fcntls_get(int fd, uint32_t *fcntlrightsp);
+
+__END_DECLS
+
+#endif /* !_KERNEL */
+
+#endif /* !_SYS_CAPSICUM_H_ */
diff --git a/freebsd/sys/sys/condvar.h b/freebsd/sys/sys/condvar.h
index 2efe469e..c4666694 100644
--- a/freebsd/sys/sys/condvar.h
+++ b/freebsd/sys/sys/condvar.h
@@ -55,8 +55,10 @@ void cv_destroy(struct cv *cvp);
void _cv_wait(struct cv *cvp, struct lock_object *lock);
void _cv_wait_unlock(struct cv *cvp, struct lock_object *lock);
int _cv_wait_sig(struct cv *cvp, struct lock_object *lock);
-int _cv_timedwait(struct cv *cvp, struct lock_object *lock, int timo);
-int _cv_timedwait_sig(struct cv *cvp, struct lock_object *lock, int timo);
+int _cv_timedwait_sbt(struct cv *cvp, struct lock_object *lock,
+ sbintime_t sbt, sbintime_t pr, int flags);
+int _cv_timedwait_sig_sbt(struct cv *cvp, struct lock_object *lock,
+ sbintime_t sbt, sbintime_t pr, int flags);
void cv_signal(struct cv *cvp);
void cv_broadcastpri(struct cv *cvp, int pri);
@@ -68,13 +70,22 @@ void cv_broadcastpri(struct cv *cvp, int pri);
#define cv_wait_sig(cvp, lock) \
_cv_wait_sig((cvp), &(lock)->lock_object)
#define cv_timedwait(cvp, lock, timo) \
- _cv_timedwait((cvp), &(lock)->lock_object, (timo))
+ _cv_timedwait_sbt((cvp), &(lock)->lock_object, \
+ tick_sbt * (timo), 0, C_HARDCLOCK)
+#define cv_timedwait_sbt(cvp, lock, sbt, pr, flags) \
+ _cv_timedwait_sbt((cvp), &(lock)->lock_object, (sbt), (pr), (flags))
#ifndef __rtems__
#define cv_timedwait_sig(cvp, lock, timo) \
- _cv_timedwait_sig((cvp), &(lock)->lock_object, (timo))
+ _cv_timedwait_sig_sbt((cvp), &(lock)->lock_object, \
+ tick_sbt * (timo), 0, C_HARDCLOCK)
+#define cv_timedwait_sig_sbt(cvp, lock, sbt, pr, flags) \
+ _cv_timedwait_sig_sbt((cvp), &(lock)->lock_object, (sbt), (pr), (flags))
#else /* __rtems__ */
#define cv_timedwait_sig(cvp, lock, timo) \
- _cv_timedwait((cvp), &(lock)->lock_object, (timo))
+ _cv_timedwait_sbt((cvp), &(lock)->lock_object, \
+ tick_sbt * (timo), 0, C_HARDCLOCK)
+#define cv_timedwait_sig_sbt(cvp, lock, sbt, pr, flags) \
+ _cv_timedwait_sbt((cvp), &(lock)->lock_object, (sbt), (pr), (flags))
#endif /* __rtems__ */
#define cv_broadcast(cvp) cv_broadcastpri(cvp, 0)
diff --git a/freebsd/sys/sys/conf.h b/freebsd/sys/sys/conf.h
index 9d8b7dcf..78bb1e2a 100644
--- a/freebsd/sys/sys/conf.h
+++ b/freebsd/sys/sys/conf.h
@@ -58,20 +58,18 @@ extern const char rtems_cdev_directory[sizeof(RTEMS_CDEV_DIRECTORY)];
struct cdev {
#ifndef __rtems__
- struct mount *si_mountpt;
+ void *si_spare0;
#endif /* __rtems__ */
u_int si_flags;
#define SI_ETERNAL 0x0001 /* never destroyed */
-#define SI_ALIAS 0x0002 /* carrier of alias name */
-#define SI_NAMED 0x0004 /* make_dev{_alias} has been called */
-#define SI_CHEAPCLONE 0x0008 /* can be removed_dev'ed when vnode reclaims */
-#define SI_CHILD 0x0010 /* child of another struct cdev **/
-#define SI_DEVOPEN 0x0020 /* opened by device */
-#define SI_CONSOPEN 0x0040 /* opened by console */
-#define SI_DUMPDEV 0x0080 /* is kernel dumpdev */
-#define SI_CANDELETE 0x0100 /* can do BIO_DELETE */
-#define SI_CLONELIST 0x0200 /* on a clone list */
+#define SI_ALIAS 0x0002 /* carrier of alias name */
+#define SI_NAMED 0x0004 /* make_dev{_alias} has been called */
+#define SI_CHEAPCLONE 0x0008 /* can be removed_dev'ed when vnode reclaims */
+#define SI_CHILD 0x0010 /* child of another struct cdev **/
+#define SI_DUMPDEV 0x0080 /* is kernel dumpdev */
+#define SI_CLONELIST 0x0200 /* on a clone list */
#define SI_UNMAPPED 0x0400 /* can handle unmapped I/O */
+#define SI_NOSPLIT 0x0800 /* I/O should not be split up */
#ifndef __rtems__
struct timespec si_atime;
struct timespec si_ctime;
@@ -89,8 +87,8 @@ struct cdev {
LIST_HEAD(, cdev) si_children;
LIST_ENTRY(cdev) si_siblings;
struct cdev *si_parent;
+ struct mount *si_mountpt;
#endif /* __rtems__ */
- char *si_name;
void *si_drv1, *si_drv2;
struct cdevsw *si_devsw;
#ifndef __rtems__
@@ -102,22 +100,14 @@ struct cdev {
union {
struct snapdata *__sid_snapdata;
} __si_u;
- char __si_namebuf[SPECNAMELEN + 1];
-#else /* __rtems__ */
- struct {
- /* Keep this two together. They will be used as one string. */
- char __si_dir[sizeof(rtems_cdev_directory) - 1];
- char __si_name[SPECNAMELEN + 1];
- } __si_pathstruct;
#endif /* __rtems__ */
- char __si_namebuf[SPECNAMELEN + 1];
-};
-
#ifdef __rtems__
-#define __si_namebuf __si_pathstruct.__si_name
-#define si_path __si_pathstruct.__si_dir
+ char si_path[sizeof(RTEMS_CDEV_DIRECTORY) - 1];
#endif /* __rtems__ */
-#define si_snapdata __si_u.__sid_snapdata
+ char si_name[SPECNAMELEN + 1];
+};
+
+#define si_snapdata __si_u.__sid_snapdata
#ifdef _KERNEL
@@ -134,24 +124,6 @@ struct clonedevs;
struct vm_object;
struct vnode;
-/*
- * Note: d_thread_t is provided as a transition aid for those drivers
- * that treat struct proc/struct thread as an opaque data type and
- * exist in substantially the same form in both 4.x and 5.x. Writers
- * of drivers that dips into the d_thread_t structure should use
- * struct thread or struct proc as appropriate for the version of the
- * OS they are using. It is provided in lieu of each device driver
- * inventing its own way of doing this. While it does violate style(9)
- * in a number of ways, this violation is deemed to be less
- * important than the benefits that a uniform API between releases
- * gives.
- *
- * Users of struct thread/struct proc that aren't device drivers should
- * not use d_thread_t.
- */
-
-typedef struct thread d_thread_t;
-
typedef int d_open_t(struct cdev *dev, int oflags, int devtype, struct thread *td);
typedef int d_fdopen_t(struct cdev *dev, int oflags, struct thread *td, struct file *fp);
typedef int d_close_t(struct cdev *dev, int fflag, int devtype, struct thread *td);
@@ -184,9 +156,9 @@ typedef int dumper_t(
#define D_TAPE 0x0001
#define D_DISK 0x0002
#define D_TTY 0x0004
-#define D_MEM 0x0008
+#define D_MEM 0x0008 /* /dev/(k)mem */
-#ifdef _KERNEL
+#ifdef _KERNEL
#define D_TYPEMASK 0xffff
@@ -194,25 +166,23 @@ typedef int dumper_t(
* Flags for d_flags which the drivers can set.
*/
#define D_TRACKCLOSE 0x00080000 /* track all closes */
-#define D_MMAP_ANON 0x00100000 /* special treatment in vm_mmap.c */
-#define D_PSEUDO 0x00200000 /* make_dev() can return NULL */
-#define D_NEEDGIANT 0x00400000 /* driver want Giant */
+#define D_MMAP_ANON 0x00100000 /* special treatment in vm_mmap.c */
+#define D_NEEDGIANT 0x00400000 /* driver want Giant */
#define D_NEEDMINOR 0x00800000 /* driver uses clone_create() */
-#define D_UNMAPPED_IO 0x01000000 /* d_strategy can accept unmapped IO */
/*
* Version numbers.
*/
-#define D_VERSION_00 0x20011966
-#define D_VERSION_01 0x17032005 /* Add d_uid,gid,mode & kind */
-#define D_VERSION_02 0x28042009 /* Add d_mmap_single */
-#define D_VERSION_03 0x17122009 /* d_mmap takes memattr,vm_ooffset_t */
-#define D_VERSION D_VERSION_03
+#define D_VERSION_00 0x20011966
+#define D_VERSION_01 0x17032005 /* Add d_uid,gid,mode & kind */
+#define D_VERSION_02 0x28042009 /* Add d_mmap_single */
+#define D_VERSION_03 0x17122009 /* d_mmap takes memattr,vm_ooffset_t */
+#define D_VERSION D_VERSION_03
/*
* Flags used for internal housekeeping
*/
-#define D_INIT 0x80000000 /* cdevsw initialized */
+#define D_INIT 0x80000000 /* cdevsw initialized */
/*
* Character device switch table
@@ -265,21 +235,45 @@ struct devsw_module_data {
/* Do not initialize fields hereafter */
};
-#define DEV_MODULE(name, evh, arg) \
+#define DEV_MODULE_ORDERED(name, evh, arg, ord) \
static moduledata_t name##_mod = { \
#name, \
evh, \
arg \
}; \
-DECLARE_MODULE(name, name##_mod, SI_SUB_DRIVERS, SI_ORDER_MIDDLE)
+DECLARE_MODULE(name, name##_mod, SI_SUB_DRIVERS, ord)
+#define DEV_MODULE(name, evh, arg) \
+ DEV_MODULE_ORDERED(name, evh, arg, SI_ORDER_MIDDLE)
void clone_setup(struct clonedevs **cdp);
void clone_cleanup(struct clonedevs **);
-#define CLONE_UNITMASK 0xfffff
-#define CLONE_FLAG0 (CLONE_UNITMASK + 1)
+#define CLONE_UNITMASK 0xfffff
+#define CLONE_FLAG0 (CLONE_UNITMASK + 1)
int clone_create(struct clonedevs **, struct cdevsw *, int *unit, struct cdev **dev, int extra);
+#define MAKEDEV_REF 0x01
+#define MAKEDEV_WHTOUT 0x02
+#define MAKEDEV_NOWAIT 0x04
+#define MAKEDEV_WAITOK 0x08
+#define MAKEDEV_ETERNAL 0x10
+#define MAKEDEV_CHECKNAME 0x20
+struct make_dev_args {
+ size_t mda_size;
+ int mda_flags;
+ struct cdevsw *mda_devsw;
+ struct ucred *mda_cr;
+ uid_t mda_uid;
+ gid_t mda_gid;
+ int mda_mode;
+ int mda_unit;
+ void *mda_si_drv1;
+ void *mda_si_drv2;
+};
+void make_dev_args_init_impl(struct make_dev_args *_args, size_t _sz);
+#define make_dev_args_init(a) \
+ make_dev_args_init_impl((a), sizeof(struct make_dev_args))
+
int count_dev(struct cdev *_dev);
void delist_dev(struct cdev *_dev);
void destroy_dev(struct cdev *_dev);
@@ -294,19 +288,11 @@ void dev_depends(struct cdev *_pdev, struct cdev *_cdev);
void dev_ref(struct cdev *dev);
void dev_refl(struct cdev *dev);
void dev_rel(struct cdev *dev);
-void dev_strategy(struct cdev *dev, struct buf *bp);
-void dev_strategy_csw(struct cdev *dev, struct cdevsw *csw, struct buf *bp);
struct cdev *make_dev(struct cdevsw *_devsw, int _unit, uid_t _uid, gid_t _gid,
int _perms, const char *_fmt, ...) __printflike(6, 7);
struct cdev *make_dev_cred(struct cdevsw *_devsw, int _unit,
struct ucred *_cr, uid_t _uid, gid_t _gid, int _perms,
const char *_fmt, ...) __printflike(7, 8);
-#define MAKEDEV_REF 0x01
-#define MAKEDEV_WHTOUT 0x02
-#define MAKEDEV_NOWAIT 0x04
-#define MAKEDEV_WAITOK 0x08
-#define MAKEDEV_ETERNAL 0x10
-#define MAKEDEV_CHECKNAME 0x20
struct cdev *make_dev_credf(int _flags,
struct cdevsw *_devsw, int _unit,
struct ucred *_cr, uid_t _uid, gid_t _gid, int _mode,
@@ -314,13 +300,15 @@ struct cdev *make_dev_credf(int _flags,
int make_dev_p(int _flags, struct cdev **_cdev, struct cdevsw *_devsw,
struct ucred *_cr, uid_t _uid, gid_t _gid, int _mode,
const char *_fmt, ...) __printflike(8, 9);
+int make_dev_s(struct make_dev_args *_args, struct cdev **_cdev,
+ const char *_fmt, ...) __printflike(3, 4);
struct cdev *make_dev_alias(struct cdev *_pdev, const char *_fmt, ...)
__printflike(2, 3);
int make_dev_alias_p(int _flags, struct cdev **_cdev, struct cdev *_pdev,
const char *_fmt, ...) __printflike(4, 5);
int make_dev_physpath_alias(int _flags, struct cdev **_cdev,
- struct cdev *_pdev, struct cdev *_old_alias,
- const char *_physpath);
+ struct cdev *_pdev, struct cdev *_old_alias,
+ const char *_physpath);
void dev_lock(void);
void dev_unlock(void);
void setconf(void);
@@ -333,11 +321,10 @@ void setconf(void);
#define dev2unit(d) ((d)->si_drv0)
-typedef void (*cdevpriv_dtr_t)(void *data);
+typedef void d_priv_dtor_t(void *data);
int devfs_get_cdevpriv(void **datap);
-int devfs_set_cdevpriv(void *priv, cdevpriv_dtr_t dtr);
+int devfs_set_cdevpriv(void *priv, d_priv_dtor_t *dtr);
void devfs_clear_cdevpriv(void);
-void devfs_fpdrop(struct file *fp); /* XXX This is not public KPI */
ino_t devfs_alloc_cdp_inode(void);
void devfs_free_cdp_inode(ino_t ino);
@@ -353,6 +340,7 @@ void devfs_free_cdp_inode(ino_t ino);
#define GID_OPERATOR 5
#define GID_BIN 7
#define GID_GAMES 13
+#define GID_VIDEO 44
#define GID_DIALER 68
#define GID_NOBODY 65534
@@ -366,16 +354,18 @@ EVENTHANDLER_DECLARE(dev_clone, dev_clone_fn);
struct dumperinfo {
dumper_t *dumper; /* Dumping function. */
- void *priv; /* Private parts. */
- u_int blocksize; /* Size of block in bytes. */
+ void *priv; /* Private parts. */
+ u_int blocksize; /* Size of block in bytes. */
u_int maxiosize; /* Max size allowed for an individual I/O */
- off_t mediaoffset; /* Initial offset in bytes. */
- off_t mediasize; /* Space available in bytes. */
+ off_t mediaoffset; /* Initial offset in bytes. */
+ off_t mediasize; /* Space available in bytes. */
+ void *blockbuf; /* Buffer for padding shorter dump blocks */
};
-int set_dumper(struct dumperinfo *);
+int set_dumper(struct dumperinfo *, const char *_devname, struct thread *td);
int dump_write(struct dumperinfo *, void *, vm_offset_t, off_t, size_t);
-void dumpsys(struct dumperinfo *);
+int dump_write_pad(struct dumperinfo *, void *, vm_offset_t, off_t, size_t,
+ size_t *);
int doadump(boolean_t);
#ifndef __rtems__
extern int dumping; /* system is dumping */
diff --git a/freebsd/sys/sys/counter.h b/freebsd/sys/sys/counter.h
new file mode 100644
index 00000000..2ce71341
--- /dev/null
+++ b/freebsd/sys/sys/counter.h
@@ -0,0 +1,63 @@
+/*-
+ * Copyright (c) 2012 Gleb Smirnoff <glebius@FreeBSD.org>
+ * All rights reserved.
+ *
+ * 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_COUNTER_H__
+#define __SYS_COUNTER_H__
+
+typedef uint64_t *counter_u64_t;
+
+#ifdef _KERNEL
+#include <machine/counter.h>
+
+counter_u64_t counter_u64_alloc(int);
+void counter_u64_free(counter_u64_t);
+
+void counter_u64_zero(counter_u64_t);
+uint64_t counter_u64_fetch(counter_u64_t);
+
+#define COUNTER_ARRAY_ALLOC(a, n, wait) do { \
+ for (int i = 0; i < (n); i++) \
+ (a)[i] = counter_u64_alloc(wait); \
+} while (0)
+
+#define COUNTER_ARRAY_FREE(a, n) do { \
+ for (int i = 0; i < (n); i++) \
+ counter_u64_free((a)[i]); \
+} while (0)
+
+#define COUNTER_ARRAY_COPY(a, dstp, n) do { \
+ for (int i = 0; i < (n); i++) \
+ ((uint64_t *)(dstp))[i] = counter_u64_fetch((a)[i]);\
+} while (0)
+
+#define COUNTER_ARRAY_ZERO(a, n) do { \
+ for (int i = 0; i < (n); i++) \
+ counter_u64_zero((a)[i]); \
+} while (0)
+#endif /* _KERNEL */
+#endif /* ! __SYS_COUNTER_H__ */
diff --git a/freebsd/sys/sys/cpu.h b/freebsd/sys/sys/cpu.h
index c16091e1..f159e376 100644
--- a/freebsd/sys/sys/cpu.h
+++ b/freebsd/sys/sys/cpu.h
@@ -37,6 +37,8 @@
#define CPU_IVAR_PCPU 1
#define CPU_IVAR_NOMINAL_MHZ 2
+#define CPU_IVAR_CPUID_SIZE 3
+#define CPU_IVAR_CPUID 4
static __inline struct pcpu *cpu_get_pcpu(device_t dev)
{
@@ -54,6 +56,20 @@ static __inline int32_t cpu_get_nominal_mhz(device_t dev)
return ((int32_t)v);
}
+static __inline const uint32_t *cpu_get_cpuid(device_t dev, size_t *count)
+{
+ uintptr_t v = 0;
+ if (BUS_READ_IVAR(device_get_parent(dev), dev,
+ CPU_IVAR_CPUID_SIZE, &v) != 0)
+ return (NULL);
+ *count = (size_t)v;
+
+ if (BUS_READ_IVAR(device_get_parent(dev), dev,
+ CPU_IVAR_CPUID, &v) != 0)
+ return (NULL);
+ return ((const uint32_t *)v);
+}
+
/*
* CPU frequency control interface.
*/
diff --git a/freebsd/sys/sys/domain.h b/freebsd/sys/sys/domain.h
index 2563cb6e..1817e788 100644
--- a/freebsd/sys/sys/domain.h
+++ b/freebsd/sys/sys/domain.h
@@ -42,6 +42,7 @@
*/
struct mbuf;
struct ifnet;
+struct socket;
struct domain {
int dom_family; /* AF_xxx */
@@ -51,25 +52,18 @@ struct domain {
void (*dom_destroy) /* cleanup structures / state */
(void);
int (*dom_externalize) /* externalize access rights */
- (struct mbuf *, struct mbuf **);
+ (struct mbuf *, struct mbuf **, int);
void (*dom_dispose) /* dispose of internalized rights */
- (struct mbuf *);
+ (struct socket *);
struct protosw *dom_protosw, *dom_protoswNPROTOSW;
struct domain *dom_next;
int (*dom_rtattach) /* initialize routing table */
(void **, int);
int (*dom_rtdetach) /* clean up routing table */
(void **, int);
- int dom_rtoffset; /* an arg to rtattach, in bits */
- /* XXX MRT.
- * rtoffset May be 0 if the domain supplies its own rtattach(),
- * in which case, a 0 indicates it's being called from
- * vfs_export.c (HACK) Only for AF_INET{,6} at this time.
- * Temporary ABI compat hack.. fix post RELENG_7
- */
- int dom_maxrtkey; /* for routing layer */
void *(*dom_ifattach)(struct ifnet *);
void (*dom_ifdetach)(struct ifnet *, void *);
+ int (*dom_ifmtu)(struct ifnet *);
/* af-dependent data on ifnet */
};
diff --git a/freebsd/sys/sys/eventhandler.h b/freebsd/sys/sys/eventhandler.h
index 95d03b83..9315f8c8 100644
--- a/freebsd/sys/sys/eventhandler.h
+++ b/freebsd/sys/sys/eventhandler.h
@@ -26,8 +26,8 @@
* $FreeBSD$
*/
-#ifndef SYS_EVENTHANDLER_H
-#define SYS_EVENTHANDLER_H
+#ifndef _SYS_EVENTHANDLER_H_
+#define _SYS_EVENTHANDLER_H_
#include <rtems/bsd/sys/lock.h>
#include <sys/ktr.h>
@@ -182,6 +182,7 @@ EVENTHANDLER_DECLARE(shutdown_final, shutdown_fn);
typedef void (*power_change_fn)(void *);
EVENTHANDLER_DECLARE(power_resume, power_change_fn);
EVENTHANDLER_DECLARE(power_suspend, power_change_fn);
+EVENTHANDLER_DECLARE(power_suspend_early, power_change_fn);
/* Low memory event */
typedef void (*vm_lowmem_handler_t)(void *, int);
@@ -192,18 +193,16 @@ EVENTHANDLER_DECLARE(vm_lowmem, vm_lowmem_handler_t);
typedef void (*mountroot_handler_t)(void *);
EVENTHANDLER_DECLARE(mountroot, mountroot_handler_t);
-/* VLAN state change events */
-struct ifnet;
-typedef void (*vlan_config_fn)(void *, struct ifnet *, uint16_t);
-typedef void (*vlan_unconfig_fn)(void *, struct ifnet *, uint16_t);
-EVENTHANDLER_DECLARE(vlan_config, vlan_config_fn);
-EVENTHANDLER_DECLARE(vlan_unconfig, vlan_unconfig_fn);
-
-/* BPF attach/detach events */
-struct ifnet;
-typedef void (*bpf_track_fn)(void *, struct ifnet *, int /* dlt */,
- int /* 1 =>'s attach */);
-EVENTHANDLER_DECLARE(bpf_track, bpf_track_fn);
+/* File system mount events */
+struct mount;
+struct vnode;
+struct thread;
+typedef void (*vfs_mounted_notify_fn)(void *, struct mount *, struct vnode *,
+ struct thread *);
+typedef void (*vfs_unmounted_notify_fn)(void *, struct mount *,
+ struct thread *);
+EVENTHANDLER_DECLARE(vfs_mounted, vfs_mounted_notify_fn);
+EVENTHANDLER_DECLARE(vfs_unmounted, vfs_unmounted_notify_fn);
/*
* Process events
@@ -231,7 +230,6 @@ EVENTHANDLER_DECLARE(process_exec, execlist_fn);
/*
* application dump event
*/
-struct thread;
typedef void (*app_coredump_start_fn)(void *, struct thread *, char *name);
typedef void (*app_coredump_progress_fn)(void *, struct thread *td, int byte_count);
typedef void (*app_coredump_finish_fn)(void *, struct thread *td);
@@ -272,5 +270,4 @@ typedef void (*unregister_framebuffer_fn)(void *, struct fb_info *);
EVENTHANDLER_DECLARE(register_framebuffer, register_framebuffer_fn);
EVENTHANDLER_DECLARE(unregister_framebuffer, unregister_framebuffer_fn);
-#endif /* SYS_EVENTHANDLER_H */
-
+#endif /* _SYS_EVENTHANDLER_H_ */
diff --git a/freebsd/sys/sys/eventvar.h b/freebsd/sys/sys/eventvar.h
index 6af0fe82..c7e46230 100644
--- a/freebsd/sys/sys/eventvar.h
+++ b/freebsd/sys/sys/eventvar.h
@@ -62,6 +62,7 @@ struct kqueue {
u_long kq_knhashmask; /* size of knhash */
struct klist *kq_knhash; /* hash table for knotes */
struct task kq_task;
+ struct ucred *kq_cred;
};
#endif /* !_SYS_EVENTVAR_H_ */
diff --git a/freebsd/sys/sys/fail.h b/freebsd/sys/sys/fail.h
new file mode 100644
index 00000000..45499af2
--- /dev/null
+++ b/freebsd/sys/sys/fail.h
@@ -0,0 +1,366 @@
+/*-
+ * Copyright (c) 2009 Isilon Inc http://www.isilon.com/
+ *
+ * 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$
+ */
+/**
+ * @file
+ *
+ * Main header for failpoint facility.
+ */
+#ifndef _SYS_FAIL_H_
+#define _SYS_FAIL_H_
+
+#include <rtems/bsd/sys/param.h>
+#include <sys/cdefs.h>
+#include <sys/linker_set.h>
+#include <sys/queue.h>
+#include <sys/sysctl.h>
+#include <sys/condvar.h>
+#include <sys/kernel.h>
+#include <rtems/bsd/sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/systm.h>
+
+/**
+ * Failpoint return codes, used internally.
+ * @ingroup failpoint_private
+ */
+enum fail_point_return_code {
+ FAIL_POINT_RC_CONTINUE = 0, /**< Continue with normal execution */
+ FAIL_POINT_RC_RETURN, /**< FP evaluated to 'return' */
+ FAIL_POINT_RC_QUEUED, /**< sleep_fn will be called */
+};
+
+struct fail_point_entry;
+struct fail_point_setting;
+
+/**
+ * Internal failpoint structure, tracking all the current details of the
+ * failpoint. This structure is the core component shared between the
+ * failure-injection code and the user-interface.
+ * @ingroup failpoint_private
+ */
+struct fail_point {
+ const char *fp_name; /* name of fail point */
+ const char *fp_location; /* file:line of fail point */
+ volatile int fp_ref_cnt; /**
+ * protects fp_setting: while holding
+ * a ref, fp_setting points to an
+ * unfreed fail_point_setting
+ */
+ struct fail_point_setting * volatile fp_setting;
+ int fp_flags;
+
+ /**< Function to call before sleep or pause */
+ void (*fp_pre_sleep_fn)(void *);
+ /**< Arg for fp_pre_sleep_fn */
+ void *fp_pre_sleep_arg;
+
+ /**< Function to call after waking from sleep or pause */
+ void (*fp_post_sleep_fn)(void *);
+ /**< Arg for fp_post_sleep_fn */
+ void *fp_post_sleep_arg;
+};
+
+#define FAIL_POINT_DYNAMIC_NAME 0x01 /**< Must free name on destroy */
+/**< Use timeout path for sleep instead of msleep */
+#define FAIL_POINT_USE_TIMEOUT_PATH 0x02
+/**< If fail point is set to sleep, replace the sleep call with delay */
+#define FAIL_POINT_NONSLEEPABLE 0x04
+
+#define FAIL_POINT_CV_DESC "fp cv no iterators"
+#define FAIL_POINT_IS_OFF(fp) (__predict_true((fp)->fp_setting == NULL) || \
+ __predict_true(fail_point_is_off(fp)))
+
+__BEGIN_DECLS
+
+/* Private failpoint eval function -- use fail_point_eval() instead. */
+enum fail_point_return_code fail_point_eval_nontrivial(struct fail_point *,
+ int *ret);
+
+/**
+ * @addtogroup failpoint
+ * @{
+ */
+/*
+ * Initialize a fail-point. The name is formed in printf-like fashion
+ * from "fmt" and the subsequent arguments.
+ * Pair with fail_point_destroy().
+ */
+void fail_point_init(struct fail_point *, const char *fmt, ...)
+ __printflike(2, 3);
+
+/* Return true iff this fail point is set to off, false otherwise */
+bool fail_point_is_off(struct fail_point *fp);
+
+/**
+ * Set the pre-sleep function for a fail point
+ * If fp_post_sleep_fn is specified, then FAIL_POINT_SLEEP will result in a
+ * (*fp->fp_pre_sleep_fn)(fp->fp_pre_sleep_arg) call by the thread.
+ */
+static inline void
+fail_point_sleep_set_pre_func(struct fail_point *fp, void (*sleep_fn)(void *))
+{
+ fp->fp_pre_sleep_fn = sleep_fn;
+}
+
+static inline void
+fail_point_sleep_set_pre_arg(struct fail_point *fp, void *sleep_arg)
+{
+ fp->fp_pre_sleep_arg = sleep_arg;
+}
+
+/**
+ * Set the post-sleep function. This will be passed to timeout if we take
+ * the timeout path. This must be set if you sleep using the timeout path.
+ */
+static inline void
+fail_point_sleep_set_post_func(struct fail_point *fp, void (*sleep_fn)(void *))
+{
+ fp->fp_post_sleep_fn = sleep_fn;
+}
+
+static inline void
+fail_point_sleep_set_post_arg(struct fail_point *fp, void *sleep_arg)
+{
+ fp->fp_post_sleep_arg = sleep_arg;
+}
+/**
+ * If the FAIL_POINT_USE_TIMEOUT flag is set on a failpoint, then
+ * FAIL_POINT_SLEEP will result in a call to timeout instead of
+ * msleep. Note that if you sleep while this flag is set, you must
+ * set fp_post_sleep_fn or an error will occur upon waking.
+ */
+static inline void
+fail_point_use_timeout_path(struct fail_point *fp, bool use_timeout,
+ void (*post_sleep_fn)(void *))
+{
+ KASSERT(!use_timeout || post_sleep_fn != NULL ||
+ (post_sleep_fn == NULL && fp->fp_post_sleep_fn != NULL),
+ ("Setting fp to use timeout, but not setting post_sleep_fn\n"));
+
+ if (use_timeout)
+ fp->fp_flags |= FAIL_POINT_USE_TIMEOUT_PATH;
+ else
+ fp->fp_flags &= ~FAIL_POINT_USE_TIMEOUT_PATH;
+
+ if (post_sleep_fn != NULL)
+ fp->fp_post_sleep_fn = post_sleep_fn;
+}
+
+/**
+ * Free the resources used by a fail-point. Pair with fail_point_init().
+ */
+void fail_point_destroy(struct fail_point *);
+
+/**
+ * Evaluate a failpoint.
+ */
+static inline enum fail_point_return_code
+fail_point_eval(struct fail_point *fp, int *ret)
+{
+ if (__predict_true(fp->fp_setting == NULL))
+ return (FAIL_POINT_RC_CONTINUE);
+ return (fail_point_eval_nontrivial(fp, ret));
+}
+
+__END_DECLS
+
+/* Declare a fail_point and its sysctl in a function. */
+#define _FAIL_POINT_NAME(name) _fail_point_##name
+#define _FAIL_POINT_LOCATION() "(" __FILE__ ":" __XSTRING(__LINE__) ")"
+#ifndef __rtems__
+#define _FAIL_POINT_INIT(parent, name, flags) \
+ static struct fail_point _FAIL_POINT_NAME(name) = { \
+ .fp_name = #name, \
+ .fp_location = _FAIL_POINT_LOCATION(), \
+ .fp_ref_cnt = 0, \
+ .fp_setting = NULL, \
+ .fp_flags = (flags), \
+ .fp_pre_sleep_fn = NULL, \
+ .fp_pre_sleep_arg = NULL, \
+ .fp_post_sleep_fn = NULL, \
+ .fp_post_sleep_arg = NULL, \
+ }; \
+ SYSCTL_OID(parent, OID_AUTO, name, \
+ CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_MPSAFE, \
+ &_FAIL_POINT_NAME(name), 0, fail_point_sysctl, \
+ "A", ""); \
+ SYSCTL_OID(parent, OID_AUTO, status_##name, \
+ CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, \
+ &_FAIL_POINT_NAME(name), 0, \
+ fail_point_sysctl_status, "A", "");
+#define _FAIL_POINT_EVAL(name, cond, code...) \
+ int RETURN_VALUE; \
+ \
+ if (__predict_false(cond && \
+ fail_point_eval(&_FAIL_POINT_NAME(name), &RETURN_VALUE))) { \
+ \
+ code; \
+ \
+ }
+#else /* __rtems__ */
+#define _FAIL_POINT_INIT(parent, name, flags) (void)0;
+#define _FAIL_POINT_EVAL(name, cond, code...) (void)0;
+#endif /* __rtems__ */
+
+
+/**
+ * Instantiate a failpoint which returns "RETURN_VALUE" from the function
+ * when triggered.
+ * @param parent The parent sysctl under which to locate the fp's sysctl
+ * @param name The name of the failpoint in the sysctl tree (and printouts)
+ * @return Instantly returns the RETURN_VALUE specified in the
+ * failpoint, if triggered.
+ */
+#define KFAIL_POINT_RETURN(parent, name) \
+ KFAIL_POINT_CODE(parent, name, return RETURN_VALUE)
+
+/**
+ * Instantiate a failpoint which returns (void) from the function when
+ * triggered.
+ * @param parent The parent sysctl under which to locate the sysctl
+ * @param name The name of the failpoint in the sysctl tree (and printouts)
+ * @return Instantly returns void, if triggered in the failpoint.
+ */
+#define KFAIL_POINT_RETURN_VOID(parent, name) \
+ KFAIL_POINT_CODE(parent, name, return)
+
+/**
+ * Instantiate a failpoint which sets an error when triggered.
+ * @param parent The parent sysctl under which to locate the sysctl
+ * @param name The name of the failpoint in the sysctl tree (and
+ * printouts)
+ * @param error_var A variable to set to the failpoint's specified
+ * return-value when triggered
+ */
+#define KFAIL_POINT_ERROR(parent, name, error_var) \
+ KFAIL_POINT_CODE(parent, name, (error_var) = RETURN_VALUE)
+
+/**
+ * Instantiate a failpoint which sets an error and then goes to a
+ * specified label in the function when triggered.
+ * @param parent The parent sysctl under which to locate the sysctl
+ * @param name The name of the failpoint in the sysctl tree (and
+ * printouts)
+ * @param error_var A variable to set to the failpoint's specified
+ * return-value when triggered
+ * @param label The location to goto when triggered.
+ */
+#define KFAIL_POINT_GOTO(parent, name, error_var, label) \
+ KFAIL_POINT_CODE(parent, name, (error_var) = RETURN_VALUE; goto label)
+
+/**
+ * Instantiate a failpoint which sets its pre- and post-sleep callback
+ * mechanisms.
+ * @param parent The parent sysctl under which to locate the sysctl
+ * @param name The name of the failpoint in the sysctl tree (and
+ * printouts)
+ * @param pre_func Function pointer to the pre-sleep function, which will be
+ * called directly before going to sleep.
+ * @param pre_arg Argument to the pre-sleep function
+ * @param post_func Function pointer to the pot-sleep function, which will be
+ * called directly before going to sleep.
+ * @param post_arg Argument to the post-sleep function
+ */
+#define KFAIL_POINT_SLEEP_CALLBACKS(parent, name, pre_func, pre_arg, \
+ post_func, post_arg) \
+ KFAIL_POINT_CODE_SLEEP_CALLBACKS(parent, name, pre_func, \
+ pre_arg, post_func, post_arg, return RETURN_VALUE)
+
+/**
+ * Instantiate a failpoint which runs arbitrary code when triggered, and sets
+ * its pre- and post-sleep callback mechanisms
+ * @param parent The parent sysctl under which to locate the sysctl
+ * @param name The name of the failpoint in the sysctl tree (and
+ * printouts)
+ * @param pre_func Function pointer to the pre-sleep function, which will be
+ * called directly before going to sleep.
+ * @param pre_arg Argument to the pre-sleep function
+ * @param post_func Function pointer to the pot-sleep function, which will be
+ * called directly before going to sleep.
+ * @param post_arg Argument to the post-sleep function
+ * @param code The arbitrary code to run when triggered. Can reference
+ * "RETURN_VALUE" if desired to extract the specified
+ * user return-value when triggered. Note that this is
+ * implemented with a do-while loop so be careful of
+ * break and continue statements.
+ */
+#define KFAIL_POINT_CODE_SLEEP_CALLBACKS(parent, name, pre_func, pre_arg, \
+ post_func, post_arg, code...) \
+ do { \
+ _FAIL_POINT_INIT(parent, name) \
+ _FAIL_POINT_NAME(name).fp_pre_sleep_fn = pre_func; \
+ _FAIL_POINT_NAME(name).fp_pre_sleep_arg = pre_arg; \
+ _FAIL_POINT_NAME(name).fp_post_sleep_fn = post_func; \
+ _FAIL_POINT_NAME(name).fp_post_sleep_arg = post_arg; \
+ _FAIL_POINT_EVAL(name, true, code) \
+ } while (0)
+
+
+/**
+ * Instantiate a failpoint which runs arbitrary code when triggered.
+ * @param parent The parent sysctl under which to locate the sysctl
+ * @param name The name of the failpoint in the sysctl tree
+ * (and printouts)
+ * @param code The arbitrary code to run when triggered. Can reference
+ * "RETURN_VALUE" if desired to extract the specified
+ * user return-value when triggered. Note that this is
+ * implemented with a do-while loop so be careful of
+ * break and continue statements.
+ */
+#define KFAIL_POINT_CODE(parent, name, code...) \
+ do { \
+ _FAIL_POINT_INIT(parent, name, 0) \
+ _FAIL_POINT_EVAL(name, true, code) \
+ } while (0)
+
+#define KFAIL_POINT_CODE_FLAGS(parent, name, flags, code...) \
+ do { \
+ _FAIL_POINT_INIT(parent, name, flags) \
+ _FAIL_POINT_EVAL(name, true, code) \
+ } while (0)
+
+#define KFAIL_POINT_CODE_COND(parent, name, cond, flags, code...) \
+ do { \
+ _FAIL_POINT_INIT(parent, name, flags) \
+ _FAIL_POINT_EVAL(name, cond, code) \
+ } while (0)
+
+/**
+ * @}
+ * (end group failpoint)
+ */
+
+#ifdef _KERNEL
+int fail_point_sysctl(SYSCTL_HANDLER_ARGS);
+int fail_point_sysctl_status(SYSCTL_HANDLER_ARGS);
+
+/* The fail point sysctl tree. */
+SYSCTL_DECL(_debug_fail_point);
+#define DEBUG_FP _debug_fail_point
+#endif
+
+#endif /* _SYS_FAIL_H_ */
diff --git a/freebsd/sys/sys/file.h b/freebsd/sys/sys/file.h
index 4ac69413..4fcbbde0 100644
--- a/freebsd/sys/sys/file.h
+++ b/freebsd/sys/sys/file.h
@@ -42,7 +42,9 @@
#include <sys/refcount.h>
#include <sys/_lock.h>
#include <sys/_mutex.h>
+#include <vm/vm.h>
+struct filedesc;
struct stat;
struct thread;
struct uio;
@@ -64,12 +66,15 @@ struct socket;
#define DTYPE_SEM 9 /* posix semaphore */
#define DTYPE_PTS 10 /* pseudo teletype master device */
#define DTYPE_DEV 11 /* Device specific fd type */
-#define DTYPE_CAPABILITY 12 /* capability */
-#define DTYPE_PROCDESC 13 /* process descriptor */
+#define DTYPE_PROCDESC 12 /* process descriptor */
+#define DTYPE_LINUXEFD 13 /* emulation eventfd type */
#ifdef _KERNEL
struct file;
+struct filecaps;
+struct kaiocb;
+struct kinfo_file;
struct ucred;
#define FOF_OFFSET 0x01 /* Use the offset in uio argument */
@@ -105,6 +110,17 @@ typedef int fo_chmod_t(struct file *fp, mode_t mode,
struct ucred *active_cred, struct thread *td);
typedef int fo_chown_t(struct file *fp, uid_t uid, gid_t gid,
struct ucred *active_cred, struct thread *td);
+typedef int fo_sendfile_t(struct file *fp, int sockfd, struct uio *hdr_uio,
+ struct uio *trl_uio, off_t offset, size_t nbytes,
+ off_t *sent, int flags, struct thread *td);
+typedef int fo_seek_t(struct file *fp, off_t offset, int whence,
+ struct thread *td);
+typedef int fo_fill_kinfo_t(struct file *fp, struct kinfo_file *kif,
+ struct filedesc *fdp);
+typedef int fo_mmap_t(struct file *fp, vm_map_t map, vm_offset_t *addr,
+ vm_size_t size, vm_prot_t prot, vm_prot_t cap_maxprot,
+ int flags, vm_ooffset_t foff, struct thread *td);
+typedef int fo_aio_queue_t(struct file *fp, struct kaiocb *job);
typedef int fo_flags_t;
struct fileops {
@@ -118,6 +134,11 @@ struct fileops {
fo_close_t *fo_close;
fo_chmod_t *fo_chmod;
fo_chown_t *fo_chown;
+ fo_sendfile_t *fo_sendfile;
+ fo_seek_t *fo_seek;
+ fo_fill_kinfo_t *fo_fill_kinfo;
+ fo_mmap_t *fo_mmap;
+ fo_aio_queue_t *fo_aio_queue;
fo_flags_t fo_flags; /* DFLAG_* below */
};
@@ -136,6 +157,7 @@ struct fileops {
*
* Below is the list of locks that protects members in struct file.
*
+ * (a) f_vnode lock required (shared allows both reads and writes)
* (f) protected with mtx_lock(mtx_pool_find(fp))
* (d) cdevpriv_mtx
* none not locked
@@ -145,8 +167,6 @@ struct fadvise_info {
int fa_advice; /* (f) FADV_* type. */
off_t fa_start; /* (f) Region start. */
off_t fa_end; /* (f) Region end. */
- off_t fa_prevstart; /* (f) Previous NOREUSE start. */
- off_t fa_prevend; /* (f) Previous NOREUSE end. */
};
struct file {
@@ -162,7 +182,7 @@ struct file {
/*
* DTYPE_VNODE specific fields.
*/
- int f_seqcount; /* Count of sequential accesses. */
+ int f_seqcount; /* (a) Count of sequential accesses. */
off_t f_nextoff; /* next expected read/write offset. */
union {
struct cdev_privdata *fvn_cdevpriv;
@@ -288,10 +308,6 @@ struct xfile {
#ifdef _KERNEL
-#ifdef MALLOC_DECLARE
-MALLOC_DECLARE(M_FILE);
-#endif
-
extern struct fileops vnops;
extern struct fileops badfileops;
#ifndef __rtems__
@@ -304,7 +320,7 @@ extern int maxfilesperproc; /* per process limit on number of open files */
extern volatile int openfiles; /* actual number of open files */
#ifndef __rtems__
-int fget(struct thread *td, int fd, cap_rights_t rights, struct file **fpp);
+int fget(struct thread *td, int fd, cap_rights_t *rightsp, struct file **fpp);
#else /* __rtems__ */
struct file *rtems_bsd_get_file(int fd);
@@ -320,32 +336,30 @@ rtems_bsd_do_fget(int fd, struct file **fpp)
#define fget(td, fd, rights, fpp) rtems_bsd_do_fget(fd, fpp)
#endif /* __rtems__ */
-int fget_mmap(struct thread *td, int fd, cap_rights_t rights,
+int fget_mmap(struct thread *td, int fd, cap_rights_t *rightsp,
u_char *maxprotp, struct file **fpp);
-int fget_read(struct thread *td, int fd, cap_rights_t rights,
+int fget_read(struct thread *td, int fd, cap_rights_t *rightsp,
struct file **fpp);
-int fget_write(struct thread *td, int fd, cap_rights_t rights,
+int fget_write(struct thread *td, int fd, cap_rights_t *rightsp,
struct file **fpp);
-int fgetcap(struct thread *td, int fd, struct file **fpp);
+int fget_fcntl(struct thread *td, int fd, cap_rights_t *rightsp,
+ int needfcntl, struct file **fpp);
int _fdrop(struct file *fp, struct thread *td);
#ifndef __rtems__
-/*
- * The socket operations are used a couple of places.
- * XXX: This is wrong, they should go through the operations vector for
- * XXX: sockets instead of going directly for the individual functions. /phk
- */
-fo_rdwr_t soo_read;
-fo_rdwr_t soo_write;
-fo_truncate_t soo_truncate;
-fo_ioctl_t soo_ioctl;
-fo_poll_t soo_poll;
-fo_kqfilter_t soo_kqfilter;
-fo_stat_t soo_stat;
-fo_close_t soo_close;
-
+fo_rdwr_t invfo_rdwr;
+fo_truncate_t invfo_truncate;
+fo_ioctl_t invfo_ioctl;
+fo_poll_t invfo_poll;
+fo_kqfilter_t invfo_kqfilter;
fo_chmod_t invfo_chmod;
fo_chown_t invfo_chown;
+fo_sendfile_t invfo_sendfile;
+
+fo_sendfile_t vn_sendfile;
+fo_seek_t vn_seek;
+fo_fill_kinfo_t vn_fill_kinfo;
+int vn_fill_kinfo_vnode(struct vnode *vp, struct kinfo_file *kif);
#else /* __rtems__ */
int rtems_bsd_soo_kqfilter(rtems_libio_t *iop, struct knote *kn);
#endif /* __rtems__ */
@@ -367,17 +381,18 @@ finit(struct file *fp, u_int fflag, short type, void *data,
pathinfo->handlers = ops;
}
#endif /* __rtems__ */
-int fgetvp(struct thread *td, int fd, cap_rights_t rights, struct vnode **vpp);
-int fgetvp_exec(struct thread *td, int fd, cap_rights_t rights,
+int fgetvp(struct thread *td, int fd, cap_rights_t *rightsp,
+ struct vnode **vpp);
+int fgetvp_exec(struct thread *td, int fd, cap_rights_t *rightsp,
struct vnode **vpp);
-int fgetvp_rights(struct thread *td, int fd, cap_rights_t need,
- cap_rights_t *have, struct vnode **vpp);
-int fgetvp_read(struct thread *td, int fd, cap_rights_t rights,
+int fgetvp_rights(struct thread *td, int fd, cap_rights_t *needrightsp,
+ struct filecaps *havecaps, struct vnode **vpp);
+int fgetvp_read(struct thread *td, int fd, cap_rights_t *rightsp,
struct vnode **vpp);
-int fgetvp_write(struct thread *td, int fd, cap_rights_t rights,
+int fgetvp_write(struct thread *td, int fd, cap_rights_t *rightsp,
struct vnode **vpp);
-int fgetsock(struct thread *td, int fd, cap_rights_t rights,
+int fgetsock(struct thread *td, int fd, cap_rights_t *rightsp,
struct socket **spp, u_int *fflagp);
void fputsock(struct socket *sp);
@@ -408,6 +423,7 @@ static __inline fo_stat_t fo_stat;
static __inline fo_close_t fo_close;
static __inline fo_chmod_t fo_chmod;
static __inline fo_chown_t fo_chown;
+static __inline fo_sendfile_t fo_sendfile;
static __inline int
fo_read(struct file *fp, struct uio *uio, struct ucred *active_cred,
@@ -516,6 +532,49 @@ fo_chown(struct file *fp, uid_t uid, gid_t gid, struct ucred *active_cred,
return ((*fp->f_ops->fo_chown)(fp, uid, gid, active_cred, td));
}
+
+static __inline int
+fo_sendfile(struct file *fp, int sockfd, struct uio *hdr_uio,
+ struct uio *trl_uio, off_t offset, size_t nbytes, off_t *sent, int flags,
+ struct thread *td)
+{
+
+ return ((*fp->f_ops->fo_sendfile)(fp, sockfd, hdr_uio, trl_uio, offset,
+ nbytes, sent, flags, td));
+}
+
+static __inline int
+fo_seek(struct file *fp, off_t offset, int whence, struct thread *td)
+{
+
+ return ((*fp->f_ops->fo_seek)(fp, offset, whence, td));
+}
+
+static __inline int
+fo_fill_kinfo(struct file *fp, struct kinfo_file *kif, struct filedesc *fdp)
+{
+
+ return ((*fp->f_ops->fo_fill_kinfo)(fp, kif, fdp));
+}
+
+static __inline int
+fo_mmap(struct file *fp, vm_map_t map, vm_offset_t *addr, vm_size_t size,
+ vm_prot_t prot, vm_prot_t cap_maxprot, int flags, vm_ooffset_t foff,
+ struct thread *td)
+{
+
+ if (fp->f_ops->fo_mmap == NULL)
+ return (ENODEV);
+ return ((*fp->f_ops->fo_mmap)(fp, map, addr, size, prot, cap_maxprot,
+ flags, foff, td));
+}
+
+static __inline int
+fo_aio_queue(struct file *fp, struct kaiocb *job)
+{
+
+ return ((*fp->f_ops->fo_aio_queue)(fp, job));
+}
#endif /* __rtems__ */
#endif /* _KERNEL */
diff --git a/freebsd/sys/sys/filedesc.h b/freebsd/sys/sys/filedesc.h
index ad18114a..30c2deef 100644
--- a/freebsd/sys/sys/filedesc.h
+++ b/freebsd/sys/sys/filedesc.h
@@ -33,14 +33,41 @@
#ifndef _SYS_FILEDESC_H_
#define _SYS_FILEDESC_H_
+#include <sys/caprights.h>
#include <sys/queue.h>
#include <sys/event.h>
#include <rtems/bsd/sys/lock.h>
#include <sys/priority.h>
+#include <sys/seq.h>
#include <sys/sx.h>
#include <machine/_limits.h>
+struct filecaps {
+ cap_rights_t fc_rights; /* per-descriptor capability rights */
+ u_long *fc_ioctls; /* per-descriptor allowed ioctls */
+ int16_t fc_nioctls; /* fc_ioctls array size */
+ uint32_t fc_fcntls; /* per-descriptor allowed fcntls */
+};
+
+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 */
+};
+#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))
+
+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)
+
/*
* This structure is used for the management of descriptors. It may be
* shared by multiple processes.
@@ -49,18 +76,16 @@
#ifndef __rtems__
struct filedesc {
- struct file **fd_ofiles; /* file structures for open files */
- char *fd_ofileflags; /* per-process open file flags */
+ struct fdescenttbl *fd_files; /* open files table */
struct vnode *fd_cdir; /* current directory */
struct vnode *fd_rdir; /* root directory */
struct vnode *fd_jdir; /* jail root directory */
- int fd_nfiles; /* number of open files allocated */
NDSLOTTYPE *fd_map; /* bitmap of free fds */
int fd_lastfile; /* high-water mark of fd_ofiles */
int fd_freefile; /* approx. next free file */
u_short fd_cmask; /* mask for file creation */
- u_short fd_refcnt; /* thread reference count */
- u_short fd_holdcnt; /* hold count on structure + mutex */
+ int fd_refcnt; /* thread reference count */
+ int fd_holdcnt; /* hold count on structure + mutex */
struct sx fd_sx; /* protects members of this struct */
struct kqlist fd_kqlist; /* list of kqueues on this filedesc */
int fd_holdleaderscount; /* block fdfree() for shared close() */
@@ -89,6 +114,8 @@ struct filedesc_to_leader {
struct filedesc_to_leader *fdl_prev;
struct filedesc_to_leader *fdl_next;
};
+#define fd_nfiles fd_files->fdt_nfiles
+#define fd_ofiles fd_files->fdt_ofiles
#else /* __rtems__ */
struct filedesc_to_leader;
#endif /* __rtems__ */
@@ -96,7 +123,7 @@ struct filedesc_to_leader;
/*
* Per-process open flags.
*/
-#define UF_EXCLOSE 0x01 /* auto-close on exec */
+#define UF_EXCLOSE 0x01 /* auto-close on exec */
#ifdef _KERNEL
#ifdef __rtems__
@@ -124,24 +151,48 @@ struct filedesc_to_leader;
SX_NOTRECURSED)
#define FILEDESC_XLOCK_ASSERT(fdp) sx_assert(&(fdp)->fd_sx, SX_XLOCKED | \
SX_NOTRECURSED)
+#define FILEDESC_UNLOCK_ASSERT(fdp) sx_assert(&(fdp)->fd_sx, SX_UNLOCKED)
+
+/* Operation types for kern_dup(). */
+enum {
+ FDDUP_NORMAL, /* dup() behavior. */
+ FDDUP_FCNTL, /* fcntl()-style errors. */
+ FDDUP_FIXED, /* Force fixed allocation. */
+ FDDUP_MUSTREPLACE, /* Target must exist. */
+ FDDUP_LASTMODE,
+};
+
+/* Flags for kern_dup(). */
+#define FDDUP_FLAG_CLOEXEC 0x1 /* Atomically set UF_EXCLOSE. */
+
+/* For backward compatibility. */
+#define falloc(td, resultfp, resultfd, flags) \
+ falloc_caps(td, resultfp, resultfd, flags, NULL)
struct thread;
+void filecaps_init(struct filecaps *fcaps);
+int filecaps_copy(const struct filecaps *src, struct filecaps *dst,
+ bool locked);
+void filecaps_move(struct filecaps *src, struct filecaps *dst);
+void filecaps_free(struct filecaps *fcaps);
+
int closef(struct file *fp, struct thread *td);
-int dupfdopen(struct thread *td, struct filedesc *fdp, int indx, int dfd,
- int mode, int error);
+int dupfdopen(struct thread *td, struct filedesc *fdp, int dfd, int mode,
+ int openerror, int *indxp);
#ifndef __rtems__
-int falloc(struct thread *td, struct file **resultfp, int *resultfd,
- int flags);
+int falloc_caps(struct thread *td, struct file **resultfp, int *resultfd,
+ int flags, struct filecaps *fcaps);
#else /* __rtems__ */
static inline int
-falloc(struct thread *td, struct file **resultfp, int *resultfd,
- int flags)
+falloc_caps(struct thread *td, struct file **resultfp, int *resultfd,
+ int flags, struct filecaps *fcaps)
{
rtems_libio_t *iop = rtems_libio_allocate();
(void) td;
(void) flags;
+ (void) fcaps;
*resultfp = rtems_bsd_iop_to_fp(iop);
@@ -157,49 +208,63 @@ falloc(struct thread *td, struct file **resultfp, int *resultfd,
}
#endif /* __rtems__ */
int falloc_noinstall(struct thread *td, struct file **resultfp);
-int finstall(struct thread *td, struct file *fp, int *resultfp, int flags);
+void _finstall(struct filedesc *fdp, struct file *fp, int fd, int flags,
+ struct filecaps *fcaps);
+int finstall(struct thread *td, struct file *fp, int *resultfd, int flags,
+ struct filecaps *fcaps);
int fdalloc(struct thread *td, int minfd, int *result);
int fdallocn(struct thread *td, int minfd, int *fds, int n);
-int fdavail(struct thread *td, int n);
int fdcheckstd(struct thread *td);
#ifndef __rtems__
-void fdclose(struct filedesc *fdp, struct file *fp, int idx, struct thread *td);
+void fdclose(struct thread *td, struct file *fp, int idx);
#else /* __rtems__ */
static inline void
-rtems_bsd_fdclose(struct file *fp, int idx, struct thread *td)
+fdclose(struct thread *td, struct file *fp, int idx)
{
- (void) idx;
- (void) td;
+ (void)td;
+ (void)idx;
rtems_libio_free(&fp->f_io);
}
-
-#define fdclose(fdp, fp, idx, td) rtems_bsd_fdclose(fp, idx, td)
#endif /* __rtems__ */
void fdcloseexec(struct thread *td);
+void fdsetugidsafety(struct thread *td);
struct filedesc *fdcopy(struct filedesc *fdp);
-void fdunshare(struct proc *p, struct thread *td);
-void fdfree(struct thread *td);
-struct filedesc *fdinit(struct filedesc *fdp);
+int fdcopy_remapped(struct filedesc *fdp, const int *fds, size_t nfds,
+ struct filedesc **newfdp);
+void fdinstall_remapped(struct thread *td, struct filedesc *fdp);
+void fdunshare(struct thread *td);
+void fdescfree(struct thread *td);
+void fdescfree_remapped(struct filedesc *fdp);
+struct filedesc *fdinit(struct filedesc *fdp, bool prepfiles);
struct filedesc *fdshare(struct filedesc *fdp);
struct filedesc_to_leader *
filedesc_to_leader_alloc(struct filedesc_to_leader *old,
struct filedesc *fdp, struct proc *leader);
-int getvnode(struct filedesc *fdp, int fd, cap_rights_t rights,
+int getvnode(struct thread *td, int fd, cap_rights_t *rightsp,
struct file **fpp);
void mountcheckdirs(struct vnode *olddp, struct vnode *newdp);
-void setugidsafety(struct thread *td);
/* Return a referenced file from an unlocked descriptor. */
#ifndef __rtems__
-struct file *fget_unlocked(struct filedesc *fdp, int fd);
+int fget_unlocked(struct filedesc *fdp, int fd, cap_rights_t *needrightsp,
+ struct file **fpp, seq_t *seqp);
#else /* __rtems__ */
-static inline struct file *
-fget_unlocked(struct filedesc *fdp, int fd)
+static inline int
+fget_unlocked(struct filedesc *fdp, int fd, cap_rights_t *needrightsp,
+ struct file **fpp, seq_t *seqp)
{
- (void) fdp;
+ (void)fdp;
+ (void)needrightsp;
+ (void)seqp;
+
+ *fpp = rtems_bsd_get_file(fd);
- return rtems_bsd_get_file(fd);
+ if (*fpp != NULL) {
+ return (0);
+ } else {
+ return (EBADF);
+ }
}
#endif /* __rtems__ */
@@ -209,10 +274,27 @@ static __inline struct file *
fget_locked(struct filedesc *fdp, int fd)
{
- return (fd < 0 || fd >= fdp->fd_nfiles ? NULL : fdp->fd_ofiles[fd]);
+ FILEDESC_LOCK_ASSERT(fdp);
+
+ if (fd < 0 || fd > fdp->fd_lastfile)
+ return (NULL);
+
+ return (fdp->fd_ofiles[fd].fde_file);
+}
+
+static __inline bool
+fd_modified(struct filedesc *fdp, int fd, seq_t seq)
+{
+
+ return (!seq_consistent(fd_seq(fdp->fd_files, fd), seq));
}
#endif /* __rtems__ */
+/* cdir/rdir/jdir manipulation functions. */
+void pwd_chdir(struct thread *td, struct vnode *vp);
+int pwd_chroot(struct thread *td, struct vnode *vp);
+void pwd_ensure_dirs(void);
+
#endif /* _KERNEL */
#endif /* !_SYS_FILEDESC_H_ */
diff --git a/freebsd/sys/sys/fnv_hash.h b/freebsd/sys/sys/fnv_hash.h
index 1b9fa9f5..e574e0e0 100644
--- a/freebsd/sys/sys/fnv_hash.h
+++ b/freebsd/sys/sys/fnv_hash.h
@@ -61,7 +61,7 @@ static __inline Fnv64_t
fnv_64_str(const char *str, Fnv64_t hval)
{
const u_int8_t *s = (const u_int8_t *)str;
- u_register_t c; /* 32 bit on i386, 64 bit on alpha,ia64 */
+ u_register_t c; /* 32 bit on i386, 64 bit on alpha */
while ((c = *s++) != 0) {
hval *= FNV_64_PRIME;
diff --git a/freebsd/sys/sys/gpio.h b/freebsd/sys/sys/gpio.h
new file mode 100644
index 00000000..9b0a1b55
--- /dev/null
+++ b/freebsd/sys/sys/gpio.h
@@ -0,0 +1,108 @@
+/* $NetBSD: gpio.h,v 1.7 2009/09/25 20:27:50 mbalmer Exp $ */
+/* $OpenBSD: gpio.h,v 1.7 2008/11/26 14:51:20 mbalmer Exp $ */
+/*-
+ * Copyright (c) 2009, Oleksandr Tymoshenko <gonzo@FreeBSD.org>
+ * All rights reserved.
+ *
+ * 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 unmodified, 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$
+ *
+ */
+
+/*
+ * Copyright (c) 2009 Marc Balmer <marc@msys.ch>
+ * Copyright (c) 2004 Alexander Yurchenko <grange@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef __GPIO_H__
+#define __GPIO_H__
+
+#include <sys/ioccom.h>
+
+/* GPIO pin states */
+#define GPIO_PIN_LOW 0x00 /* low level (logical 0) */
+#define GPIO_PIN_HIGH 0x01 /* high level (logical 1) */
+
+/* Max name length of a pin */
+#define GPIOMAXNAME 64
+
+/* GPIO pin configuration flags */
+#define GPIO_PIN_INPUT 0x00000001 /* input direction */
+#define GPIO_PIN_OUTPUT 0x00000002 /* output direction */
+#define GPIO_PIN_OPENDRAIN 0x00000004 /* open-drain output */
+#define GPIO_PIN_PUSHPULL 0x00000008 /* push-pull output */
+#define GPIO_PIN_TRISTATE 0x00000010 /* output disabled */
+#define GPIO_PIN_PULLUP 0x00000020 /* internal pull-up enabled */
+#define GPIO_PIN_PULLDOWN 0x00000040 /* internal pull-down enabled */
+#define GPIO_PIN_INVIN 0x00000080 /* invert input */
+#define GPIO_PIN_INVOUT 0x00000100 /* invert output */
+#define GPIO_PIN_PULSATE 0x00000200 /* pulsate in hardware */
+/* GPIO interrupt capabilities */
+#define GPIO_INTR_NONE 0x00000000 /* no interrupt support */
+#define GPIO_INTR_LEVEL_LOW 0x00010000 /* level trigger, low */
+#define GPIO_INTR_LEVEL_HIGH 0x00020000 /* level trigger, high */
+#define GPIO_INTR_EDGE_RISING 0x00040000 /* edge trigger, rising */
+#define GPIO_INTR_EDGE_FALLING 0x00080000 /* edge trigger, falling */
+#define GPIO_INTR_EDGE_BOTH 0x00100000 /* edge trigger, both */
+#define GPIO_INTR_MASK (GPIO_INTR_LEVEL_LOW | GPIO_INTR_LEVEL_HIGH | \
+ GPIO_INTR_EDGE_RISING | \
+ GPIO_INTR_EDGE_FALLING | GPIO_INTR_EDGE_BOTH)
+
+struct gpio_pin {
+ uint32_t gp_pin; /* pin number */
+ char gp_name[GPIOMAXNAME]; /* human-readable name */
+ uint32_t gp_caps; /* capabilities */
+ uint32_t gp_flags; /* current flags */
+};
+
+/* GPIO pin request (read/write/toggle) */
+struct gpio_req {
+ uint32_t gp_pin; /* pin number */
+ uint32_t gp_value; /* value */
+};
+
+/*
+ * ioctls
+ */
+#define GPIOMAXPIN _IOR('G', 0, int)
+#define GPIOGETCONFIG _IOWR('G', 1, struct gpio_pin)
+#define GPIOSETCONFIG _IOW('G', 2, struct gpio_pin)
+#define GPIOGET _IOWR('G', 3, struct gpio_req)
+#define GPIOSET _IOW('G', 4, struct gpio_req)
+#define GPIOTOGGLE _IOWR('G', 5, struct gpio_req)
+#define GPIOSETNAME _IOW('G', 6, struct gpio_pin)
+
+#endif /* __GPIO_H__ */
diff --git a/freebsd/sys/sys/hash.h b/freebsd/sys/sys/hash.h
index 6ad89c5e..8abf17bb 100644
--- a/freebsd/sys/sys/hash.h
+++ b/freebsd/sys/sys/hash.h
@@ -118,4 +118,17 @@ hash32_strne(const void *buf, size_t len, int end, const char **ep,
return hash;
}
+
+#ifdef _KERNEL
+/*
+ * Hashing function from Bob Jenkins. Implementation in libkern/jenkins_hash.c.
+ */
+uint32_t jenkins_hash(const void *, size_t, uint32_t);
+uint32_t jenkins_hash32(const uint32_t *, size_t, uint32_t);
+
+uint32_t murmur3_32_hash(const void *, size_t, uint32_t);
+uint32_t murmur3_32_hash32(const uint32_t *, size_t, uint32_t);
+
+#endif /* _KERNEL */
+
#endif /* !_SYS_HASH_H_ */
diff --git a/freebsd/sys/sys/hhook.h b/freebsd/sys/sys/hhook.h
index 0d54eda4..7de47d48 100644
--- a/freebsd/sys/sys/hhook.h
+++ b/freebsd/sys/sys/hhook.h
@@ -64,6 +64,9 @@
/* Helper hook types. */
#define HHOOK_TYPE_TCP 1
+#define HHOOK_TYPE_SOCKET 2
+#define HHOOK_TYPE_IPSEC_IN 3
+#define HHOOK_TYPE_IPSEC_OUT 4
struct helper;
struct osd;
diff --git a/freebsd/sys/sys/interrupt.h b/freebsd/sys/sys/interrupt.h
index 3dace82e..c320e5fc 100644
--- a/freebsd/sys/sys/interrupt.h
+++ b/freebsd/sys/sys/interrupt.h
@@ -112,13 +112,13 @@ struct intr_event {
void (*ie_pre_ithread)(void *);
void (*ie_post_ithread)(void *);
void (*ie_post_filter)(void *);
- int (*ie_assign_cpu)(void *, u_char);
+ int (*ie_assign_cpu)(void *, int);
int ie_flags;
int ie_count; /* Loop counter. */
int ie_warncnt; /* Rate-check interrupt storm warns. */
struct timeval ie_warntm;
int ie_irq; /* Physical irq number if !SOFT. */
- u_char ie_cpu; /* CPU this event is bound to. */
+ int ie_cpu; /* CPU this event is bound to. */
};
/* Interrupt event flags kept in ie_flags. */
@@ -161,11 +161,11 @@ u_char intr_priority(enum intr_type flags);
int intr_event_add_handler(struct intr_event *ie, const char *name,
driver_filter_t filter, driver_intr_t handler, void *arg,
u_char pri, enum intr_type flags, void **cookiep);
-int intr_event_bind(struct intr_event *ie, u_char cpu);
+int intr_event_bind(struct intr_event *ie, int cpu);
int intr_event_create(struct intr_event **event, void *source,
int flags, int irq, void (*pre_ithread)(void *),
void (*post_ithread)(void *), void (*post_filter)(void *),
- int (*assign_cpu)(void *, u_char), const char *fmt, ...)
+ int (*assign_cpu)(void *, int), const char *fmt, ...)
__printflike(9, 10);
int intr_event_describe_handler(struct intr_event *ie, void *cookie,
const char *descr);
diff --git a/freebsd/sys/sys/jail.h b/freebsd/sys/sys/jail.h
index 063dd6a3..5fcbaf39 100644
--- a/freebsd/sys/sys/jail.h
+++ b/freebsd/sys/sys/jail.h
@@ -134,6 +134,7 @@ MALLOC_DECLARE(M_PRISON);
#include <sys/osd.h>
#define HOSTUUIDLEN 64
+#define OSRELEASELEN 32
struct racct;
struct prison_racct;
@@ -148,7 +149,6 @@ struct prison_racct;
* (p) locked by pr_mtx
* (c) set only during creation before the structure is shared, no mutex
* required to read
- * (d) set only during destruction of jail, no mutex needed
*/
struct prison {
TAILQ_ENTRY(prison) pr_list; /* (a) all prisons */
@@ -160,7 +160,7 @@ struct prison {
LIST_ENTRY(prison) pr_sibling; /* (a) next in parent's list */
struct prison *pr_parent; /* (c) containing jail */
struct mtx pr_mtx;
- struct task pr_task; /* (d) destroy task */
+ struct task pr_task; /* (c) destroy task */
struct osd pr_osd; /* (p) additional data */
struct cpuset *pr_cpuset; /* (p) cpuset */
struct vnet *pr_vnet; /* (c) network stack */
@@ -177,13 +177,15 @@ struct prison {
int pr_securelevel; /* (p) securelevel */
int pr_enforce_statfs; /* (p) statfs permission */
int pr_devfs_rsnum; /* (p) devfs ruleset */
- int pr_spare[4];
+ int pr_spare[3];
+ int pr_osreldate; /* (c) kern.osreldate value */
unsigned long pr_hostid; /* (p) jail hostid */
char pr_name[MAXHOSTNAMELEN]; /* (p) admin jail name */
char pr_path[MAXPATHLEN]; /* (c) chroot path */
char pr_hostname[MAXHOSTNAMELEN]; /* (p) jail hostname */
char pr_domainname[MAXHOSTNAMELEN]; /* (p) jail domainname */
char pr_hostuuid[HOSTUUIDLEN]; /* (p) jail hostuuid */
+ char pr_osrelease[OSRELEASELEN]; /* (c) kern.osrelease value */
};
struct prison_racct {
@@ -201,15 +203,12 @@ struct prison_racct {
#define PR_IP4_USER 0x00000004 /* Restrict IPv4 addresses */
#define PR_IP6_USER 0x00000008 /* Restrict IPv6 addresses */
#define PR_VNET 0x00000010 /* Virtual network stack */
-#define PR_IP4_DISABLE 0x00000020 /* Disable IPv4 */
-#define PR_IP6_DISABLE 0x00000040 /* Disable IPv6 */
#define PR_IP4_SADDRSEL 0x00000080 /* Do IPv4 src addr sel. or use the */
/* primary jail address. */
#define PR_IP6_SADDRSEL 0x00000100 /* Do IPv6 src addr sel. or use the */
/* primary jail address. */
/* Internal flag bits */
-#define PR_REMOVE 0x01000000 /* In process of being removed */
#define PR_IP4 0x02000000 /* IPv4 restricted or disabled */
/* by this jail or an ancestor */
#define PR_IP6 0x04000000 /* IPv6 restricted or disabled */
@@ -227,7 +226,11 @@ struct prison_racct {
#define PR_ALLOW_MOUNT_NULLFS 0x0100
#define PR_ALLOW_MOUNT_ZFS 0x0200
#define PR_ALLOW_MOUNT_PROCFS 0x0400
-#define PR_ALLOW_ALL 0x07ff
+#define PR_ALLOW_MOUNT_TMPFS 0x0800
+#define PR_ALLOW_MOUNT_FDESCFS 0x1000
+#define PR_ALLOW_MOUNT_LINPROCFS 0x2000
+#define PR_ALLOW_MOUNT_LINSYSFS 0x4000
+#define PR_ALLOW_ALL 0x7fff
/*
* OSD methods
@@ -237,7 +240,8 @@ struct prison_racct {
#define PR_METHOD_SET 2
#define PR_METHOD_CHECK 3
#define PR_METHOD_ATTACH 4
-#define PR_MAXMETHOD 5
+#define PR_METHOD_REMOVE 5
+#define PR_MAXMETHOD 6
/*
* Lock/unlock a prison.
@@ -362,6 +366,7 @@ void getcredhostname(struct ucred *, char *, size_t);
void getcreddomainname(struct ucred *, char *, size_t);
void getcredhostuuid(struct ucred *, char *, size_t);
void getcredhostid(struct ucred *, unsigned long *);
+void prison0_init(void);
int prison_allow(struct ucred *, unsigned);
int prison_check(struct ucred *cred1, struct ucred *cred2);
int prison_owns_vnet(struct ucred *);
@@ -387,8 +392,11 @@ int prison_equal_ip4(struct prison *, struct prison *);
int prison_get_ip4(struct ucred *cred, struct in_addr *ia);
int prison_local_ip4(struct ucred *cred, struct in_addr *ia);
int prison_remote_ip4(struct ucred *cred, struct in_addr *ia);
-int prison_check_ip4(struct ucred *cred, struct in_addr *ia);
+int prison_check_ip4(const struct ucred *, const struct in_addr *);
+int prison_check_ip4_locked(const struct prison *, const struct in_addr *);
int prison_saddrsel_ip4(struct ucred *, struct in_addr *);
+int prison_restrict_ip4(struct prison *, struct in_addr *);
+int prison_qcmp_v4(const void *, const void *);
#ifdef INET6
#ifndef __rtems__
int prison_equal_ip6(struct prison *, struct prison *);
@@ -398,8 +406,11 @@ int prison_equal_ip6(struct prison *, struct prison *);
int prison_get_ip6(struct ucred *, struct in6_addr *);
int prison_local_ip6(struct ucred *, struct in6_addr *, int);
int prison_remote_ip6(struct ucred *, struct in6_addr *);
-int prison_check_ip6(struct ucred *, struct in6_addr *);
+int prison_check_ip6(const struct ucred *, const struct in6_addr *);
+int prison_check_ip6_locked(const struct prison *, const struct in6_addr *);
int prison_saddrsel_ip6(struct ucred *, struct in6_addr *);
+int prison_restrict_ip6(struct prison *, struct in6_addr *);
+int prison_qcmp_v6(const void *, const void *);
#endif
int prison_check_af(struct ucred *cred, int af);
int prison_if(struct ucred *cred, struct sockaddr *sa);
@@ -407,7 +418,8 @@ char *prison_name(struct prison *, struct prison *);
int prison_priv_check(struct ucred *cred, int priv);
int sysctl_jail_param(SYSCTL_HANDLER_ARGS);
void prison_racct_foreach(void (*callback)(struct racct *racct,
- void *arg2, void *arg3), void *arg2, void *arg3);
+ void *arg2, void *arg3), void (*pre)(void), void (*post)(void),
+ void *arg2, void *arg3);
struct prison_racct *prison_racct_find(const char *name);
void prison_racct_hold(struct prison_racct *prr);
void prison_racct_free(struct prison_racct *prr);
diff --git a/freebsd/sys/sys/kernel.h b/freebsd/sys/sys/kernel.h
index 687ee531..8f8f4ea7 100644
--- a/freebsd/sys/sys/kernel.h
+++ b/freebsd/sys/sys/kernel.h
@@ -91,22 +91,19 @@ extern volatile int32_t _bsd_ticks;
* for binary compatibility with inserted elements.
*
* The SI_SUB_LAST value must have the highest lexical value.
- *
- * The SI_SUB_SWAP values represent a value used by
- * the BSD 4.4Lite but not by FreeBSD; it is maintained in dependent
- * order to support porting.
*/
enum sysinit_sub_id {
SI_SUB_DUMMY = 0x0000000, /* not executed; for linker*/
SI_SUB_DONE = 0x0000001, /* processed*/
SI_SUB_TUNABLES = 0x0700000, /* establish tunable values */
SI_SUB_COPYRIGHT = 0x0800001, /* first use of console*/
- SI_SUB_SETTINGS = 0x0880000, /* check and recheck settings */
- SI_SUB_MTX_POOL_STATIC = 0x0900000, /* static mutex pool */
- SI_SUB_LOCKMGR = 0x0980000, /* lockmgr locks */
SI_SUB_VM = 0x1000000, /* virtual memory system init*/
SI_SUB_KMEM = 0x1800000, /* kernel memory*/
- SI_SUB_KVM_RSRC = 0x1A00000, /* kvm operational limits*/
+ SI_SUB_HYPERVISOR = 0x1A40000, /*
+ * Hypervisor detection and
+ * virtualization support
+ * setup.
+ */
SI_SUB_WITNESS = 0x1A80000, /* witness initialization */
SI_SUB_MTX_POOL_DYNAMIC = 0x1AC0000, /* dynamic mutex pool */
SI_SUB_LOCK = 0x1B00000, /* various locks */
@@ -115,8 +112,8 @@ enum sysinit_sub_id {
SI_SUB_KLD = 0x2000000, /* KLD and module setup */
SI_SUB_CPU = 0x2100000, /* CPU resource(s)*/
SI_SUB_RACCT = 0x2110000, /* resource accounting */
- SI_SUB_RANDOM = 0x2120000, /* random number generator */
SI_SUB_KDTRACE = 0x2140000, /* Kernel dtrace hooks */
+ SI_SUB_RANDOM = 0x2160000, /* random number generator */
SI_SUB_MAC = 0x2180000, /* TrustedBSD MAC subsystem */
SI_SUB_MAC_POLICY = 0x21C0000, /* TrustedBSD MAC policies */
SI_SUB_MAC_LATE = 0x21D0000, /* TrustedBSD MAC subsystem */
@@ -127,14 +124,15 @@ enum sysinit_sub_id {
SI_SUB_RUN_QUEUE = 0x2400000, /* set up run queue*/
SI_SUB_KTRACE = 0x2480000, /* ktrace */
SI_SUB_OPENSOLARIS = 0x2490000, /* OpenSolaris compatibility */
- SI_SUB_CYCLIC = 0x24A0000, /* Cyclic timers */
SI_SUB_AUDIT = 0x24C0000, /* audit */
SI_SUB_CREATE_INIT = 0x2500000, /* create init process*/
SI_SUB_SCHED_IDLE = 0x2600000, /* required idle procs */
SI_SUB_MBUF = 0x2700000, /* mbuf subsystem */
SI_SUB_INTR = 0x2800000, /* interrupt threads */
- SI_SUB_SOFTINTR = 0x2800001, /* start soft interrupt thread */
- SI_SUB_ACL = 0x2900000, /* start for filesystem ACLs */
+#ifdef EARLY_AP_STARTUP
+ SI_SUB_SMP = 0x2900000, /* start the APs*/
+#endif
+ SI_SUB_SOFTINTR = 0x2A00000, /* start soft interrupt thread */
SI_SUB_DEVFS = 0x2F00000, /* devfs ready for devices */
SI_SUB_INIT_IF = 0x3000000, /* prep for net interfaces */
SI_SUB_NETGRAPH = 0x3010000, /* Let Netgraph initialize */
@@ -145,7 +143,6 @@ enum sysinit_sub_id {
SI_SUB_CONFIGURE = 0x3800000, /* Configure devices */
SI_SUB_VFS = 0x4000000, /* virtual filesystem*/
SI_SUB_CLOCKS = 0x4800000, /* real time and stat clocks*/
- SI_SUB_CLIST = 0x5800000, /* clists*/
SI_SUB_SYSV_SHM = 0x6400000, /* System V shared memory*/
SI_SUB_SYSV_SEM = 0x6800000, /* System V semaphores*/
SI_SUB_SYSV_MSG = 0x6C00000, /* System V message queues*/
@@ -153,18 +150,18 @@ enum sysinit_sub_id {
SI_SUB_PSEUDO = 0x7000000, /* pseudo devices*/
SI_SUB_EXEC = 0x7400000, /* execve() handlers */
SI_SUB_PROTO_BEGIN = 0x8000000, /* VNET initialization */
+ SI_SUB_PROTO_PFIL = 0x8100000, /* Initialize pfil before FWs */
SI_SUB_PROTO_IF = 0x8400000, /* interfaces*/
SI_SUB_PROTO_DOMAININIT = 0x8600000, /* domain registration system */
+ SI_SUB_PROTO_MC = 0x8700000, /* Multicast */
SI_SUB_PROTO_DOMAIN = 0x8800000, /* domains (address families?)*/
- SI_SUB_PROTO_IFATTACHDOMAIN = 0x8800001, /* domain dependent data init*/
+ SI_SUB_PROTO_FIREWALL = 0x8806000, /* Firewalls */
+ SI_SUB_PROTO_IFATTACHDOMAIN = 0x8808000,/* domain dependent data init */
SI_SUB_PROTO_END = 0x8ffffff, /* VNET helper functions */
SI_SUB_KPROF = 0x9000000, /* kernel profiling*/
SI_SUB_KICK_SCHEDULER = 0xa000000, /* start the timeout events*/
SI_SUB_INT_CONFIG_HOOKS = 0xa800000, /* Interrupts enabled config */
SI_SUB_ROOT_CONF = 0xb000000, /* Find root devices */
- SI_SUB_DUMP_CONF = 0xb200000, /* Find dump devices */
- SI_SUB_RAID = 0xb380000, /* Configure GEOM classes */
- SI_SUB_SWAP = 0xc000000, /* swap */
SI_SUB_INTRINSIC_POST = 0xd000000, /* proc 0 cleanup*/
SI_SUB_SYSCALLS = 0xd800000, /* register system calls */
SI_SUB_VNET_DONE = 0xdc00000, /* vnet registration complete */
@@ -174,8 +171,10 @@ enum sysinit_sub_id {
SI_SUB_KTHREAD_BUF = 0xea00000, /* buffer daemon*/
SI_SUB_KTHREAD_UPDATE = 0xec00000, /* update daemon*/
SI_SUB_KTHREAD_IDLE = 0xee00000, /* idle procs*/
+#ifndef EARLY_AP_STARTUP
SI_SUB_SMP = 0xf000000, /* start the APs*/
- SI_SUB_RACCTD = 0xf100000, /* start raccd*/
+#endif
+ SI_SUB_RACCTD = 0xf100000, /* start racctd*/
SI_SUB_LAST = 0xfffffff /* final initialization */
};
@@ -303,7 +302,7 @@ void sysinit_add(struct sysinit **set, struct sysinit **set_end);
/*
* Infrastructure for tunable 'constants'. Value may be specified at compile
* time or kernel load time. Rules relating tunables together can be placed
- * in a SYSINIT function at SI_SUB_TUNABLES with SI_ORDER_LAST.
+ * in a SYSINIT function at SI_SUB_TUNABLES with SI_ORDER_ANY.
*
* WARNING: developers should never use the reserved suffixes specified in
* loader.conf(5) for any tunables or conflicts will result.
@@ -368,6 +367,44 @@ struct tunable_ulong {
#define TUNABLE_ULONG_FETCH(path, var) getenv_ulong((path), (var))
/*
+ * int64_t
+ */
+extern void tunable_int64_init(void *);
+struct tunable_int64 {
+ const char *path;
+ int64_t *var;
+};
+#define TUNABLE_INT64(path, var) \
+ static struct tunable_int64 __CONCAT(__tunable_int64_, __LINE__) = { \
+ (path), \
+ (var), \
+ }; \
+ SYSINIT(__CONCAT(__Tunable_init_, __LINE__), \
+ SI_SUB_TUNABLES, SI_ORDER_MIDDLE, tunable_int64_init, \
+ &__CONCAT(__tunable_int64_, __LINE__))
+
+#define TUNABLE_INT64_FETCH(path, var) getenv_int64((path), (var))
+
+/*
+ * uint64_t
+ */
+extern void tunable_uint64_init(void *);
+struct tunable_uint64 {
+ const char *path;
+ uint64_t *var;
+};
+#define TUNABLE_UINT64(path, var) \
+ static struct tunable_ulong __CONCAT(__tunable_uint64_, __LINE__) = { \
+ (path), \
+ (var), \
+ }; \
+ SYSINIT(__CONCAT(__Tunable_init_, __LINE__), \
+ SI_SUB_TUNABLES, SI_ORDER_MIDDLE, tunable_uint64_init, \
+ &__CONCAT(__tunable_uint64_, __LINE__))
+
+#define TUNABLE_UINT64_FETCH(path, var) getenv_uint64((path), (var))
+
+/*
* quad
*/
extern void tunable_quad_init(void *);
diff --git a/freebsd/sys/sys/khelp.h b/freebsd/sys/sys/khelp.h
index db12d6bb..f542b148 100644
--- a/freebsd/sys/sys/khelp.h
+++ b/freebsd/sys/sys/khelp.h
@@ -55,6 +55,7 @@ struct osd;
/* Helper classes. */
#define HELPER_CLASS_TCP 0x00000001
+#define HELPER_CLASS_SOCKET 0x00000002
/* Public KPI functions. */
int khelp_register_helper(struct helper *h);
diff --git a/freebsd/sys/sys/kobj.h b/freebsd/sys/sys/kobj.h
index 5df5dccc..36d8d2a7 100644
--- a/freebsd/sys/sys/kobj.h
+++ b/freebsd/sys/sys/kobj.h
@@ -34,7 +34,7 @@
*/
typedef struct kobj *kobj_t;
typedef struct kobj_class *kobj_class_t;
-typedef struct kobj_method kobj_method_t;
+typedef const struct kobj_method kobj_method_t;
typedef int (*kobjop_t)(void);
typedef struct kobj_ops *kobj_ops_t;
typedef struct kobjop_desc *kobjop_desc_t;
@@ -86,7 +86,7 @@ struct kobj_ops {
struct kobjop_desc {
unsigned int id; /* unique ID */
- kobj_method_t *deflt; /* default implementation */
+ kobj_method_t deflt; /* default implementation */
};
/*
@@ -146,13 +146,13 @@ struct kobj_class classvar = { \
* DEFINE_CLASS_2(foo, foo_class, foo_methods, sizeof(foo_softc),
* bar, baz);
*/
-#define DEFINE_CLASS_2(name, methods, size, \
+#define DEFINE_CLASS_2(name, classvar, methods, size, \
base1, base2) \
\
static kobj_class_t name ## _baseclasses[] = \
{ &base1, \
&base2, NULL }; \
-struct kobj_class name ## _class = { \
+struct kobj_class classvar = { \
#name, methods, size, name ## _baseclasses \
}
@@ -162,14 +162,14 @@ struct kobj_class name ## _class = { \
* DEFINE_CLASS_3(foo, foo_class, foo_methods, sizeof(foo_softc),
* bar, baz, foobar);
*/
-#define DEFINE_CLASS_3(name, methods, size, \
+#define DEFINE_CLASS_3(name, classvar, methods, size, \
base1, base2, base3) \
\
static kobj_class_t name ## _baseclasses[] = \
{ &base1, \
&base2, \
&base3, NULL }; \
-struct kobj_class name ## _class = { \
+struct kobj_class classvar = { \
#name, methods, size, name ## _baseclasses \
}
diff --git a/freebsd/sys/sys/kthread.h b/freebsd/sys/sys/kthread.h
index 4911eccc..b6304f52 100644
--- a/freebsd/sys/sys/kthread.h
+++ b/freebsd/sys/sys/kthread.h
@@ -37,14 +37,14 @@
* Note: global_procpp may be NULL for no global save area.
*/
struct kproc_desc {
- char *arg0; /* arg 0 (for 'ps' listing) */
- void (*func)(void); /* "main" for kernel process */
+ const char *arg0; /* arg 0 (for 'ps' listing) */
+ void (*func)(void); /* "main" for kernel process */
struct proc **global_procpp; /* ptr to proc ptr save area */
};
/* A kernel thread descriptor; used to start "internal" daemons. */
struct kthread_desc {
- char *arg0; /* arg 0 (for 'ps' listing) */
+ const char *arg0; /* arg 0 (for 'ps' listing) */
void (*func)(void); /* "main" for kernel thread */
struct thread **global_threadpp; /* ptr to thread ptr save area */
};
diff --git a/freebsd/sys/sys/ktr.h b/freebsd/sys/sys/ktr.h
index de8ebe54..e25cfe03 100644
--- a/freebsd/sys/sys/ktr.h
+++ b/freebsd/sys/sys/ktr.h
@@ -36,56 +36,7 @@
#ifndef _SYS_KTR_H_
#define _SYS_KTR_H_
-/*
- * Trace classes
- *
- * Two of the trace classes (KTR_DEV and KTR_SUBSYS) are special in that
- * they are really placeholders so that indvidual drivers and subsystems
- * can map their internal tracing to the general class when they wish to
- * have tracing enabled and map it to 0 when they don't.
- */
-#define KTR_GEN 0x00000001 /* General (TR) */
-#define KTR_NET 0x00000002 /* Network */
-#define KTR_DEV 0x00000004 /* Device driver */
-#define KTR_LOCK 0x00000008 /* MP locking */
-#define KTR_SMP 0x00000010 /* MP general */
-#define KTR_SUBSYS 0x00000020 /* Subsystem. */
-#define KTR_PMAP 0x00000040 /* Pmap tracing */
-#define KTR_MALLOC 0x00000080 /* Malloc tracing */
-#define KTR_TRAP 0x00000100 /* Trap processing */
-#define KTR_INTR 0x00000200 /* Interrupt tracing */
-#define KTR_SIG 0x00000400 /* Signal processing */
-#define KTR_SPARE2 0x00000800 /* XXX Used by cxgb */
-#define KTR_PROC 0x00001000 /* Process scheduling */
-#define KTR_SYSC 0x00002000 /* System call */
-#define KTR_INIT 0x00004000 /* System initialization */
-#define KTR_SPARE3 0x00008000 /* XXX Used by cxgb */
-#define KTR_SPARE4 0x00010000 /* XXX Used by cxgb */
-#define KTR_EVH 0x00020000 /* Eventhandler */
-#define KTR_VFS 0x00040000 /* VFS events */
-#define KTR_VOP 0x00080000 /* Auto-generated vop events */
-#define KTR_VM 0x00100000 /* The virtual memory system */
-#define KTR_INET 0x00200000 /* IPv4 stack */
-#define KTR_RUNQ 0x00400000 /* Run queue */
-#define KTR_CONTENTION 0x00800000 /* Lock contention */
-#define KTR_UMA 0x01000000 /* UMA slab allocator */
-#define KTR_CALLOUT 0x02000000 /* Callouts and timeouts */
-#define KTR_GEOM 0x04000000 /* GEOM I/O events */
-#define KTR_BUSDMA 0x08000000 /* busdma(9) events */
-#define KTR_INET6 0x10000000 /* IPv6 stack */
-#define KTR_SCHED 0x20000000 /* Machine parsed sched info. */
-#define KTR_BUF 0x40000000 /* Buffer cache */
-#define KTR_ALL 0x7fffffff
-
-/* Trace classes to compile in */
-#ifdef KTR
-#ifndef KTR_COMPILE
-#define KTR_COMPILE (KTR_ALL)
-#endif
-#else /* !KTR */
-#undef KTR_COMPILE
-#define KTR_COMPILE 0
-#endif /* KTR */
+#include <sys/ktr_class.h>
/*
* Version number for ktr_entry struct. Increment this when you break binary
@@ -111,16 +62,16 @@ struct ktr_entry {
};
extern cpuset_t ktr_cpumask;
-extern int ktr_mask;
+extern uint64_t ktr_mask;
extern int ktr_entries;
extern int ktr_verbose;
extern volatile int ktr_idx;
-extern struct ktr_entry ktr_buf[];
+extern struct ktr_entry *ktr_buf;
#ifdef KTR
-void ktr_tracepoint(u_int mask, const char *file, int line,
+void ktr_tracepoint(uint64_t mask, const char *file, int line,
const char *format, u_long arg1, u_long arg2, u_long arg3,
u_long arg4, u_long arg5, u_long arg6);
@@ -244,6 +195,50 @@ void ktr_tracepoint(u_int mask, const char *file, int line,
point, a0, (v0), a1, (v1), a2, (v2), a3, (v3))
/*
+ * Start functions denote the start of a region of code or operation
+ * and should be paired with stop functions for timing of nested
+ * sequences.
+ *
+ * Specifying extra attributes with the name "key" will result in
+ * multi-part keys. For example a block device and offset pair
+ * might be used to describe a buf undergoing I/O.
+ */
+#define KTR_START0(m, egroup, ident, key) \
+ KTR_EVENT0(m, egroup, ident, "start:0x%jX", (uintmax_t)key)
+#define KTR_START1(m, egroup, ident, key, a0, v0) \
+ KTR_EVENT1(m, egroup, ident, "start:0x%jX", (uintmax_t)key, a0, (v0))
+#define KTR_START2(m, egroup, ident, key, a0, v0, a1, v1) \
+ KTR_EVENT2(m, egroup, ident, "start:0x%jX", (uintmax_t)key, \
+ a0, (v0), a1, (v1))
+#define KTR_START3(m, egroup, ident, key, a0, v0, a1, v1, a2, v2)\
+ KTR_EVENT3(m, egroup, ident, "start:0x%jX", (uintmax_t)key, \
+ a0, (v0), a1, (v1), a2, (v2))
+#define KTR_START4(m, egroup, ident, key, \
+ a0, v0, a1, v1, a2, v2, a3, v3) \
+ KTR_EVENT4(m, egroup, ident, "start:0x%jX", (uintmax_t)key, \
+ a0, (v0), a1, (v1), a2, (v2), a3, (v3))
+
+/*
+ * Stop functions denote the end of a region of code or operation
+ * and should be paired with start functions for timing of nested
+ * sequences.
+ */
+#define KTR_STOP0(m, egroup, ident, key) \
+ KTR_EVENT0(m, egroup, ident, "stop:0x%jX", (uintmax_t)key)
+#define KTR_STOP1(m, egroup, ident, key, a0, v0) \
+ KTR_EVENT1(m, egroup, ident, "stop:0x%jX", (uintmax_t)key, a0, (v0))
+#define KTR_STOP2(m, egroup, ident, key, a0, v0, a1, v1) \
+ KTR_EVENT2(m, egroup, ident, "stop:0x%jX", (uintmax_t)key, \
+ a0, (v0), a1, (v1))
+#define KTR_STOP3(m, egroup, ident, key, a0, v0, a1, v1, a2, v2)\
+ KTR_EVENT3(m, egroup, ident, "stop:0x%jX", (uintmax_t)key, \
+ a0, (v0), a1, (v1), a2, (v2))
+#define KTR_STOP4(m, egroup, ident, \
+ key, a0, v0, a1, v1, a2, v2, a3, v3) \
+ KTR_EVENT4(m, egroup, ident, "stop:0x%jX", (uintmax_t)key, \
+ a0, (v0), a1, (v1), a2, (v2), a3, (v3))
+
+/*
* Trace initialization events, similar to CTR with KTR_INIT, but
* completely ifdef'ed out if KTR_INIT isn't in KTR_COMPILE (to
* save string space, the compiler doesn't optimize out strings
diff --git a/freebsd/sys/sys/ktr_class.h b/freebsd/sys/sys/ktr_class.h
new file mode 100644
index 00000000..4bfc895b
--- /dev/null
+++ b/freebsd/sys/sys/ktr_class.h
@@ -0,0 +1,87 @@
+/*-
+ * Copyright (c) 1996 Berkeley Software Design, Inc. All rights reserved.
+ *
+ * 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.
+ * 3. Berkeley Software Design Inc's name may not be used to endorse or
+ * promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BERKELEY SOFTWARE DESIGN INC ``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 BERKELEY SOFTWARE DESIGN INC 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.
+ *
+ * from BSDI $Id: ktr.h,v 1.10.2.7 2000/03/16 21:44:42 cp Exp $
+ * $FreeBSD$
+ */
+
+#ifndef _SYS_KTR_CLASS_H_
+#define _SYS_KTR_CLASS_H_
+
+/*
+ * KTR trace classes
+ *
+ * Two of the trace classes (KTR_DEV and KTR_SUBSYS) are special in that
+ * they are really placeholders so that indvidual drivers and subsystems
+ * can map their internal tracing to the general class when they wish to
+ * have tracing enabled and map it to 0 when they don't.
+ */
+#define KTR_GEN 0x00000001 /* General (TR) */
+#define KTR_NET 0x00000002 /* Network */
+#define KTR_DEV 0x00000004 /* Device driver */
+#define KTR_LOCK 0x00000008 /* MP locking */
+#define KTR_SMP 0x00000010 /* MP general */
+#define KTR_SUBSYS 0x00000020 /* Subsystem. */
+#define KTR_PMAP 0x00000040 /* Pmap tracing */
+#define KTR_MALLOC 0x00000080 /* Malloc tracing */
+#define KTR_TRAP 0x00000100 /* Trap processing */
+#define KTR_INTR 0x00000200 /* Interrupt tracing */
+#define KTR_SIG 0x00000400 /* Signal processing */
+#define KTR_SPARE2 0x00000800 /* cxgb, amd64, xen, clk, &c */
+#define KTR_PROC 0x00001000 /* Process scheduling */
+#define KTR_SYSC 0x00002000 /* System call */
+#define KTR_INIT 0x00004000 /* System initialization */
+#define KTR_SPARE3 0x00008000 /* cxgb, drm2, ioat, ntb */
+#define KTR_SPARE4 0x00010000 /* geom_sched */
+#define KTR_EVH 0x00020000 /* Eventhandler */
+#define KTR_VFS 0x00040000 /* VFS events */
+#define KTR_VOP 0x00080000 /* Auto-generated vop events */
+#define KTR_VM 0x00100000 /* The virtual memory system */
+#define KTR_INET 0x00200000 /* IPv4 stack */
+#define KTR_RUNQ 0x00400000 /* Run queue */
+#define KTR_CONTENTION 0x00800000 /* Lock contention */
+#define KTR_UMA 0x01000000 /* UMA slab allocator */
+#define KTR_CALLOUT 0x02000000 /* Callouts and timeouts */
+#define KTR_GEOM 0x04000000 /* GEOM I/O events */
+#define KTR_BUSDMA 0x08000000 /* busdma(9) events */
+#define KTR_INET6 0x10000000 /* IPv6 stack */
+#define KTR_SCHED 0x20000000 /* Machine parsed sched info. */
+#define KTR_BUF 0x40000000 /* Buffer cache */
+#define KTR_PTRACE 0x80000000 /* Process debugging. */
+#define KTR_ALL 0xffffffff
+
+/* KTR trace classes to compile in */
+#ifdef KTR
+#ifndef KTR_COMPILE
+#define KTR_COMPILE (KTR_ALL)
+#endif
+#else /* !KTR */
+#undef KTR_COMPILE
+#define KTR_COMPILE 0
+#endif /* KTR */
+
+#endif /* !_SYS_KTR_CLASS_H_ */
diff --git a/freebsd/sys/sys/libkern.h b/freebsd/sys/sys/libkern.h
index eebbcb62..c8fcd877 100644
--- a/freebsd/sys/sys/libkern.h
+++ b/freebsd/sys/sys/libkern.h
@@ -65,8 +65,20 @@ static __inline u_int max(u_int a, u_int b) { return (a > b ? a : b); }
static __inline u_int min(u_int a, u_int b) { return (a < b ? a : b); }
static __inline quad_t qmax(quad_t a, quad_t b) { return (a > b ? a : b); }
static __inline quad_t qmin(quad_t a, quad_t b) { return (a < b ? a : b); }
+static __inline u_quad_t uqmax(u_quad_t a, u_quad_t b) { return (a > b ? a : b); }
+static __inline u_quad_t uqmin(u_quad_t a, u_quad_t b) { return (a < b ? a : b); }
static __inline u_long ulmax(u_long a, u_long b) { return (a > b ? a : b); }
static __inline u_long ulmin(u_long a, u_long b) { return (a < b ? a : b); }
+static __inline __uintmax_t ummax(__uintmax_t a, __uintmax_t b)
+{
+
+ return (a > b ? a : b);
+}
+static __inline __uintmax_t ummin(__uintmax_t a, __uintmax_t b)
+{
+
+ return (a < b ? a : b);
+}
static __inline off_t omax(off_t a, off_t b) { return (a > b ? a : b); }
static __inline off_t omin(off_t a, off_t b) { return (a < b ? a : b); }
@@ -84,8 +96,21 @@ extern int arc4rand_iniseed_state;
/* Prototypes for non-quad routines. */
struct malloc_type;
uint32_t arc4random(void);
+#ifndef __rtems__
void arc4rand(void *ptr, u_int len, int reseed);
+#else /* __rtems__ */
+void arc4random_buf(void *, size_t);
+
+static inline void
+arc4rand(void *ptr, u_int len, int reseed)
+{
+
+ (void)reseed;
+ arc4random_buf(ptr, len);
+}
+#endif /* __rtems__ */
int bcmp(const void *, const void *, size_t);
+int timingsafe_bcmp(const void *, const void *, size_t);
void *bsearch(const void *, const void *, size_t,
size_t, int (*)(const void *, const void *));
#ifndef __rtems__
@@ -95,10 +120,9 @@ int ffs(int);
#ifndef HAVE_INLINE_FFSL
int ffsl(long);
#endif
-#else /* __rtems__ */
-#define ffs(_x) __builtin_ffs((unsigned int)(_x))
-#define ffsl(_x) __builtin_ffsl((unsigned long)(_x))
-#endif /* __rtems__ */
+#ifndef HAVE_INLINE_FFSLL
+int ffsll(long long);
+#endif
#ifndef HAVE_INLINE_FLS
int fls(int);
#endif
@@ -108,10 +132,36 @@ int flsl(long);
#ifndef HAVE_INLINE_FLSLL
int flsll(long long);
#endif
+#else /* __rtems__ */
+#define ffs(_x) __builtin_ffs((unsigned int)(_x))
+#define ffsl(_x) __builtin_ffsl((unsigned long)(_x))
+
+static inline int
+fls(int x)
+{
+
+ return (x != 0 ? sizeof(x) * 8 - __builtin_clz((unsigned int)x) : 0);
+}
+
+static inline int
+flsl(long x)
+{
+
+ return (x != 0 ? sizeof(x) * 8 - __builtin_clzl((unsigned long)x) : 0);
+}
+#endif /* __rtems__ */
+#define bitcount64(x) __bitcount64((uint64_t)(x))
+#define bitcount32(x) __bitcount32((uint32_t)(x))
+#define bitcount16(x) __bitcount16((uint16_t)(x))
+#define bitcountl(x) __bitcountl((u_long)(x))
+#define bitcount(x) __bitcount((u_int)(x))
+
int fnmatch(const char *, const char *, int);
int locc(int, char *, u_int);
void *memchr(const void *s, int c, size_t n);
+void *memcchr(const void *s, int c, size_t n);
int memcmp(const void *b1, const void *b2, size_t len);
+void *memmem(const void *l, size_t l_len, const void *s, size_t s_len);
void qsort(void *base, size_t nmemb, size_t size,
int (*compar)(const void *, const void *));
void qsort_r(void *base, size_t nmemb, size_t size, void *thunk,
@@ -123,10 +173,7 @@ u_long random(void);
u_long _bsd_random(void);
#define random() _bsd_random()
#endif /* __rtems__ */
-char *index(const char *, int);
-char *rindex(const char *, int);
int scanc(u_int, const u_char *, const u_char *, int);
-int skpc(int, int, char *);
#ifndef __rtems__
void srandom(u_long);
#else /* __rtems__ */
@@ -135,14 +182,18 @@ void _bsd_srandom(u_long);
#endif /* __rtems__ */
int strcasecmp(const char *, const char *);
char *strcat(char * __restrict, const char * __restrict);
+char *strchr(const char *, int);
int strcmp(const char *, const char *);
char *strcpy(char * __restrict, const char * __restrict);
size_t strcspn(const char * __restrict, const char * __restrict) __pure;
#ifdef __rtems__
#include <string.h>
-#define strdup _bsd_strdup
+#define strdup _bsd_strdup
+#define strndup _bsd_strndup
#endif /* __rtems__ */
char *strdup(const char *__restrict, struct malloc_type *);
+char *strncat(char *, const char *, size_t);
+char *strndup(const char *__restrict, size_t, struct malloc_type *);
size_t strlcat(char *, const char *, size_t);
size_t strlcpy(char *, const char *, size_t);
size_t strlen(const char *);
@@ -150,12 +201,13 @@ int strncasecmp(const char *, const char *, size_t);
int strncmp(const char *, const char *, size_t);
char *strncpy(char * __restrict, const char * __restrict, size_t);
size_t strnlen(const char *, size_t);
+char *strrchr(const char *, int);
char *strsep(char **, const char *delim);
size_t strspn(const char *, const char *);
char *strstr(const char *, const char *);
int strvalid(const char *, size_t);
-extern uint32_t crc32_tab[];
+extern const uint32_t crc32_tab[];
static __inline uint32_t
crc32_raw(const void *buf, size_t size, uint32_t crc)
@@ -177,8 +229,8 @@ crc32(const void *buf, size_t size)
}
uint32_t
-calculate_crc32c(uint32_t crc32c, const unsigned char *buffer,
- unsigned int length);
+calculate_crc32c(uint32_t crc32c, const unsigned char *buffer,
+ unsigned int length);
LIBKERN_INLINE void *memset(void *, int, size_t);
@@ -199,15 +251,17 @@ memset(void *b, int c, size_t len)
#ifndef __rtems__
static __inline char *
-strchr(const char *p, int ch)
+index(const char *p, int ch)
{
- return (index(p, ch));
+
+ return (strchr(p, ch));
}
static __inline char *
-strrchr(const char *p, int ch)
+rindex(const char *p, int ch)
{
- return (rindex(p, ch));
+
+ return (strrchr(p, ch));
}
#endif /* __rtems__ */
diff --git a/freebsd/sys/sys/linker.h b/freebsd/sys/sys/linker.h
index 29db893f..90db1b8c 100644
--- a/freebsd/sys/sys/linker.h
+++ b/freebsd/sys/sys/linker.h
@@ -79,6 +79,8 @@ struct linker_file {
int id; /* unique id */
caddr_t address; /* load address */
size_t size; /* size of file */
+ caddr_t ctors_addr; /* address of .ctors */
+ size_t ctors_size; /* size of .ctors */
int ndeps; /* number of dependencies */
linker_file_t* deps; /* list of dependencies */
STAILQ_HEAD(, common_symbol) common; /* list of common symbols */
@@ -158,7 +160,7 @@ int linker_file_function_listall(linker_file_t,
linker_function_nameval_callback_t, void *);
/*
- * Functions soley for use by the linker class handlers.
+ * Functions solely for use by the linker class handlers.
*/
int linker_add_class(linker_class_t _cls);
int linker_file_unload(linker_file_t _file, int flags);
@@ -211,6 +213,9 @@ void *linker_hwpmc_list_objects(void);
#define MODINFOMD_KERNEND 0x0008 /* kernend */
#endif
#define MODINFOMD_SHDR 0x0009 /* section header table */
+#define MODINFOMD_CTORS_ADDR 0x000a /* address of .ctors */
+#define MODINFOMD_CTORS_SIZE 0x000b /* size of .ctors */
+#define MODINFOMD_FW_HANDLE 0x000c /* Firmware dependent handle */
#define MODINFOMD_NOCOPY 0x8000 /* don't copy this metadata to the kernel */
#define MODINFOMD_DEPLIST (0x4001 | MODINFOMD_NOCOPY) /* depends on */
@@ -224,6 +229,7 @@ void *linker_hwpmc_list_objects(void);
#endif
#define LINKER_HINTS_VERSION 1 /* linker.hints file version */
+#define LINKER_HINTS_MAX (1 << 20) /* Allow at most 1MB for linker.hints */
#ifdef _KERNEL
@@ -260,7 +266,7 @@ extern int kld_debug;
#endif
#ifndef __rtems__
-typedef Elf_Addr elf_lookup_fn(linker_file_t, Elf_Size, int);
+typedef int elf_lookup_fn(linker_file_t, Elf_Size, int, Elf_Addr *);
/* Support functions */
int elf_reloc(linker_file_t _lf, Elf_Addr base, const void *_rel, int _type, elf_lookup_fn _lu);
diff --git a/freebsd/sys/sys/linker_set.h b/freebsd/sys/sys/linker_set.h
index c403d764..918d7242 100644
--- a/freebsd/sys/sys/linker_set.h
+++ b/freebsd/sys/sys/linker_set.h
@@ -43,16 +43,27 @@
* For ELF, this is done by constructing a separate segment for each set.
*/
+#if defined(__powerpc64__)
+/*
+ * Move the symbol pointer from ".text" to ".data" segment, to make
+ * the GCC compiler happy:
+ */
+#define __MAKE_SET_CONST
+#else
+#define __MAKE_SET_CONST const
+#endif
+
/*
* Private macros, not to be used outside this header file.
*/
#ifdef __GNUCLIKE___SECTION
#ifndef __rtems__
-#define __MAKE_SET(set, sym) \
- __GLOBL(__CONCAT(__start_set_,set)); \
- __GLOBL(__CONCAT(__stop_set_,set)); \
- static void const * const __set_##set##_sym_##sym \
- __section("set_" #set) __used = &sym
+#define __MAKE_SET(set, sym) \
+ __GLOBL(__CONCAT(__start_set_,set)); \
+ __GLOBL(__CONCAT(__stop_set_,set)); \
+ static void const * __MAKE_SET_CONST \
+ __set_##set##_sym_##sym __section("set_" #set) \
+ __used = &(sym)
#else /* __rtems__ */
#define RTEMS_BSD_DEFINE_SET(set, type) \
type const __CONCAT(_bsd__start_set_,set)[0] \
@@ -111,9 +122,9 @@
* Initialize before referring to a given linker set.
*/
#ifndef __rtems__
-#define SET_DECLARE(set, ptype) \
- extern ptype *__CONCAT(__start_set_,set); \
- extern ptype *__CONCAT(__stop_set_,set)
+#define SET_DECLARE(set, ptype) \
+ extern ptype __weak_symbol *__CONCAT(__start_set_,set); \
+ extern ptype __weak_symbol *__CONCAT(__stop_set_,set)
#define SET_BEGIN(set) \
(&__CONCAT(__start_set_,set))
diff --git a/freebsd/sys/sys/lockmgr.h b/freebsd/sys/sys/lockmgr.h
index 10227cdd..3019e4c4 100644
--- a/freebsd/sys/sys/lockmgr.h
+++ b/freebsd/sys/sys/lockmgr.h
@@ -69,7 +69,7 @@ struct thread;
int __lockmgr_args(struct lock *lk, u_int flags, struct lock_object *ilk,
const char *wmesg, int prio, int timo, const char *file, int line);
#if defined(INVARIANTS) || defined(INVARIANT_SUPPORT)
-void _lockmgr_assert(struct lock *lk, int what, const char *file, int line);
+void _lockmgr_assert(const struct lock *lk, int what, const char *file, int line);
#endif
void _lockmgr_disown(struct lock *lk, const char *file, int line);
@@ -77,13 +77,14 @@ void lockallowrecurse(struct lock *lk);
void lockallowshare(struct lock *lk);
void lockdestroy(struct lock *lk);
void lockdisablerecurse(struct lock *lk);
+void lockdisableshare(struct lock *lk);
void lockinit(struct lock *lk, int prio, const char *wmesg, int timo,
int flags);
#ifdef DDB
int lockmgr_chain(struct thread *td, struct thread **ownerp);
#endif
-void lockmgr_printinfo(struct lock *lk);
-int lockstatus(struct lock *lk);
+void lockmgr_printinfo(const struct lock *lk);
+int lockstatus(const struct lock *lk);
/*
* As far as the ilk can be a static NULL pointer these functions need a
@@ -126,8 +127,6 @@ _lockmgr_args_rw(struct lock *lk, u_int flags, struct rwlock *ilk,
#define lockmgr_rw(lk, flags, ilk) \
_lockmgr_args_rw((lk), (flags), (ilk), LK_WMESG_DEFAULT, \
LK_PRIO_DEFAULT, LK_TIMO_DEFAULT, LOCK_FILE, LOCK_LINE)
-#define lockmgr_waiters(lk) \
- ((lk)->lk_lock & LK_ALL_WAITERS)
#ifdef INVARIANTS
#define lockmgr_assert(lk, what) \
_lockmgr_assert((lk), (what), LOCK_FILE, LOCK_LINE)
@@ -146,6 +145,7 @@ _lockmgr_args_rw(struct lock *lk, u_int flags, struct rwlock *ilk,
#define LK_NOWITNESS 0x000010
#define LK_QUIET 0x000020
#define LK_ADAPTIVE 0x000040
+#define LK_IS_VNODE 0x000080 /* Tell WITNESS about a VNODE lock */
/*
* Additional attributes to be used in lockmgr().
@@ -156,6 +156,8 @@ _lockmgr_args_rw(struct lock *lk, u_int flags, struct rwlock *ilk,
#define LK_RETRY 0x000400
#define LK_SLEEPFAIL 0x000800
#define LK_TIMELOCK 0x001000
+#define LK_NODDLKTREAT 0x002000
+#define LK_VNHELD 0x004000
/*
* Operations for lockmgr().
diff --git a/freebsd/sys/sys/lockstat.h b/freebsd/sys/sys/lockstat.h
index ed9cffa9..1fc79ffe 100644
--- a/freebsd/sys/sys/lockstat.h
+++ b/freebsd/sys/sys/lockstat.h
@@ -27,180 +27,91 @@
/*
* DTrace lockstat provider definitions
- *
*/
-#ifndef _SYS_LOCKSTAT_H
+#ifndef _SYS_LOCKSTAT_H
#define _SYS_LOCKSTAT_H
-#ifdef _KERNEL
+#ifdef _KERNEL
-/*
- * Spin Locks
- */
-#define LS_MTX_SPIN_LOCK_ACQUIRE 0
-#define LS_MTX_SPIN_UNLOCK_RELEASE 1
-#define LS_MTX_SPIN_LOCK_SPIN 2
+#include <rtems/bsd/sys/param.h>
+#include <sys/queue.h>
+#include <sys/sdt.h>
-/*
- * Adaptive Locks
- */
-#define LS_MTX_LOCK_ACQUIRE 3
-#define LS_MTX_UNLOCK_RELEASE 4
-#define LS_MTX_LOCK_SPIN 5
-#define LS_MTX_LOCK_BLOCK 6
-#define LS_MTX_TRYLOCK_ACQUIRE 7
+SDT_PROVIDER_DECLARE(lockstat);
-/*
- * Reader/Writer Locks
- */
-#define LS_RW_RLOCK_ACQUIRE 8
-#define LS_RW_RUNLOCK_RELEASE 9
-#define LS_RW_WLOCK_ACQUIRE 10
-#define LS_RW_WUNLOCK_RELEASE 11
-#define LS_RW_RLOCK_SPIN 12
-#define LS_RW_RLOCK_BLOCK 13
-#define LS_RW_WLOCK_SPIN 14
-#define LS_RW_WLOCK_BLOCK 15
-#define LS_RW_TRYUPGRADE_UPGRADE 16
-#define LS_RW_DOWNGRADE_DOWNGRADE 17
+SDT_PROBE_DECLARE(lockstat, , , adaptive__acquire);
+SDT_PROBE_DECLARE(lockstat, , , adaptive__release);
+SDT_PROBE_DECLARE(lockstat, , , adaptive__spin);
+SDT_PROBE_DECLARE(lockstat, , , adaptive__block);
-/*
- * Shared/Exclusive Locks
- */
-#define LS_SX_SLOCK_ACQUIRE 18
-#define LS_SX_SUNLOCK_RELEASE 19
-#define LS_SX_XLOCK_ACQUIRE 20
-#define LS_SX_XUNLOCK_RELEASE 21
-#define LS_SX_SLOCK_SPIN 22
-#define LS_SX_SLOCK_BLOCK 23
-#define LS_SX_XLOCK_SPIN 24
-#define LS_SX_XLOCK_BLOCK 25
-#define LS_SX_TRYUPGRADE_UPGRADE 26
-#define LS_SX_DOWNGRADE_DOWNGRADE 27
-
-/*
- * Thread Locks
- */
-#define LS_THREAD_LOCK_SPIN 28
+SDT_PROBE_DECLARE(lockstat, , , spin__acquire);
+SDT_PROBE_DECLARE(lockstat, , , spin__release);
+SDT_PROBE_DECLARE(lockstat, , , spin__spin);
-/*
- * Lockmanager Locks
- * According to locking(9) Lockmgr locks are "Largely deprecated"
- * so no support for these have been added in the lockstat provider.
- */
+SDT_PROBE_DECLARE(lockstat, , , rw__acquire);
+SDT_PROBE_DECLARE(lockstat, , , rw__release);
+SDT_PROBE_DECLARE(lockstat, , , rw__block);
+SDT_PROBE_DECLARE(lockstat, , , rw__spin);
+SDT_PROBE_DECLARE(lockstat, , , rw__upgrade);
+SDT_PROBE_DECLARE(lockstat, , , rw__downgrade);
-#define LS_NPROBES 29
-
-#define LS_MTX_LOCK "mtx_lock"
-#define LS_MTX_UNLOCK "mtx_unlock"
-#define LS_MTX_SPIN_LOCK "mtx_lock_spin"
-#define LS_MTX_SPIN_UNLOCK "mtx_unlock_spin"
-#define LS_MTX_TRYLOCK "mtx_trylock"
-#define LS_RW_RLOCK "rw_rlock"
-#define LS_RW_WLOCK "rw_wlock"
-#define LS_RW_RUNLOCK "rw_runlock"
-#define LS_RW_WUNLOCK "rw_wunlock"
-#define LS_RW_TRYUPGRADE "rw_try_upgrade"
-#define LS_RW_DOWNGRADE "rw_downgrade"
-#define LS_SX_SLOCK "sx_slock"
-#define LS_SX_XLOCK "sx_xlock"
-#define LS_SX_SUNLOCK "sx_sunlock"
-#define LS_SX_XUNLOCK "sx_xunlock"
-#define LS_SX_TRYUPGRADE "sx_try_upgrade"
-#define LS_SX_DOWNGRADE "sx_downgrade"
-#define LS_THREAD_LOCK "thread_lock"
-
-#define LS_ACQUIRE "acquire"
-#define LS_RELEASE "release"
-#define LS_SPIN "spin"
-#define LS_BLOCK "block"
-#define LS_UPGRADE "upgrade"
-#define LS_DOWNGRADE "downgrade"
-
-#define LS_TYPE_ADAPTIVE "adaptive"
-#define LS_TYPE_SPIN "spin"
-#define LS_TYPE_THREAD "thread"
-#define LS_TYPE_RW "rw"
-#define LS_TYPE_SX "sx"
-
-#define LSA_ACQUIRE (LS_TYPE_ADAPTIVE "-" LS_ACQUIRE)
-#define LSA_RELEASE (LS_TYPE_ADAPTIVE "-" LS_RELEASE)
-#define LSA_SPIN (LS_TYPE_ADAPTIVE "-" LS_SPIN)
-#define LSA_BLOCK (LS_TYPE_ADAPTIVE "-" LS_BLOCK)
-#define LSS_ACQUIRE (LS_TYPE_SPIN "-" LS_ACQUIRE)
-#define LSS_RELEASE (LS_TYPE_SPIN "-" LS_RELEASE)
-#define LSS_SPIN (LS_TYPE_SPIN "-" LS_SPIN)
-#define LSR_ACQUIRE (LS_TYPE_RW "-" LS_ACQUIRE)
-#define LSR_RELEASE (LS_TYPE_RW "-" LS_RELEASE)
-#define LSR_BLOCK (LS_TYPE_RW "-" LS_BLOCK)
-#define LSR_SPIN (LS_TYPE_RW "-" LS_SPIN)
-#define LSR_UPGRADE (LS_TYPE_RW "-" LS_UPGRADE)
-#define LSR_DOWNGRADE (LS_TYPE_RW "-" LS_DOWNGRADE)
-#define LSX_ACQUIRE (LS_TYPE_SX "-" LS_ACQUIRE)
-#define LSX_RELEASE (LS_TYPE_SX "-" LS_RELEASE)
-#define LSX_BLOCK (LS_TYPE_SX "-" LS_BLOCK)
-#define LSX_SPIN (LS_TYPE_SX "-" LS_SPIN)
-#define LSX_UPGRADE (LS_TYPE_SX "-" LS_UPGRADE)
-#define LSX_DOWNGRADE (LS_TYPE_SX "-" LS_DOWNGRADE)
-#define LST_SPIN (LS_TYPE_THREAD "-" LS_SPIN)
+SDT_PROBE_DECLARE(lockstat, , , sx__acquire);
+SDT_PROBE_DECLARE(lockstat, , , sx__release);
+SDT_PROBE_DECLARE(lockstat, , , sx__block);
+SDT_PROBE_DECLARE(lockstat, , , sx__spin);
+SDT_PROBE_DECLARE(lockstat, , , sx__upgrade);
+SDT_PROBE_DECLARE(lockstat, , , sx__downgrade);
-/*
- * The following must match the type definition of dtrace_probe. It is
- * defined this way to avoid having to rely on CDDL code.
- */
-extern uint32_t lockstat_probemap[LS_NPROBES];
-typedef void (*lockstat_probe_func_t)(uint32_t, uintptr_t arg0, uintptr_t arg1,
- uintptr_t arg2, uintptr_t arg3, uintptr_t arg4);
-extern lockstat_probe_func_t lockstat_probe_func;
-extern uint64_t lockstat_nsecs(void);
+SDT_PROBE_DECLARE(lockstat, , , thread__spin);
-#ifdef KDTRACE_HOOKS
-/*
- * Macros to record lockstat probes.
- */
-#define LOCKSTAT_RECORD4(probe, lp, arg1, arg2, arg3, arg4) do { \
- uint32_t id; \
- \
- if ((id = lockstat_probemap[(probe)])) \
- (*lockstat_probe_func)(id, (uintptr_t)(lp), (arg1), (arg2), \
- (arg3), (arg4)); \
-} while (0)
+#define LOCKSTAT_WRITER 0
+#define LOCKSTAT_READER 1
-#define LOCKSTAT_RECORD(probe, lp, arg1) \
- LOCKSTAT_RECORD4(probe, lp, arg1, 0, 0, 0)
+extern int lockstat_enabled;
-#define LOCKSTAT_RECORD0(probe, lp) \
- LOCKSTAT_RECORD4(probe, lp, 0, 0, 0, 0)
+#ifdef KDTRACE_HOOKS
-#define LOCKSTAT_RECORD1(probe, lp, arg1) \
- LOCKSTAT_RECORD4(probe, lp, arg1, 0, 0, 0)
+#define LOCKSTAT_RECORD0(probe, lp) \
+ SDT_PROBE1(lockstat, , , probe, lp)
-#define LOCKSTAT_RECORD2(probe, lp, arg1, arg2) \
- LOCKSTAT_RECORD4(probe, lp, arg1, arg2, 0, 0)
+#define LOCKSTAT_RECORD1(probe, lp, arg1) \
+ SDT_PROBE2(lockstat, , , probe, lp, arg1)
-#define LOCKSTAT_RECORD3(probe, lp, arg1, arg2, arg3) \
- LOCKSTAT_RECORD4(probe, lp, arg1, arg2, arg3, 0)
+#define LOCKSTAT_RECORD2(probe, lp, arg1, arg2) \
+ SDT_PROBE3(lockstat, , , probe, lp, arg1, arg2)
-#define LOCKSTAT_PROFILE_OBTAIN_LOCK_SUCCESS(probe, lp, c, wt, f, l) do { \
- uint32_t id; \
- \
- lock_profile_obtain_lock_success(&(lp)->lock_object, c, wt, f, l); \
- if ((id = lockstat_probemap[(probe)])) \
- (*lockstat_probe_func)(id, (uintptr_t)(lp), 0, 0, 0, 0); \
+#define LOCKSTAT_RECORD3(probe, lp, arg1, arg2, arg3) \
+ SDT_PROBE4(lockstat, , , probe, lp, arg1, arg2, arg3)
+
+#define LOCKSTAT_RECORD4(probe, lp, arg1, arg2, arg3, arg4) \
+ SDT_PROBE5(lockstat, , , probe, lp, arg1, arg2, arg3, arg4)
+
+#define LOCKSTAT_PROFILE_OBTAIN_LOCK_SUCCESS(probe, lp, c, wt, f, l) do { \
+ lock_profile_obtain_lock_success(&(lp)->lock_object, c, wt, f, l); \
+ LOCKSTAT_RECORD0(probe, lp); \
} while (0)
-#define LOCKSTAT_PROFILE_RELEASE_LOCK(probe, lp) do { \
- uint32_t id; \
- \
- lock_profile_release_lock(&(lp)->lock_object); \
- if ((id = lockstat_probemap[(probe)])) \
- (*lockstat_probe_func)(id, (uintptr_t)(lp), 0, 0, 0, 0); \
+#define LOCKSTAT_PROFILE_OBTAIN_RWLOCK_SUCCESS(probe, lp, c, wt, f, l, a) do { \
+ lock_profile_obtain_lock_success(&(lp)->lock_object, c, wt, f, l); \
+ LOCKSTAT_RECORD1(probe, lp, a); \
} while (0)
-#else /* !KDTRACE_HOOKS */
+#define LOCKSTAT_PROFILE_RELEASE_LOCK(probe, lp) do { \
+ lock_profile_release_lock(&(lp)->lock_object); \
+ LOCKSTAT_RECORD0(probe, lp); \
+} while (0)
+
+#define LOCKSTAT_PROFILE_RELEASE_RWLOCK(probe, lp, a) do { \
+ lock_profile_release_lock(&(lp)->lock_object); \
+ LOCKSTAT_RECORD1(probe, lp, a); \
+} while (0)
+
+struct lock_object;
+uint64_t lockstat_nsecs(struct lock_object *);
+
+#else /* !KDTRACE_HOOKS */
-#define LOCKSTAT_RECORD(probe, lp, arg1)
#define LOCKSTAT_RECORD0(probe, lp)
#define LOCKSTAT_RECORD1(probe, lp, arg1)
#define LOCKSTAT_RECORD2(probe, lp, arg1, arg2)
@@ -210,11 +121,15 @@ extern uint64_t lockstat_nsecs(void);
#define LOCKSTAT_PROFILE_OBTAIN_LOCK_SUCCESS(probe, lp, c, wt, f, l) \
lock_profile_obtain_lock_success(&(lp)->lock_object, c, wt, f, l)
+#define LOCKSTAT_PROFILE_OBTAIN_RWLOCK_SUCCESS(probe, lp, c, wt, f, l, a) \
+ LOCKSTAT_PROFILE_OBTAIN_LOCK_SUCCESS(probe, lp, c, wt, f, l)
+
#define LOCKSTAT_PROFILE_RELEASE_LOCK(probe, lp) \
lock_profile_release_lock(&(lp)->lock_object)
-#endif /* !KDTRACE_HOOKS */
-
-#endif /* _KERNEL */
+#define LOCKSTAT_PROFILE_RELEASE_RWLOCK(probe, lp, a) \
+ LOCKSTAT_PROFILE_RELEASE_LOCK(probe, lp)
-#endif /* _SYS_LOCKSTAT_H */
+#endif /* !KDTRACE_HOOKS */
+#endif /* _KERNEL */
+#endif /* _SYS_LOCKSTAT_H */
diff --git a/freebsd/sys/sys/loginclass.h b/freebsd/sys/sys/loginclass.h
index 08f3409a..6783123a 100644
--- a/freebsd/sys/sys/loginclass.h
+++ b/freebsd/sys/sys/loginclass.h
@@ -48,6 +48,7 @@ void loginclass_hold(struct loginclass *lc);
void loginclass_free(struct loginclass *lc);
struct loginclass *loginclass_find(const char *name);
void loginclass_racct_foreach(void (*callback)(struct racct *racct,
- void *arg2, void *arg3), void *arg2, void *arg3);
+ void *arg2, void *arg3), void (*pre)(void), void (*post)(void),
+ void *arg2, void *arg3);
#endif /* !_SYS_LOGINCLASS_H_ */
diff --git a/freebsd/sys/sys/malloc.h b/freebsd/sys/sys/malloc.h
index f99dfc5e..310d2551 100644
--- a/freebsd/sys/sys/malloc.h
+++ b/freebsd/sys/sys/malloc.h
@@ -51,6 +51,8 @@
#define M_NOVM 0x0200 /* don't ask VM for pages */
#define M_USE_RESERVE 0x0400 /* can alloc out of reserve memory */
#define M_NODUMP 0x0800 /* don't dump pages in this allocation */
+#define M_FIRSTFIT 0x1000 /* Only for vmem, fast fit. */
+#define M_BESTFIT 0x2000 /* Only for vmem, low fragmentation. */
#define M_MAGIC 877983977 /* time when first defined :-) */
@@ -139,7 +141,7 @@ struct malloc_type_header {
struct malloc_type type[1] = { \
{ NULL, M_MAGIC, shortdesc, NULL } \
}; \
- SYSINIT(type##_init, SI_SUB_KMEM, SI_ORDER_SECOND, malloc_init, \
+ SYSINIT(type##_init, SI_SUB_KMEM, SI_ORDER_THIRD, malloc_init, \
type); \
SYSUNINIT(type##_uninit, SI_SUB_KMEM, SI_ORDER_ANY, \
malloc_uninit, type)
@@ -151,9 +153,6 @@ MALLOC_DECLARE(M_CACHE);
MALLOC_DECLARE(M_DEVBUF);
MALLOC_DECLARE(M_TEMP);
-MALLOC_DECLARE(M_IP6OPT); /* for INET6 */
-MALLOC_DECLARE(M_IP6NDP); /* for INET6 */
-
/*
* Deprecated macro versions of not-quite-malloc() and free().
*/
@@ -178,9 +177,11 @@ typedef void malloc_type_list_func_t(struct malloc_type *, void *);
void contigfree(void *addr, unsigned long size, struct malloc_type *type);
void *contigmalloc(unsigned long size, struct malloc_type *type, int flags,
vm_paddr_t low, vm_paddr_t high, unsigned long alignment,
- unsigned long boundary) __malloc_like;
+ vm_paddr_t boundary) __malloc_like __result_use_check
+ __alloc_size(1) __alloc_align(6);
void free(void *addr, struct malloc_type *type);
-void *malloc(unsigned long size, struct malloc_type *type, int flags) __malloc_like;
+void *malloc(unsigned long size, struct malloc_type *type, int flags)
+ __malloc_like __result_use_check __alloc_size(1);
void malloc_init(void *);
int malloc_last_fail(void);
void malloc_type_allocated(struct malloc_type *type, unsigned long size);
@@ -188,9 +189,9 @@ void malloc_type_freed(struct malloc_type *type, unsigned long size);
void malloc_type_list(malloc_type_list_func_t *, void *);
void malloc_uninit(void *);
void *realloc(void *addr, unsigned long size, struct malloc_type *type,
- int flags);
+ int flags) __result_use_check __alloc_size(2);
void *reallocf(void *addr, unsigned long size, struct malloc_type *type,
- int flags);
+ int flags) __alloc_size(2);
struct malloc_type *malloc_desc2type(const char *desc);
#endif /* _KERNEL */
diff --git a/freebsd/sys/sys/mbuf.h b/freebsd/sys/sys/mbuf.h
index b6d58a25..95194e0b 100644
--- a/freebsd/sys/sys/mbuf.h
+++ b/freebsd/sys/sys/mbuf.h
@@ -44,6 +44,32 @@
#endif
#endif
+#ifdef _KERNEL
+#include <sys/sdt.h>
+
+#define MBUF_PROBE1(probe, arg0) \
+ SDT_PROBE1(sdt, , , probe, arg0)
+#define MBUF_PROBE2(probe, arg0, arg1) \
+ SDT_PROBE2(sdt, , , probe, arg0, arg1)
+#define MBUF_PROBE3(probe, arg0, arg1, arg2) \
+ SDT_PROBE3(sdt, , , probe, arg0, arg1, arg2)
+#define MBUF_PROBE4(probe, arg0, arg1, arg2, arg3) \
+ SDT_PROBE4(sdt, , , probe, arg0, arg1, arg2, arg3)
+#define MBUF_PROBE5(probe, arg0, arg1, arg2, arg3, arg4) \
+ SDT_PROBE5(sdt, , , probe, arg0, arg1, arg2, arg3, arg4)
+
+SDT_PROBE_DECLARE(sdt, , , m__init);
+SDT_PROBE_DECLARE(sdt, , , m__gethdr);
+SDT_PROBE_DECLARE(sdt, , , m__get);
+SDT_PROBE_DECLARE(sdt, , , m__getcl);
+SDT_PROBE_DECLARE(sdt, , , m__clget);
+SDT_PROBE_DECLARE(sdt, , , m__cljget);
+SDT_PROBE_DECLARE(sdt, , , m__cljset);
+SDT_PROBE_DECLARE(sdt, , , m__free);
+SDT_PROBE_DECLARE(sdt, , , m__freem);
+
+#endif /* _KERNEL */
+
/*
* Mbufs are of a single size, MSIZE (sys/param.h), which includes overhead.
* An mbuf may add a single "mbuf cluster" of size MCLBYTES (also in
@@ -52,11 +78,24 @@
* stored. Additionally, it is possible to allocate a separate buffer
* externally and attach it to the mbuf in a way similar to that of mbuf
* clusters.
+ *
+ * NB: These calculation do not take actual compiler-induced alignment and
+ * padding inside the complete struct mbuf into account. Appropriate
+ * attention is required when changing members of struct mbuf.
+ *
+ * MLEN is data length in a normal mbuf.
+ * MHLEN is data length in an mbuf with pktheader.
+ * MINCLSIZE is a smallest amount of data that should be put into cluster.
+ *
+ * Compile-time assertions in uipc_mbuf.c test these values to ensure that
+ * they are sensible.
*/
-#define MLEN (MSIZE - sizeof(struct m_hdr)) /* normal data len */
-#define MHLEN (MLEN - sizeof(struct pkthdr)) /* data len w/pkthdr */
-#define MINCLSIZE (MHLEN + 1) /* smallest amount to put in cluster */
-#define M_MAXCOMPRESS (MHLEN / 2) /* max amount to copy for compression */
+struct mbuf;
+#define MHSIZE offsetof(struct mbuf, m_dat)
+#define MPKTHSIZE offsetof(struct mbuf, m_pktdat)
+#define MLEN ((int)(MSIZE - MHSIZE))
+#define MHLEN ((int)(MSIZE - MPKTHSIZE))
+#define MINCLSIZE (MHLEN + 1)
#ifdef _KERNEL
/*-
@@ -64,8 +103,10 @@
* type:
*
* mtod(m, t) -- Convert mbuf pointer to data pointer of correct type.
+ * mtodo(m, o) -- Same as above but with offset 'o' into data.
*/
#define mtod(m, t) ((t)((m)->m_data))
+#define mtodo(m, o) ((void *)(((m)->m_data) + (o)))
/*
* Argument structure passed to UMA routines during mbuf and packet
@@ -77,25 +118,6 @@ struct mb_args {
};
#endif /* _KERNEL */
-#if defined(__LP64__)
-#define M_HDR_PAD 6
-#else
-#define M_HDR_PAD 2
-#endif
-
-/*
- * Header present at the beginning of every mbuf.
- */
-struct m_hdr {
- struct mbuf *mh_next; /* next buffer in chain */
- struct mbuf *mh_nextpkt; /* next chain in queue/record */
- caddr_t mh_data; /* location of data */
- int mh_len; /* amount of data in this mbuf */
- int mh_flags; /* flags; see below */
- short mh_type; /* type of data in this mbuf */
- uint8_t pad[M_HDR_PAD];/* word align */
-};
-
/*
* Packet tag structure (see below for details).
*/
@@ -109,40 +131,73 @@ struct m_tag {
/*
* Record/packet header in first mbuf of chain; valid only if M_PKTHDR is set.
+ * Size ILP32: 48
+ * LP64: 56
+ * Compile-time assertions in uipc_mbuf.c test these values to ensure that
+ * they are correct.
*/
struct pkthdr {
struct ifnet *rcvif; /* rcv interface */
- /* variables for ip and tcp reassembly */
- void *header; /* pointer to packet header */
- int len; /* total packet length */
- uint32_t flowid; /* packet's 4-tuple system
- * flow identifier
- */
- /* variables for hardware checksum */
- int csum_flags; /* flags regarding checksum */
- int csum_data; /* data field used by csum routines */
- u_int16_t tso_segsz; /* TSO segment size */
- union {
- u_int16_t vt_vtag; /* Ethernet 802.1p+q vlan tag */
- u_int16_t vt_nrecs; /* # of IGMPv3 records in this chain */
- } PH_vt;
SLIST_HEAD(packet_tags, m_tag) tags; /* list of packet tags */
+ int32_t len; /* total packet length */
+
+ /* Layer crossing persistent information. */
+ uint32_t flowid; /* packet's 4-tuple system */
+ uint64_t csum_flags; /* checksum and offload features */
+ uint16_t fibnum; /* this packet should use this fib */
+ uint8_t cosqos; /* class/quality of service */
+ uint8_t rsstype; /* hash type */
+ uint8_t l2hlen; /* layer 2 header length */
+ uint8_t l3hlen; /* layer 3 header length */
+ uint8_t l4hlen; /* layer 4 header length */
+ uint8_t l5hlen; /* layer 5 header length */
+ union {
+ uint8_t eight[8];
+ uint16_t sixteen[4];
+ uint32_t thirtytwo[2];
+ uint64_t sixtyfour[1];
+ uintptr_t unintptr[1];
+ void *ptr;
+ } PH_per;
+
+ /* Layer specific non-persistent local storage for reassembly, etc. */
+ union {
+ uint8_t eight[8];
+ uint16_t sixteen[4];
+ uint32_t thirtytwo[2];
+ uint64_t sixtyfour[1];
+ uintptr_t unintptr[1];
+ void *ptr;
+ } PH_loc;
};
-#define ether_vtag PH_vt.vt_vtag
+#define ether_vtag PH_per.sixteen[0]
+#define PH_vt PH_per
+#define vt_nrecs sixteen[0]
+#define tso_segsz PH_per.sixteen[1]
+#define csum_phsum PH_per.sixteen[2]
+#define csum_data PH_per.thirtytwo[1]
/*
* Description of external storage mapped into mbuf; valid only if M_EXT is
* set.
+ * Size ILP32: 28
+ * LP64: 48
+ * Compile-time assertions in uipc_mbuf.c test these values to ensure that
+ * they are correct.
*/
struct m_ext {
+ union {
+ volatile u_int ext_count; /* value of ref count info */
+ volatile u_int *ext_cnt; /* pointer to ref count info */
+ };
caddr_t ext_buf; /* start of buffer */
+ uint32_t ext_size; /* size of buffer, for ext_free */
+ uint32_t ext_type:8, /* type of external storage */
+ ext_flags:24; /* external storage mbuf flags */
void (*ext_free) /* free routine if not the usual */
- (void *, void *);
+ (struct mbuf *, void *, void *);
void *ext_arg1; /* optional argument pointer */
void *ext_arg2; /* optional argument pointer */
- u_int ext_size; /* size of buffer, for ext_free */
- volatile u_int *ref_cnt; /* pointer to ref count info */
- int ext_type; /* type of external storage */
};
/*
@@ -150,71 +205,107 @@ struct m_ext {
* purposes.
*/
struct mbuf {
- struct m_hdr m_hdr;
+ /*
+ * Header present at the beginning of every mbuf.
+ * Size ILP32: 24
+ * LP64: 32
+ * Compile-time assertions in uipc_mbuf.c test these values to ensure
+ * that they are correct.
+ */
+ union { /* next buffer in chain */
+ struct mbuf *m_next;
+ SLIST_ENTRY(mbuf) m_slist;
+ STAILQ_ENTRY(mbuf) m_stailq;
+ };
+ union { /* next chain in queue/record */
+ struct mbuf *m_nextpkt;
+ SLIST_ENTRY(mbuf) m_slistpkt;
+ STAILQ_ENTRY(mbuf) m_stailqpkt;
+ };
+ caddr_t m_data; /* location of data */
+ int32_t m_len; /* amount of data in this mbuf */
+ uint32_t m_type:8, /* type of data in this mbuf */
+ m_flags:24; /* flags; see below */
+#if !defined(__LP64__)
+ uint32_t m_pad; /* pad for 64bit alignment */
+#endif
+
+ /*
+ * A set of optional headers (packet header, external storage header)
+ * and internal data storage. Historically, these arrays were sized
+ * to MHLEN (space left after a packet header) and MLEN (space left
+ * after only a regular mbuf header); they are now variable size in
+ * order to support future work on variable-size mbufs.
+ */
union {
struct {
- struct pkthdr MH_pkthdr; /* M_PKTHDR set */
+ struct pkthdr m_pkthdr; /* M_PKTHDR set */
union {
- struct m_ext MH_ext; /* M_EXT set */
- char MH_databuf[MHLEN];
- } MH_dat;
- } MH;
- char M_databuf[MLEN]; /* !M_PKTHDR, !M_EXT */
- } M_dat;
+ struct m_ext m_ext; /* M_EXT set */
+ char m_pktdat[0];
+ };
+ };
+ char m_dat[0]; /* !M_PKTHDR, !M_EXT */
+ };
};
-#define m_next m_hdr.mh_next
-#define m_len m_hdr.mh_len
-#define m_data m_hdr.mh_data
-#define m_type m_hdr.mh_type
-#define m_flags m_hdr.mh_flags
-#define m_nextpkt m_hdr.mh_nextpkt
-#define m_act m_nextpkt
-#define m_pkthdr M_dat.MH.MH_pkthdr
-#define m_ext M_dat.MH.MH_dat.MH_ext
-#define m_pktdat M_dat.MH.MH_dat.MH_databuf
-#define m_dat M_dat.M_databuf
/*
- * mbuf flags.
+ * mbuf flags of global significance and layer crossing.
+ * Those of only protocol/layer specific significance are to be mapped
+ * to M_PROTO[1-12] and cleared at layer handoff boundaries.
+ * NB: Limited to the lower 24 bits.
*/
#define M_EXT 0x00000001 /* has associated external storage */
#define M_PKTHDR 0x00000002 /* start of record */
#define M_EOR 0x00000004 /* end of record */
#define M_RDONLY 0x00000008 /* associated data is marked read-only */
-#define M_PROTO1 0x00000010 /* protocol-specific */
-#define M_PROTO2 0x00000020 /* protocol-specific */
-#define M_PROTO3 0x00000040 /* protocol-specific */
-#define M_PROTO4 0x00000080 /* protocol-specific */
-#define M_PROTO5 0x00000100 /* protocol-specific */
-#define M_BCAST 0x00000200 /* send/received as link-level broadcast */
-#define M_MCAST 0x00000400 /* send/received as link-level multicast */
-#define M_FRAG 0x00000800 /* packet is a fragment of a larger packet */
-#define M_FIRSTFRAG 0x00001000 /* packet is first fragment */
-#define M_LASTFRAG 0x00002000 /* packet is last fragment */
-#define M_SKIP_FIREWALL 0x00004000 /* skip firewall processing */
-#define M_FREELIST 0x00008000 /* mbuf is on the free list */
-#define M_VLANTAG 0x00010000 /* ether_vtag is valid */
-#define M_PROMISC 0x00020000 /* packet was not for us */
-#define M_NOFREE 0x00040000 /* do not free mbuf, embedded in cluster */
-#define M_PROTO6 0x00080000 /* protocol-specific */
-#define M_PROTO7 0x00100000 /* protocol-specific */
-#define M_PROTO8 0x00200000 /* protocol-specific */
-#define M_FLOWID 0x00400000 /* deprecated: flowid is valid */
-#define M_HASHTYPEBITS 0x0F000000 /* mask of bits holding flowid hash type */
+#define M_BCAST 0x00000010 /* send/received as link-level broadcast */
+#define M_MCAST 0x00000020 /* send/received as link-level multicast */
+#define M_PROMISC 0x00000040 /* packet was not for us */
+#define M_VLANTAG 0x00000080 /* ether_vtag is valid */
+#define M_UNUSED_8 0x00000100 /* --available-- */
+#define M_NOFREE 0x00000200 /* do not free mbuf, embedded in cluster */
+
+#define M_PROTO1 0x00001000 /* protocol-specific */
+#define M_PROTO2 0x00002000 /* protocol-specific */
+#define M_PROTO3 0x00004000 /* protocol-specific */
+#define M_PROTO4 0x00008000 /* protocol-specific */
+#define M_PROTO5 0x00010000 /* protocol-specific */
+#define M_PROTO6 0x00020000 /* protocol-specific */
+#define M_PROTO7 0x00040000 /* protocol-specific */
+#define M_PROTO8 0x00080000 /* protocol-specific */
+#define M_PROTO9 0x00100000 /* protocol-specific */
+#define M_PROTO10 0x00200000 /* protocol-specific */
+#define M_PROTO11 0x00400000 /* protocol-specific */
+#define M_PROTO12 0x00800000 /* protocol-specific */
+
+#define MB_DTOR_SKIP 0x1 /* don't pollute the cache by touching a freed mbuf */
/*
- * For RELENG_{6,7} steal these flags for limited multiple routing table
- * support. In RELENG_8 and beyond, use just one flag and a tag.
+ * Flags to purge when crossing layers.
*/
-#define M_FIB 0xF0000000 /* steal some bits to store fib number. */
+#define M_PROTOFLAGS \
+ (M_PROTO1|M_PROTO2|M_PROTO3|M_PROTO4|M_PROTO5|M_PROTO6|M_PROTO7|M_PROTO8|\
+ M_PROTO9|M_PROTO10|M_PROTO11|M_PROTO12)
-#define M_NOTIFICATION M_PROTO5 /* SCTP notification */
+/*
+ * Flags preserved when copying m_pkthdr.
+ */
+#define M_COPYFLAGS \
+ (M_PKTHDR|M_EOR|M_RDONLY|M_BCAST|M_MCAST|M_PROMISC|M_VLANTAG| \
+ M_PROTOFLAGS)
/*
- * Flags to purge when crossing layers.
+ * Mbuf flag description for use with printf(9) %b identifier.
*/
-#define M_PROTOFLAGS \
- (M_PROTO1|M_PROTO2|M_PROTO3|M_PROTO4|M_PROTO5|M_PROTO6|M_PROTO7|M_PROTO8)
+#define M_FLAG_BITS \
+ "\20\1M_EXT\2M_PKTHDR\3M_EOR\4M_RDONLY\5M_BCAST\6M_MCAST" \
+ "\7M_PROMISC\10M_VLANTAG"
+#define M_FLAG_PROTOBITS \
+ "\15M_PROTO1\16M_PROTO2\17M_PROTO3\20M_PROTO4\21M_PROTO5" \
+ "\22M_PROTO6\23M_PROTO7\24M_PROTO8\25M_PROTO9\26M_PROTO10" \
+ "\27M_PROTO11\30M_PROTO12"
+#define M_FLAG_PRINTF (M_FLAG_BITS M_FLAG_PROTOBITS)
/*
* Network interface cards are able to hash protocol fields (such as IPv4
@@ -227,88 +318,214 @@ struct mbuf {
*
* Most NICs support RSS, which provides ordering and explicit affinity, and
* use the hash m_flag bits to indicate what header fields were covered by
- * the hash. M_HASHTYPE_OPAQUE can be set by non-RSS cards or configurations
- * that provide an opaque flow identifier, allowing for ordering and
- * distribution without explicit affinity.
+ * the hash. M_HASHTYPE_OPAQUE and M_HASHTYPE_OPAQUE_HASH can be set by non-
+ * RSS cards or configurations that provide an opaque flow identifier, allowing
+ * for ordering and distribution without explicit affinity. Additionally,
+ * M_HASHTYPE_OPAQUE_HASH indicates that the flow identifier has hash
+ * properties.
*/
-#define M_HASHTYPE_SHIFT 24
-#define M_HASHTYPE_NONE 0x0
-#define M_HASHTYPE_RSS_IPV4 0x1 /* IPv4 2-tuple */
-#define M_HASHTYPE_RSS_TCP_IPV4 0x2 /* TCPv4 4-tuple */
-#define M_HASHTYPE_RSS_IPV6 0x3 /* IPv6 2-tuple */
-#define M_HASHTYPE_RSS_TCP_IPV6 0x4 /* TCPv6 4-tuple */
-#define M_HASHTYPE_RSS_IPV6_EX 0x5 /* IPv6 2-tuple + ext hdrs */
-#define M_HASHTYPE_RSS_TCP_IPV6_EX 0x6 /* TCPv6 4-tiple + ext hdrs */
-#define M_HASHTYPE_OPAQUE 0xf /* ordering, not affinity */
-
-#define M_HASHTYPE_CLEAR(m) (m)->m_flags &= ~(M_HASHTYPEBITS)
-#define M_HASHTYPE_GET(m) (((m)->m_flags & M_HASHTYPEBITS) >> \
- M_HASHTYPE_SHIFT)
-#define M_HASHTYPE_SET(m, v) do { \
- (m)->m_flags &= ~M_HASHTYPEBITS; \
- (m)->m_flags |= ((v) << M_HASHTYPE_SHIFT); \
-} while (0)
+#define M_HASHTYPE_HASHPROP 0x80 /* has hash properties */
+#define M_HASHTYPE_HASH(t) (M_HASHTYPE_HASHPROP | (t))
+/* Microsoft RSS standard hash types */
+#define M_HASHTYPE_NONE 0
+#define M_HASHTYPE_RSS_IPV4 M_HASHTYPE_HASH(1) /* IPv4 2-tuple */
+#define M_HASHTYPE_RSS_TCP_IPV4 M_HASHTYPE_HASH(2) /* TCPv4 4-tuple */
+#define M_HASHTYPE_RSS_IPV6 M_HASHTYPE_HASH(3) /* IPv6 2-tuple */
+#define M_HASHTYPE_RSS_TCP_IPV6 M_HASHTYPE_HASH(4) /* TCPv6 4-tuple */
+#define M_HASHTYPE_RSS_IPV6_EX M_HASHTYPE_HASH(5) /* IPv6 2-tuple +
+ * ext hdrs */
+#define M_HASHTYPE_RSS_TCP_IPV6_EX M_HASHTYPE_HASH(6) /* TCPv6 4-tiple +
+ * ext hdrs */
+/* Non-standard RSS hash types */
+#define M_HASHTYPE_RSS_UDP_IPV4 M_HASHTYPE_HASH(7) /* IPv4 UDP 4-tuple*/
+#define M_HASHTYPE_RSS_UDP_IPV4_EX M_HASHTYPE_HASH(8) /* IPv4 UDP 4-tuple +
+ * ext hdrs */
+#define M_HASHTYPE_RSS_UDP_IPV6 M_HASHTYPE_HASH(9) /* IPv6 UDP 4-tuple*/
+#define M_HASHTYPE_RSS_UDP_IPV6_EX M_HASHTYPE_HASH(10)/* IPv6 UDP 4-tuple +
+ * ext hdrs */
+
+#define M_HASHTYPE_OPAQUE 63 /* ordering, not affinity */
+#define M_HASHTYPE_OPAQUE_HASH M_HASHTYPE_HASH(M_HASHTYPE_OPAQUE)
+ /* ordering+hash, not affinity*/
+
+#define M_HASHTYPE_CLEAR(m) ((m)->m_pkthdr.rsstype = 0)
+#define M_HASHTYPE_GET(m) ((m)->m_pkthdr.rsstype)
+#define M_HASHTYPE_SET(m, v) ((m)->m_pkthdr.rsstype = (v))
#define M_HASHTYPE_TEST(m, v) (M_HASHTYPE_GET(m) == (v))
+#define M_HASHTYPE_ISHASH(m) (M_HASHTYPE_GET(m) & M_HASHTYPE_HASHPROP)
/*
- * Flags preserved when copying m_pkthdr.
+ * COS/QOS class and quality of service tags.
+ * It uses DSCP code points as base.
*/
-#define M_COPYFLAGS \
- (M_PKTHDR|M_EOR|M_RDONLY|M_PROTOFLAGS|M_SKIP_FIREWALL|M_BCAST|M_MCAST|\
- M_FRAG|M_FIRSTFRAG|M_LASTFRAG|M_VLANTAG|M_PROMISC|M_FIB|M_HASHTYPEBITS)
+#define QOS_DSCP_CS0 0x00
+#define QOS_DSCP_DEF QOS_DSCP_CS0
+#define QOS_DSCP_CS1 0x20
+#define QOS_DSCP_AF11 0x28
+#define QOS_DSCP_AF12 0x30
+#define QOS_DSCP_AF13 0x38
+#define QOS_DSCP_CS2 0x40
+#define QOS_DSCP_AF21 0x48
+#define QOS_DSCP_AF22 0x50
+#define QOS_DSCP_AF23 0x58
+#define QOS_DSCP_CS3 0x60
+#define QOS_DSCP_AF31 0x68
+#define QOS_DSCP_AF32 0x70
+#define QOS_DSCP_AF33 0x78
+#define QOS_DSCP_CS4 0x80
+#define QOS_DSCP_AF41 0x88
+#define QOS_DSCP_AF42 0x90
+#define QOS_DSCP_AF43 0x98
+#define QOS_DSCP_CS5 0xa0
+#define QOS_DSCP_EF 0xb8
+#define QOS_DSCP_CS6 0xc0
+#define QOS_DSCP_CS7 0xe0
/*
- * External buffer types: identify ext_buf type.
+ * External mbuf storage buffer types.
*/
#define EXT_CLUSTER 1 /* mbuf cluster */
-#define EXT_SFBUF 2 /* sendfile(2)'s sf_bufs */
-#define EXT_JUMBOP 3 /* jumbo cluster 4096 bytes */
+#ifndef __rtems__
+#define EXT_SFBUF 2 /* sendfile(2)'s sf_buf */
+#endif /* __rtems__ */
+#define EXT_JUMBOP 3 /* jumbo cluster page sized */
#define EXT_JUMBO9 4 /* jumbo cluster 9216 bytes */
#define EXT_JUMBO16 5 /* jumbo cluster 16184 bytes */
#define EXT_PACKET 6 /* mbuf+cluster from packet zone */
#define EXT_MBUF 7 /* external mbuf reference (M_IOVEC) */
-#define EXT_NET_DRV 100 /* custom ext_buf provided by net driver(s) */
-#define EXT_MOD_TYPE 200 /* custom module's ext_buf type */
-#define EXT_DISPOSABLE 300 /* can throw this buffer away w/page flipping */
-#define EXT_EXTREF 400 /* has externally maintained ref_cnt ptr */
+#ifndef __rtems__
+#define EXT_SFBUF_NOCACHE 8 /* sendfile(2)'s sf_buf not to be cached */
+#endif /* __rtems__ */
+
+#define EXT_VENDOR1 224 /* for vendor-internal use */
+#define EXT_VENDOR2 225 /* for vendor-internal use */
+#define EXT_VENDOR3 226 /* for vendor-internal use */
+#define EXT_VENDOR4 227 /* for vendor-internal use */
+
+#define EXT_EXP1 244 /* for experimental use */
+#define EXT_EXP2 245 /* for experimental use */
+#define EXT_EXP3 246 /* for experimental use */
+#define EXT_EXP4 247 /* for experimental use */
+
+#define EXT_NET_DRV 252 /* custom ext_buf provided by net driver(s) */
+#define EXT_MOD_TYPE 253 /* custom module's ext_buf type */
+#define EXT_DISPOSABLE 254 /* can throw this buffer away w/page flipping */
+#define EXT_EXTREF 255 /* has externally maintained ext_cnt ptr */
/*
- * Flags indicating hw checksum support and sw checksum requirements. This
- * field can be directly tested against if_data.ifi_hwassist.
+ * Flags for external mbuf buffer types.
+ * NB: limited to the lower 24 bits.
*/
-#define CSUM_IP 0x0001 /* will csum IP */
-#define CSUM_TCP 0x0002 /* will csum TCP */
-#define CSUM_UDP 0x0004 /* will csum UDP */
-#define CSUM_IP_FRAGS 0x0008 /* removed, left for compat */
-#define CSUM_FRAGMENT 0x0010 /* will do IP fragmentation */
-#define CSUM_TSO 0x0020 /* will do TSO */
-#define CSUM_SCTP 0x0040 /* will csum SCTP */
-#define CSUM_SCTP_IPV6 0x0080 /* will csum IPv6/SCTP */
-
-#define CSUM_IP_CHECKED 0x0100 /* did csum IP */
-#define CSUM_IP_VALID 0x0200 /* ... the csum is valid */
-#define CSUM_DATA_VALID 0x0400 /* csum_data field is valid */
-#define CSUM_PSEUDO_HDR 0x0800 /* csum_data has pseudo hdr */
-#define CSUM_SCTP_VALID 0x1000 /* SCTP checksum is valid */
-#define CSUM_UDP_IPV6 0x2000 /* will csum IPv6/UDP */
-#define CSUM_TCP_IPV6 0x4000 /* will csum IPv6/TCP */
-/* CSUM_TSO_IPV6 0x8000 will do IPv6/TSO */
-
-/* CSUM_FRAGMENT_IPV6 0x10000 will do IPv6 fragementation */
-
-#define CSUM_DELAY_DATA_IPV6 (CSUM_TCP_IPV6 | CSUM_UDP_IPV6)
-#define CSUM_DATA_VALID_IPV6 CSUM_DATA_VALID
+#define EXT_FLAG_EMBREF 0x000001 /* embedded ext_count */
+#define EXT_FLAG_EXTREF 0x000002 /* external ext_cnt, notyet */
+
+#define EXT_FLAG_NOFREE 0x000010 /* don't free mbuf to pool, notyet */
-#define CSUM_DELAY_DATA (CSUM_TCP | CSUM_UDP)
-#define CSUM_DELAY_IP (CSUM_IP) /* Only v4, no v6 IP hdr csum */
+#define EXT_FLAG_VENDOR1 0x010000 /* for vendor-internal use */
+#define EXT_FLAG_VENDOR2 0x020000 /* for vendor-internal use */
+#define EXT_FLAG_VENDOR3 0x040000 /* for vendor-internal use */
+#define EXT_FLAG_VENDOR4 0x080000 /* for vendor-internal use */
+
+#define EXT_FLAG_EXP1 0x100000 /* for experimental use */
+#define EXT_FLAG_EXP2 0x200000 /* for experimental use */
+#define EXT_FLAG_EXP3 0x400000 /* for experimental use */
+#define EXT_FLAG_EXP4 0x800000 /* for experimental use */
+
+/*
+ * EXT flag description for use with printf(9) %b identifier.
+ */
+#define EXT_FLAG_BITS \
+ "\20\1EXT_FLAG_EMBREF\2EXT_FLAG_EXTREF\5EXT_FLAG_NOFREE" \
+ "\21EXT_FLAG_VENDOR1\22EXT_FLAG_VENDOR2\23EXT_FLAG_VENDOR3" \
+ "\24EXT_FLAG_VENDOR4\25EXT_FLAG_EXP1\26EXT_FLAG_EXP2\27EXT_FLAG_EXP3" \
+ "\30EXT_FLAG_EXP4"
+
+/*
+ * External reference/free functions.
+ */
+void sf_ext_free(void *, void *);
+void sf_ext_free_nocache(void *, void *);
/*
- * mbuf types.
+ * Flags indicating checksum, segmentation and other offload work to be
+ * done, or already done, by hardware or lower layers. It is split into
+ * separate inbound and outbound flags.
+ *
+ * Outbound flags that are set by upper protocol layers requesting lower
+ * layers, or ideally the hardware, to perform these offloading tasks.
+ * For outbound packets this field and its flags can be directly tested
+ * against ifnet if_hwassist.
+ */
+#define CSUM_IP 0x00000001 /* IP header checksum offload */
+#define CSUM_IP_UDP 0x00000002 /* UDP checksum offload */
+#define CSUM_IP_TCP 0x00000004 /* TCP checksum offload */
+#define CSUM_IP_SCTP 0x00000008 /* SCTP checksum offload */
+#define CSUM_IP_TSO 0x00000010 /* TCP segmentation offload */
+#define CSUM_IP_ISCSI 0x00000020 /* iSCSI checksum offload */
+
+#define CSUM_IP6_UDP 0x00000200 /* UDP checksum offload */
+#define CSUM_IP6_TCP 0x00000400 /* TCP checksum offload */
+#define CSUM_IP6_SCTP 0x00000800 /* SCTP checksum offload */
+#define CSUM_IP6_TSO 0x00001000 /* TCP segmentation offload */
+#define CSUM_IP6_ISCSI 0x00002000 /* iSCSI checksum offload */
+
+/* Inbound checksum support where the checksum was verified by hardware. */
+#define CSUM_L3_CALC 0x01000000 /* calculated layer 3 csum */
+#define CSUM_L3_VALID 0x02000000 /* checksum is correct */
+#define CSUM_L4_CALC 0x04000000 /* calculated layer 4 csum */
+#define CSUM_L4_VALID 0x08000000 /* checksum is correct */
+#define CSUM_L5_CALC 0x10000000 /* calculated layer 5 csum */
+#define CSUM_L5_VALID 0x20000000 /* checksum is correct */
+#define CSUM_COALESED 0x40000000 /* contains merged segments */
+
+/*
+ * CSUM flag description for use with printf(9) %b identifier.
+ */
+#define CSUM_BITS \
+ "\20\1CSUM_IP\2CSUM_IP_UDP\3CSUM_IP_TCP\4CSUM_IP_SCTP\5CSUM_IP_TSO" \
+ "\6CSUM_IP_ISCSI" \
+ "\12CSUM_IP6_UDP\13CSUM_IP6_TCP\14CSUM_IP6_SCTP\15CSUM_IP6_TSO" \
+ "\16CSUM_IP6_ISCSI" \
+ "\31CSUM_L3_CALC\32CSUM_L3_VALID\33CSUM_L4_CALC\34CSUM_L4_VALID" \
+ "\35CSUM_L5_CALC\36CSUM_L5_VALID\37CSUM_COALESED"
+
+/* CSUM flags compatibility mappings. */
+#define CSUM_IP_CHECKED CSUM_L3_CALC
+#define CSUM_IP_VALID CSUM_L3_VALID
+#define CSUM_DATA_VALID CSUM_L4_VALID
+#define CSUM_PSEUDO_HDR CSUM_L4_CALC
+#define CSUM_SCTP_VALID CSUM_L4_VALID
+#define CSUM_DELAY_DATA (CSUM_TCP|CSUM_UDP)
+#define CSUM_DELAY_IP CSUM_IP /* Only v4, no v6 IP hdr csum */
+#define CSUM_DELAY_DATA_IPV6 (CSUM_TCP_IPV6|CSUM_UDP_IPV6)
+#define CSUM_DATA_VALID_IPV6 CSUM_DATA_VALID
+#define CSUM_TCP CSUM_IP_TCP
+#define CSUM_UDP CSUM_IP_UDP
+#define CSUM_SCTP CSUM_IP_SCTP
+#define CSUM_TSO (CSUM_IP_TSO|CSUM_IP6_TSO)
+#define CSUM_UDP_IPV6 CSUM_IP6_UDP
+#define CSUM_TCP_IPV6 CSUM_IP6_TCP
+#define CSUM_SCTP_IPV6 CSUM_IP6_SCTP
+
+/*
+ * mbuf types describing the content of the mbuf (including external storage).
*/
#define MT_NOTMBUF 0 /* USED INTERNALLY ONLY! Object is not mbuf */
#define MT_DATA 1 /* dynamic (data) allocation */
#define MT_HEADER MT_DATA /* packet header, use M_PKTHDR instead */
+
+#define MT_VENDOR1 4 /* for vendor-internal use */
+#define MT_VENDOR2 5 /* for vendor-internal use */
+#define MT_VENDOR3 6 /* for vendor-internal use */
+#define MT_VENDOR4 7 /* for vendor-internal use */
+
#define MT_SONAME 8 /* socket name */
+
+#define MT_EXP1 9 /* for experimental use */
+#define MT_EXP2 10 /* for experimental use */
+#define MT_EXP3 11 /* for experimental use */
+#define MT_EXP4 12 /* for experimental use */
+
#define MT_CONTROL 14 /* extra-data protocol message */
#define MT_OOBDATA 15 /* expedited data */
#define MT_NTYPES 16 /* number of mbuf types for mbtypes[] */
@@ -316,55 +533,6 @@ struct mbuf {
#define MT_NOINIT 255 /* Not a type but a flag to allocate
a non-initialized mbuf */
-#define MB_NOTAGS 0x1UL /* no tags attached to mbuf */
-
-/*
- * General mbuf allocator statistics structure.
- *
- * Many of these statistics are no longer used; we instead track many
- * allocator statistics through UMA's built in statistics mechanism.
- */
-struct mbstat {
- u_long m_mbufs; /* XXX */
- u_long m_mclusts; /* XXX */
-
- u_long m_drain; /* times drained protocols for space */
- u_long m_mcfail; /* XXX: times m_copym failed */
- u_long m_mpfail; /* XXX: times m_pullup failed */
- u_long m_msize; /* length of an mbuf */
- u_long m_mclbytes; /* length of an mbuf cluster */
- u_long m_minclsize; /* min length of data to allocate a cluster */
- u_long m_mlen; /* length of data in an mbuf */
- u_long m_mhlen; /* length of data in a header mbuf */
-
- /* Number of mbtypes (gives # elems in mbtypes[] array) */
- short m_numtypes;
-
- /* XXX: Sendfile stats should eventually move to their own struct */
- u_long sf_iocnt; /* times sendfile had to do disk I/O */
- u_long sf_allocfail; /* times sfbuf allocation failed */
- u_long sf_allocwait; /* times sfbuf allocation had to wait */
-};
-
-/*
- * Flags specifying how an allocation should be made.
- *
- * The flag to use is as follows:
- * - M_NOWAIT (M_DONTWAIT) from an interrupt handler to not block allocation.
- * - M_WAITOK (M_WAIT) from wherever it is safe to block.
- *
- * M_DONTWAIT/M_NOWAIT means that we will not block the thread explicitly and
- * if we cannot allocate immediately we may return NULL, whereas
- * M_WAIT/M_WAITOK means that if we cannot allocate resources we
- * will block until they are available, and thus never return NULL.
- *
- * XXX Eventually just phase this out to use M_WAITOK/M_NOWAIT.
- */
-#define MBTOM(how) (how)
-#define M_DONTWAIT M_NOWAIT
-#define M_TRYWAIT M_WAITOK
-#define M_WAIT M_WAITOK
-
/*
* String names of mbuf-related UMA(9) and malloc(9) types. Exposed to
* !_KERNEL so that monitoring tools can look up the zones with
@@ -402,23 +570,53 @@ extern uma_zone_t zone_pack;
extern uma_zone_t zone_jumbop;
extern uma_zone_t zone_jumbo9;
extern uma_zone_t zone_jumbo16;
-extern uma_zone_t zone_ext_refcnt;
-
-static __inline struct mbuf *m_getcl(int how, short type, int flags);
-static __inline struct mbuf *m_get(int how, short type);
-static __inline struct mbuf *m_gethdr(int how, short type);
-static __inline struct mbuf *m_getjcl(int how, short type, int flags,
- int size);
-static __inline struct mbuf *m_getclr(int how, short type); /* XXX */
-static __inline int m_init(struct mbuf *m, uma_zone_t zone,
- int size, int how, short type, int flags);
-static __inline struct mbuf *m_free(struct mbuf *m);
-static __inline void m_clget(struct mbuf *m, int how);
-static __inline void *m_cljget(struct mbuf *m, int how, int size);
-static __inline void m_chtype(struct mbuf *m, short new_type);
-void mb_free_ext(struct mbuf *);
-static __inline struct mbuf *m_last(struct mbuf *m);
-int m_pkthdr_init(struct mbuf *m, int how);
+
+void mb_dupcl(struct mbuf *, struct mbuf *);
+void mb_free_ext(struct mbuf *);
+void m_adj(struct mbuf *, int);
+int m_apply(struct mbuf *, int, int,
+ int (*)(void *, void *, u_int), void *);
+int m_append(struct mbuf *, int, c_caddr_t);
+void m_cat(struct mbuf *, struct mbuf *);
+void m_catpkt(struct mbuf *, struct mbuf *);
+int m_clget(struct mbuf *m, int how);
+void *m_cljget(struct mbuf *m, int how, int size);
+struct mbuf *m_collapse(struct mbuf *, int, int);
+void m_copyback(struct mbuf *, int, int, c_caddr_t);
+void m_copydata(const struct mbuf *, int, int, caddr_t);
+struct mbuf *m_copym(struct mbuf *, int, int, int);
+struct mbuf *m_copypacket(struct mbuf *, int);
+void m_copy_pkthdr(struct mbuf *, struct mbuf *);
+struct mbuf *m_copyup(struct mbuf *, int, int);
+struct mbuf *m_defrag(struct mbuf *, int);
+void m_demote_pkthdr(struct mbuf *);
+void m_demote(struct mbuf *, int, int);
+struct mbuf *m_devget(char *, int, int, struct ifnet *,
+ void (*)(char *, caddr_t, u_int));
+struct mbuf *m_dup(const struct mbuf *, int);
+int m_dup_pkthdr(struct mbuf *, const struct mbuf *, int);
+void m_extadd(struct mbuf *, caddr_t, u_int,
+ void (*)(struct mbuf *, void *, void *), void *, void *,
+ int, int);
+u_int m_fixhdr(struct mbuf *);
+struct mbuf *m_fragment(struct mbuf *, int, int);
+void m_freem(struct mbuf *);
+struct mbuf *m_get2(int, int, short, int);
+struct mbuf *m_getjcl(int, short, int, int);
+struct mbuf *m_getm2(struct mbuf *, int, int, short, int);
+struct mbuf *m_getptr(struct mbuf *, int, int *);
+u_int m_length(struct mbuf *, struct mbuf **);
+int m_mbuftouio(struct uio *, struct mbuf *, int);
+void m_move_pkthdr(struct mbuf *, struct mbuf *);
+int m_pkthdr_init(struct mbuf *, int);
+struct mbuf *m_prepend(struct mbuf *, int, int);
+void m_print(const struct mbuf *, int);
+struct mbuf *m_pulldown(struct mbuf *, int, int, int *);
+struct mbuf *m_pullup(struct mbuf *, int);
+int m_sanity(struct mbuf *, int);
+struct mbuf *m_split(struct mbuf *, int, int);
+struct mbuf *m_uiotombuf(struct uio *, int, int, int, int);
+struct mbuf *m_unshare(struct mbuf *, int);
static __inline int
m_gettype(int size)
@@ -444,7 +642,7 @@ m_gettype(int size)
type = EXT_JUMBO16;
break;
default:
- panic("%s: m_getjcl: invalid cluster size", __func__);
+ panic("%s: invalid cluster size %d", __func__, size);
}
return (type);
@@ -455,7 +653,7 @@ m_gettype(int size)
*/
static __inline void
m_extaddref(struct mbuf *m, caddr_t buf, u_int size, u_int *ref_cnt,
- void (*freef)(void *, void *), void *arg1, void *arg2)
+ void (*freef)(struct mbuf *, void *, void *), void *arg1, void *arg2)
{
KASSERT(ref_cnt != NULL, ("%s: ref_cnt not provided", __func__));
@@ -463,13 +661,14 @@ m_extaddref(struct mbuf *m, caddr_t buf, u_int size, u_int *ref_cnt,
atomic_add_int((int*)ref_cnt, 1);
m->m_flags |= M_EXT;
m->m_ext.ext_buf = buf;
- m->m_ext.ref_cnt = ref_cnt;
+ m->m_ext.ext_cnt = ref_cnt;
m->m_data = m->m_ext.ext_buf;
m->m_ext.ext_size = size;
m->m_ext.ext_free = freef;
m->m_ext.ext_arg1 = arg1;
m->m_ext.ext_arg2 = arg2;
m->m_ext.ext_type = EXT_EXTREF;
+ m->m_ext.ext_flags = 0;
}
static __inline uma_zone_t
@@ -478,9 +677,6 @@ m_getzone(int size)
uma_zone_t zone;
switch (size) {
- case MSIZE:
- zone = zone_mbuf;
- break;
case MCLBYTES:
zone = zone_clust;
break;
@@ -496,7 +692,7 @@ m_getzone(int size)
zone = zone_jumbo16;
break;
default:
- panic("%s: m_getjcl: invalid cluster type", __func__);
+ panic("%s: invalid cluster size %d", __func__, size);
}
return (zone);
@@ -510,8 +706,7 @@ m_getzone(int size)
* should go away with constant propagation for !MGETHDR.
*/
static __inline int
-m_init(struct mbuf *m, uma_zone_t zone, int size, int how, short type,
- int flags)
+m_init(struct mbuf *m, int how, short type, int flags)
{
int error;
@@ -521,182 +716,81 @@ m_init(struct mbuf *m, uma_zone_t zone, int size, int how, short type,
m->m_len = 0;
m->m_flags = flags;
m->m_type = type;
- if (flags & M_PKTHDR) {
- if ((error = m_pkthdr_init(m, how)) != 0)
- return (error);
- }
+ if (flags & M_PKTHDR)
+ error = m_pkthdr_init(m, how);
+ else
+ error = 0;
- return (0);
+ MBUF_PROBE5(m__init, m, how, type, flags, error);
+ return (error);
}
static __inline struct mbuf *
m_get(int how, short type)
{
- struct mb_args args;
-
- args.flags = 0;
- args.type = type;
- return ((struct mbuf *)(uma_zalloc_arg(zone_mbuf, &args, how)));
-}
-
-/*
- * XXX This should be deprecated, very little use.
- */
-static __inline struct mbuf *
-m_getclr(int how, short type)
-{
struct mbuf *m;
struct mb_args args;
args.flags = 0;
args.type = type;
- m = (struct mbuf *)uma_zalloc_arg(zone_mbuf, &args, how);
- if (m != NULL)
- bzero(m->m_data, MLEN);
+ m = uma_zalloc_arg(zone_mbuf, &args, how);
+ MBUF_PROBE3(m__get, how, type, m);
return (m);
}
static __inline struct mbuf *
m_gethdr(int how, short type)
{
+ struct mbuf *m;
struct mb_args args;
args.flags = M_PKTHDR;
args.type = type;
- return ((struct mbuf *)(uma_zalloc_arg(zone_mbuf, &args, how)));
+ m = uma_zalloc_arg(zone_mbuf, &args, how);
+ MBUF_PROBE3(m__gethdr, how, type, m);
+ return (m);
}
static __inline struct mbuf *
m_getcl(int how, short type, int flags)
{
+ struct mbuf *m;
struct mb_args args;
args.flags = flags;
args.type = type;
- return ((struct mbuf *)(uma_zalloc_arg(zone_pack, &args, how)));
-}
-
-/*
- * m_getjcl() returns an mbuf with a cluster of the specified size attached.
- * For size it takes MCLBYTES, MJUMPAGESIZE, MJUM9BYTES, MJUM16BYTES.
- *
- * XXX: This is rather large, should be real function maybe.
- */
-static __inline struct mbuf *
-m_getjcl(int how, short type, int flags, int size)
-{
- struct mb_args args;
- struct mbuf *m, *n;
- uma_zone_t zone;
-
- if (size == MCLBYTES)
- return m_getcl(how, type, flags);
-
- args.flags = flags;
- args.type = type;
-
- m = (struct mbuf *)uma_zalloc_arg(zone_mbuf, &args, how);
- if (m == NULL)
- return (NULL);
-
- zone = m_getzone(size);
- n = (struct mbuf *)uma_zalloc_arg(zone, m, how);
- if (n == NULL) {
- uma_zfree(zone_mbuf, m);
- return (NULL);
- }
+ m = uma_zalloc_arg(zone_pack, &args, how);
+ MBUF_PROBE4(m__getcl, how, type, flags, m);
return (m);
}
-static __inline void
-m_free_fast(struct mbuf *m)
-{
-#ifdef INVARIANTS
- if (m->m_flags & M_PKTHDR)
- KASSERT(SLIST_EMPTY(&m->m_pkthdr.tags), ("doing fast free of mbuf with tags"));
-#endif
-
- uma_zfree_arg(zone_mbuf, m, (void *)MB_NOTAGS);
-}
-
-static __inline struct mbuf *
-m_free(struct mbuf *m)
-{
- struct mbuf *n = m->m_next;
-
- if (m->m_flags & M_EXT)
- mb_free_ext(m);
- else if ((m->m_flags & M_NOFREE) == 0)
- uma_zfree(zone_mbuf, m);
- return (n);
-}
-
-static __inline void
-m_clget(struct mbuf *m, int how)
-{
-
- if (m->m_flags & M_EXT)
- printf("%s: %p mbuf already has cluster\n", __func__, m);
- m->m_ext.ext_buf = (char *)NULL;
- uma_zalloc_arg(zone_clust, m, how);
- /*
- * On a cluster allocation failure, drain the packet zone and retry,
- * we might be able to loosen a few clusters up on the drain.
- */
- if ((how & M_NOWAIT) && (m->m_ext.ext_buf == NULL)) {
- zone_drain(zone_pack);
- uma_zalloc_arg(zone_clust, m, how);
- }
-}
-
/*
- * m_cljget() is different from m_clget() as it can allocate clusters without
- * attaching them to an mbuf. In that case the return value is the pointer
- * to the cluster of the requested size. If an mbuf was specified, it gets
- * the cluster attached to it and the return value can be safely ignored.
- * For size it takes MCLBYTES, MJUMPAGESIZE, MJUM9BYTES, MJUM16BYTES.
+ * XXX: m_cljset() is a dangerous API. One must attach only a new,
+ * unreferenced cluster to an mbuf(9). It is not possible to assert
+ * that, so care can be taken only by users of the API.
*/
-static __inline void *
-m_cljget(struct mbuf *m, int how, int size)
-{
- uma_zone_t zone;
-
- if (m && m->m_flags & M_EXT)
- printf("%s: %p mbuf already has cluster\n", __func__, m);
- if (m != NULL)
- m->m_ext.ext_buf = NULL;
-
- zone = m_getzone(size);
- return (uma_zalloc_arg(zone, m, how));
-}
-
static __inline void
m_cljset(struct mbuf *m, void *cl, int type)
{
- uma_zone_t zone;
int size;
switch (type) {
case EXT_CLUSTER:
size = MCLBYTES;
- zone = zone_clust;
break;
#if MJUMPAGESIZE != MCLBYTES
case EXT_JUMBOP:
size = MJUMPAGESIZE;
- zone = zone_jumbop;
break;
#endif
case EXT_JUMBO9:
size = MJUM9BYTES;
- zone = zone_jumbo9;
break;
case EXT_JUMBO16:
size = MJUM16BYTES;
- zone = zone_jumbo16;
break;
default:
- panic("unknown cluster type");
+ panic("%s: unknown cluster type %d", __func__, type);
break;
}
@@ -705,9 +799,10 @@ m_cljset(struct mbuf *m, void *cl, int type)
m->m_ext.ext_arg1 = m->m_ext.ext_arg2 = NULL;
m->m_ext.ext_size = size;
m->m_ext.ext_type = type;
- m->m_ext.ref_cnt = (volatile u_int *) uma_find_refcnt(zone, cl);
+ m->m_ext.ext_flags = EXT_FLAG_EMBREF;
+ m->m_ext.ext_count = 1;
m->m_flags |= M_EXT;
-
+ MBUF_PROBE3(m__cljset, m, cl, type);
}
static __inline void
@@ -717,6 +812,16 @@ m_chtype(struct mbuf *m, short new_type)
m->m_type = new_type;
}
+static __inline void
+m_clrprotoflags(struct mbuf *m)
+{
+
+ while (m) {
+ m->m_flags &= ~M_PROTOFLAGS;
+ m = m->m_next;
+ }
+}
+
static __inline struct mbuf *
m_last(struct mbuf *m)
{
@@ -726,14 +831,14 @@ m_last(struct mbuf *m)
return (m);
}
-extern void (*m_addr_chg_pf_p)(struct mbuf *m);
-
-static __inline void
-m_addr_changed(struct mbuf *m)
+static inline u_int
+m_extrefcnt(struct mbuf *m)
{
- if (m_addr_chg_pf_p)
- m_addr_chg_pf_p(m);
+ KASSERT(m->m_flags & M_EXT, ("%s: M_EXT missing", __func__));
+
+ return ((m->m_ext.ext_flags & EXT_FLAG_EMBREF) ? m->m_ext.ext_count :
+ *m->m_ext.ext_cnt);
}
/*
@@ -745,7 +850,8 @@ m_addr_changed(struct mbuf *m)
#define MGETHDR(m, how, type) ((m) = m_gethdr((how), (type)))
#define MCLGET(m, how) m_clget((m), (how))
#define MEXTADD(m, buf, size, free, arg1, arg2, flags, type) \
- m_extadd((m), (caddr_t)(buf), (size), (free),(arg1),(arg2),(flags), (type))
+ m_extadd((m), (caddr_t)(buf), (size), (free), (arg1), (arg2), \
+ (flags), (type))
#define m_getm(m, len, how, type) \
m_getm2((m), (len), (how), (type), M_PKTHDR)
@@ -756,7 +862,7 @@ m_addr_changed(struct mbuf *m)
*/
#define M_WRITABLE(m) (!((m)->m_flags & M_RDONLY) && \
(!(((m)->m_flags & M_EXT)) || \
- (*((m)->m_ext.ref_cnt) == 1)) ) \
+ (m_extrefcnt(m) == 1)))
/* Check if the supplied mbuf has a packet header, or else panic. */
#define M_ASSERTPKTHDR(m) \
@@ -773,28 +879,50 @@ m_addr_changed(struct mbuf *m)
("%s: attempted use of a free mbuf!", __func__))
/*
- * Set the m_data pointer of a newly-allocated mbuf (m_get/MGET) to place an
- * object of the specified size at the end of the mbuf, longword aligned.
+ * Return the address of the start of the buffer associated with an mbuf,
+ * handling external storage, packet-header mbufs, and regular data mbufs.
*/
-#define M_ALIGN(m, len) do { \
- KASSERT(!((m)->m_flags & (M_PKTHDR|M_EXT)), \
- ("%s: M_ALIGN not normal mbuf", __func__)); \
- KASSERT((m)->m_data == (m)->m_dat, \
- ("%s: M_ALIGN not a virgin mbuf", __func__)); \
- (m)->m_data += (MLEN - (len)) & ~(sizeof(long) - 1); \
-} while (0)
+#define M_START(m) \
+ (((m)->m_flags & M_EXT) ? (m)->m_ext.ext_buf : \
+ ((m)->m_flags & M_PKTHDR) ? &(m)->m_pktdat[0] : \
+ &(m)->m_dat[0])
/*
- * As above, for mbufs allocated with m_gethdr/MGETHDR or initialized by
- * M_DUP/MOVE_PKTHDR.
+ * Return the size of the buffer associated with an mbuf, handling external
+ * storage, packet-header mbufs, and regular data mbufs.
*/
-#define MH_ALIGN(m, len) do { \
- KASSERT((m)->m_flags & M_PKTHDR && !((m)->m_flags & M_EXT), \
- ("%s: MH_ALIGN not PKTHDR mbuf", __func__)); \
- KASSERT((m)->m_data == (m)->m_pktdat, \
- ("%s: MH_ALIGN not a virgin mbuf", __func__)); \
- (m)->m_data += (MHLEN - (len)) & ~(sizeof(long) - 1); \
-} while (0)
+#define M_SIZE(m) \
+ (((m)->m_flags & M_EXT) ? (m)->m_ext.ext_size : \
+ ((m)->m_flags & M_PKTHDR) ? MHLEN : \
+ MLEN)
+
+/*
+ * Set the m_data pointer of a newly allocated mbuf to place an object of the
+ * specified size at the end of the mbuf, longword aligned.
+ *
+ * NB: Historically, we had M_ALIGN(), MH_ALIGN(), and MEXT_ALIGN() as
+ * separate macros, each asserting that it was called at the proper moment.
+ * This required callers to themselves test the storage type and call the
+ * right one. Rather than require callers to be aware of those layout
+ * decisions, we centralize here.
+ */
+static __inline void
+m_align(struct mbuf *m, int len)
+{
+#ifdef INVARIANTS
+ const char *msg = "%s: not a virgin mbuf";
+#endif
+ int adjust;
+
+ KASSERT(m->m_data == M_START(m), (msg, __func__));
+
+ adjust = M_SIZE(m) - len;
+ m->m_data += adjust &~ (sizeof(long)-1);
+}
+
+#define M_ALIGN(m, len) m_align(m, len)
+#define MH_ALIGN(m, len) m_align(m, len)
+#define MEXT_ALIGN(m, len) m_align(m, len)
/*
* Compute the amount of space available before the current start of data in
@@ -802,24 +930,27 @@ m_addr_changed(struct mbuf *m)
*
* The M_WRITABLE() is a temporary, conservative safety measure: the burden
* of checking writability of the mbuf data area rests solely with the caller.
+ *
+ * NB: In previous versions, M_LEADINGSPACE() would only check M_WRITABLE()
+ * for mbufs with external storage. We now allow mbuf-embedded data to be
+ * read-only as well.
*/
#define M_LEADINGSPACE(m) \
- ((m)->m_flags & M_EXT ? \
- (M_WRITABLE(m) ? (m)->m_data - (m)->m_ext.ext_buf : 0): \
- (m)->m_flags & M_PKTHDR ? (m)->m_data - (m)->m_pktdat : \
- (m)->m_data - (m)->m_dat)
+ (M_WRITABLE(m) ? ((m)->m_data - M_START(m)) : 0)
/*
* Compute the amount of space available after the end of data in an mbuf.
*
* The M_WRITABLE() is a temporary, conservative safety measure: the burden
* of checking writability of the mbuf data area rests solely with the caller.
+ *
+ * NB: In previous versions, M_TRAILINGSPACE() would only check M_WRITABLE()
+ * for mbufs with external storage. We now allow mbuf-embedded data to be
+ * read-only as well.
*/
#define M_TRAILINGSPACE(m) \
- ((m)->m_flags & M_EXT ? \
- (M_WRITABLE(m) ? (m)->m_ext.ext_buf + (m)->m_ext.ext_size \
- - ((m)->m_data + (m)->m_len) : 0) : \
- &(m)->m_dat[MLEN] - ((m)->m_data + (m)->m_len))
+ (M_WRITABLE(m) ? \
+ ((M_START(m) + M_SIZE(m)) - ((m)->m_data + (m)->m_len)) : 0)
/*
* Arrange to prepend space of size plen to mbuf m. If a new mbuf must be
@@ -853,57 +984,14 @@ m_addr_changed(struct mbuf *m)
#define M_COPYALL 1000000000
/* Compatibility with 4.3. */
-#define m_copy(m, o, l) m_copym((m), (o), (l), M_DONTWAIT)
+#define m_copy(m, o, l) m_copym((m), (o), (l), M_NOWAIT)
extern int max_datalen; /* MHLEN - max_hdr */
extern int max_hdr; /* Largest link + protocol header */
extern int max_linkhdr; /* Largest link-level header */
extern int max_protohdr; /* Largest protocol header */
-extern struct mbstat mbstat; /* General mbuf stats/infos */
extern int nmbclusters; /* Maximum number of clusters */
-struct uio;
-
-void m_adj(struct mbuf *, int);
-void m_align(struct mbuf *, int);
-int m_apply(struct mbuf *, int, int,
- int (*)(void *, void *, u_int), void *);
-int m_append(struct mbuf *, int, c_caddr_t);
-void m_cat(struct mbuf *, struct mbuf *);
-void m_extadd(struct mbuf *, caddr_t, u_int,
- void (*)(void *, void *), void *, void *, int, int);
-struct mbuf *m_collapse(struct mbuf *, int, int);
-void m_copyback(struct mbuf *, int, int, c_caddr_t);
-void m_copydata(const struct mbuf *, int, int, caddr_t);
-struct mbuf *m_copym(struct mbuf *, int, int, int);
-struct mbuf *m_copymdata(struct mbuf *, struct mbuf *,
- int, int, int, int);
-struct mbuf *m_copypacket(struct mbuf *, int);
-void m_copy_pkthdr(struct mbuf *, struct mbuf *);
-struct mbuf *m_copyup(struct mbuf *n, int len, int dstoff);
-struct mbuf *m_defrag(struct mbuf *, int);
-void m_demote(struct mbuf *, int);
-struct mbuf *m_devget(char *, int, int, struct ifnet *,
- void (*)(char *, caddr_t, u_int));
-struct mbuf *m_dup(struct mbuf *, int);
-int m_dup_pkthdr(struct mbuf *, struct mbuf *, int);
-u_int m_fixhdr(struct mbuf *);
-struct mbuf *m_fragment(struct mbuf *, int, int);
-void m_freem(struct mbuf *);
-struct mbuf *m_getm2(struct mbuf *, int, int, short, int);
-struct mbuf *m_getptr(struct mbuf *, int, int *);
-u_int m_length(struct mbuf *, struct mbuf **);
-int m_mbuftouio(struct uio *, struct mbuf *, int);
-void m_move_pkthdr(struct mbuf *, struct mbuf *);
-struct mbuf *m_prepend(struct mbuf *, int, int);
-void m_print(const struct mbuf *, int);
-struct mbuf *m_pulldown(struct mbuf *, int, int, int *);
-struct mbuf *m_pullup(struct mbuf *, int);
-int m_sanity(struct mbuf *, int);
-struct mbuf *m_split(struct mbuf *, int, int);
-struct mbuf *m_uiotombuf(struct uio *, int, int, int, int);
-struct mbuf *m_unshare(struct mbuf *, int how);
-
/*-
* Network packets may have annotations attached by affixing a list of
* "packet tags" to the pkthdr structure. Packet tags are dynamically
@@ -975,7 +1063,7 @@ struct mbuf *m_unshare(struct mbuf *, int how);
#define PACKET_TAG_DIVERT 17 /* divert info */
#define PACKET_TAG_IPFORWARD 18 /* ipforward info */
#define PACKET_TAG_MACLABEL (19 | MTAG_PERSISTENT) /* MAC label */
-#define PACKET_TAG_PF 21 /* PF + ALTQ information */
+#define PACKET_TAG_PF (21 | MTAG_PERSISTENT) /* PF/ALTQ information */
#define PACKET_TAG_RTSOCKFAM 25 /* rtsock sa family */
#define PACKET_TAG_IPOPTIONS 27 /* Saved IP options */
#define PACKET_TAG_CARP 28 /* CARP info */
@@ -991,7 +1079,7 @@ void m_tag_delete_chain(struct mbuf *, struct m_tag *);
void m_tag_free_default(struct m_tag *);
struct m_tag *m_tag_locate(struct mbuf *, u_int32_t, int, struct m_tag *);
struct m_tag *m_tag_copy(struct m_tag *, int);
-int m_tag_copy_chain(struct mbuf *, struct mbuf *, int);
+int m_tag_copy_chain(struct mbuf *, const struct mbuf *, int);
void m_tag_delete_nonpersistent(struct mbuf *);
/*
@@ -1043,7 +1131,7 @@ m_tag_first(struct mbuf *m)
* Return the next tag in the list of tags associated with an mbuf.
*/
static __inline struct m_tag *
-m_tag_next(struct mbuf *m, struct m_tag *t)
+m_tag_next(struct mbuf *m __unused, struct m_tag *t)
{
return (SLIST_NEXT(t, m_tag_link));
@@ -1085,20 +1173,43 @@ m_tag_find(struct mbuf *m, int type, struct m_tag *start)
m_tag_locate(m, MTAG_ABI_COMPAT, type, start));
}
-/* XXX temporary FIB methods probably eventually use tags.*/
-#define M_FIBSHIFT 28
-#define M_FIBMASK 0x0F
+static __inline struct mbuf *
+m_free(struct mbuf *m)
+{
+ struct mbuf *n = m->m_next;
-/* get the fib from an mbuf and if it is not set, return the default */
-#define M_GETFIB(_m) \
- ((((_m)->m_flags & M_FIB) >> M_FIBSHIFT) & M_FIBMASK)
+ MBUF_PROBE1(m__free, m);
+ if ((m->m_flags & (M_PKTHDR|M_NOFREE)) == (M_PKTHDR|M_NOFREE))
+ m_tag_delete_chain(m, NULL);
+ if (m->m_flags & M_EXT)
+ mb_free_ext(m);
+ else if ((m->m_flags & M_NOFREE) == 0)
+ uma_zfree(zone_mbuf, m);
+ return (n);
+}
+
+static __inline int
+rt_m_getfib(struct mbuf *m)
+{
+ KASSERT(m->m_flags & M_PKTHDR , ("Attempt to get FIB from non header mbuf."));
+ return (m->m_pkthdr.fibnum);
+}
+
+#define M_GETFIB(_m) rt_m_getfib(_m)
#define M_SETFIB(_m, _fib) do { \
- _m->m_flags &= ~M_FIB; \
- _m->m_flags |= (((_fib) << M_FIBSHIFT) & M_FIB); \
+ KASSERT((_m)->m_flags & M_PKTHDR, ("Attempt to set FIB on non header mbuf.")); \
+ ((_m)->m_pkthdr.fibnum) = (_fib); \
} while (0)
-#endif /* _KERNEL */
+/* flags passed as first argument for "m_ether_tcpip_hash()" */
+#define MBUF_HASHFLAG_L2 (1 << 2)
+#define MBUF_HASHFLAG_L3 (1 << 3)
+#define MBUF_HASHFLAG_L4 (1 << 4)
+
+/* mbuf hashing helper routines */
+uint32_t m_ether_tcpip_hash_init(void);
+uint32_t m_ether_tcpip_hash(const uint32_t, const struct mbuf *, const uint32_t);
#ifdef MBUF_PROFILING
void m_profile(struct mbuf *m);
@@ -1107,5 +1218,103 @@ m_tag_find(struct mbuf *m, int type, struct m_tag *start)
#define M_PROFILE(m)
#endif
+struct mbufq {
+ STAILQ_HEAD(, mbuf) mq_head;
+ int mq_len;
+ int mq_maxlen;
+};
+
+static inline void
+mbufq_init(struct mbufq *mq, int maxlen)
+{
+
+ STAILQ_INIT(&mq->mq_head);
+ mq->mq_maxlen = maxlen;
+ mq->mq_len = 0;
+}
+
+static inline struct mbuf *
+mbufq_flush(struct mbufq *mq)
+{
+ struct mbuf *m;
+
+ m = STAILQ_FIRST(&mq->mq_head);
+ STAILQ_INIT(&mq->mq_head);
+ mq->mq_len = 0;
+ return (m);
+}
+
+static inline void
+mbufq_drain(struct mbufq *mq)
+{
+ struct mbuf *m, *n;
+
+ n = mbufq_flush(mq);
+ while ((m = n) != NULL) {
+ n = STAILQ_NEXT(m, m_stailqpkt);
+ m_freem(m);
+ }
+}
+
+static inline struct mbuf *
+mbufq_first(const struct mbufq *mq)
+{
+
+ return (STAILQ_FIRST(&mq->mq_head));
+}
+
+static inline struct mbuf *
+mbufq_last(const struct mbufq *mq)
+{
+
+ return (STAILQ_LAST(&mq->mq_head, mbuf, m_stailqpkt));
+}
+
+static inline int
+mbufq_full(const struct mbufq *mq)
+{
+
+ return (mq->mq_len >= mq->mq_maxlen);
+}
+
+static inline int
+mbufq_len(const struct mbufq *mq)
+{
+ return (mq->mq_len);
+}
+
+static inline int
+mbufq_enqueue(struct mbufq *mq, struct mbuf *m)
+{
+
+ if (mbufq_full(mq))
+ return (ENOBUFS);
+ STAILQ_INSERT_TAIL(&mq->mq_head, m, m_stailqpkt);
+ mq->mq_len++;
+ return (0);
+}
+
+static inline struct mbuf *
+mbufq_dequeue(struct mbufq *mq)
+{
+ struct mbuf *m;
+
+ m = STAILQ_FIRST(&mq->mq_head);
+ if (m) {
+ STAILQ_REMOVE_HEAD(&mq->mq_head, m_stailqpkt);
+ m->m_nextpkt = NULL;
+ mq->mq_len--;
+ }
+ return (m);
+}
+
+static inline void
+mbufq_prepend(struct mbufq *mq, struct mbuf *m)
+{
+
+ STAILQ_INSERT_HEAD(&mq->mq_head, m, m_stailqpkt);
+ mq->mq_len++;
+}
+#endif /* _KERNEL */
#endif /* !_SYS_MBUF_H_ */
diff --git a/freebsd/sys/sys/module.h b/freebsd/sys/sys/module.h
index 782770a7..07464fc6 100644
--- a/freebsd/sys/sys/module.h
+++ b/freebsd/sys/sys/module.h
@@ -35,6 +35,7 @@
#define MDT_DEPEND 1 /* argument is a module name */
#define MDT_MODULE 2 /* module declaration */
#define MDT_VERSION 3 /* module version(s) */
+#define MDT_PNP_INFO 4 /* Plug and play hints record */
#define MDT_STRUCT_VERSION 1 /* version of metadata structure */
#define MDT_SETNAME "modmetadata_set"
@@ -70,7 +71,7 @@ typedef union modspecific {
} modspecific_t;
/*
- * Module dependency declarartion
+ * Module dependency declaration
*/
struct mod_depend {
int md_ver_minimum;
@@ -88,10 +89,19 @@ struct mod_version {
struct mod_metadata {
int md_version; /* structure version MDTV_* */
int md_type; /* type of entry MDT_* */
- void *md_data; /* specific data */
+ const void *md_data; /* specific data */
const char *md_cval; /* common string label */
};
+struct mod_pnp_match_info
+{
+ const char *descr; /* Description of the table */
+ const char *bus; /* Name of the bus for this table */
+ const void *table; /* Pointer to pnp table */
+ int entry_len; /* Length of each entry in the table (may be */
+ /* longer than descr describes). */
+ int num_entry; /* Number of entries in the table */
+};
#ifdef _KERNEL
#include <sys/linker_set.h>
@@ -106,7 +116,8 @@ struct mod_metadata {
DATA_SET(modmetadata_set, _mod_metadata##uniquifier)
#define MODULE_DEPEND(module, mdepend, vmin, vpref, vmax) \
- static struct mod_depend _##module##_depend_on_##mdepend = { \
+ static struct mod_depend _##module##_depend_on_##mdepend \
+ __section(".data") = { \
vmin, \
vpref, \
vmax \
@@ -146,12 +157,51 @@ struct mod_metadata {
DECLARE_MODULE_WITH_MAXVER(name, data, sub, order, __FreeBSD_version)
#define MODULE_VERSION(module, version) \
- static struct mod_version _##module##_version = { \
+ static struct mod_version _##module##_version \
+ __section(".data") = { \
version \
}; \
MODULE_METADATA(_##module##_version, MDT_VERSION, \
&_##module##_version, #module)
+/**
+ * Generic macros to create pnp info hints that modules may export
+ * to allow external tools to parse their internal device tables
+ * to make an informed guess about what driver(s) to load.
+ */
+#define MODULE_PNP_INFO(d, b, unique, t, l, n) \
+ static const struct mod_pnp_match_info _module_pnp_##b##_##unique = { \
+ .descr = d, \
+ .bus = #b, \
+ .table = t, \
+ .entry_len = l, \
+ .num_entry = n \
+ }; \
+ MODULE_METADATA(_md_##b##_pnpinfo_##unique, MDT_PNP_INFO, \
+ &_module_pnp_##b##_##unique, #b);
+/**
+ * descr is a string that describes each entry in the table. The general
+ * form is (TYPE:pnp_name[/pnp_name];)*
+ * where TYPE is one of the following:
+ * U8 uint8_t element
+ * V8 like U8 and 0xff means match any
+ * G16 uint16_t element, any value >= matches
+ * L16 uint16_t element, any value <= matches
+ * M16 uint16_t element, mask of which of the following fields to use.
+ * U16 uint16_t element
+ * V16 like U16 and 0xffff means match any
+ * U32 uint32_t element
+ * V32 like U32 and 0xffffffff means match any
+ * W32 Two 16-bit values with first pnp_name in LSW and second in MSW.
+ * Z pointer to a string to match exactly
+ * D like Z, but is the string passed to device_set_descr()
+ * P A pointer that should be ignored
+ * E EISA PNP Identifier (in binary, but bus publishes string)
+ * K Key for whole table. pnp_name=value. must be last, if present.
+ *
+ * The pnp_name "#" is reserved for other fields that should be ignored.
+ */
+
extern struct sx modules_sx;
#define MOD_XLOCK sx_xlock(&modules_sx)
diff --git a/freebsd/sys/sys/mount.h b/freebsd/sys/sys/mount.h
index 0001016b..49e688f3 100644
--- a/freebsd/sys/sys/mount.h
+++ b/freebsd/sys/sys/mount.h
@@ -39,6 +39,7 @@
#include <rtems/bsd/sys/lock.h>
#include <sys/lockmgr.h>
#include <sys/_mutex.h>
+#include <sys/_sx.h>
#endif
/*
@@ -170,7 +171,6 @@ struct mount {
int mnt_writeopcount; /* (i) write syscalls pending */
int mnt_kern_flag; /* (i) kernel only flags */
uint64_t mnt_flag; /* (i) flags shared with user */
- u_int mnt_pad_noasync;
struct vfsoptlist *mnt_opt; /* current mount options */
struct vfsoptlist *mnt_optnew; /* new options passed to fs */
int mnt_maxsymlinklen; /* max size of short symlink */
@@ -226,29 +226,6 @@ void __mnt_vnode_markerfree_active(struct vnode **mvp, struct mount *);
#define MNT_VNODE_FOREACH_ACTIVE_ABORT(mp, mvp) \
__mnt_vnode_markerfree_active(&(mvp), (mp))
-/*
- * Definitions for MNT_VNODE_FOREACH.
- *
- * This interface has been deprecated in favor of MNT_VNODE_FOREACH_ALL.
- */
-struct vnode *__mnt_vnode_next(struct vnode **mvp, struct mount *mp);
-struct vnode *__mnt_vnode_first(struct vnode **mvp, struct mount *mp);
-void __mnt_vnode_markerfree(struct vnode **mvp, struct mount *mp);
-
-#define MNT_VNODE_FOREACH(vp, mp, mvp) \
- for (vp = __mnt_vnode_first(&(mvp), (mp)); \
- (vp) != NULL; vp = __mnt_vnode_next(&(mvp), (mp)))
-
-#define MNT_VNODE_FOREACH_ABORT_ILOCKED(mp, mvp) \
- __mnt_vnode_markerfree(&(mvp), (mp))
-
-#define MNT_VNODE_FOREACH_ABORT(mp, mvp) \
- do { \
- MNT_ILOCK(mp); \
- MNT_VNODE_FOREACH_ABORT_ILOCKED(mp, mvp); \
- MNT_IUNLOCK(mp); \
- } while (0)
-
#define MNT_ILOCK(mp) mtx_lock(&(mp)->mnt_mtx)
#define MNT_ITRYLOCK(mp) mtx_trylock(&(mp)->mnt_mtx)
#define MNT_IUNLOCK(mp) mtx_unlock(&(mp)->mnt_mtx)
@@ -283,6 +260,7 @@ void __mnt_vnode_markerfree(struct vnode **mvp, struct mount *mp);
#define MNT_NOCLUSTERR 0x0000000040000000ULL /* disable cluster read */
#define MNT_NOCLUSTERW 0x0000000080000000ULL /* disable cluster write */
#define MNT_SUJ 0x0000000100000000ULL /* using journaled soft updates */
+#define MNT_AUTOMOUNTED 0x0000000200000000ULL /* mounted by automountd(8) */
/*
* NFS export related mount flags.
@@ -319,7 +297,7 @@ void __mnt_vnode_markerfree(struct vnode **mvp, struct mount *mp);
MNT_NOCLUSTERW | MNT_SUIDDIR | MNT_SOFTDEP | \
MNT_IGNORE | MNT_EXPUBLIC | MNT_NOSYMFOLLOW | \
MNT_GJOURNAL | MNT_MULTILABEL | MNT_ACLS | \
- MNT_NFS4ACLS)
+ MNT_NFS4ACLS | MNT_AUTOMOUNTED)
/* Mask of flags that can be updated. */
#define MNT_UPDATEMASK (MNT_NOSUID | MNT_NOEXEC | \
@@ -327,23 +305,28 @@ void __mnt_vnode_markerfree(struct vnode **mvp, struct mount *mp);
MNT_NOATIME | \
MNT_NOSYMFOLLOW | MNT_IGNORE | \
MNT_NOCLUSTERR | MNT_NOCLUSTERW | MNT_SUIDDIR | \
- MNT_ACLS | MNT_USER | MNT_NFS4ACLS)
+ MNT_ACLS | MNT_USER | MNT_NFS4ACLS | \
+ MNT_AUTOMOUNTED)
/*
* External filesystem command modifier flags.
* Unmount can use the MNT_FORCE flag.
* XXX: These are not STATES and really should be somewhere else.
- * XXX: MNT_BYFSID collides with MNT_ACLS, but because MNT_ACLS is only used for
- * mount(2) and MNT_BYFSID is only used for unmount(2) it's harmless.
+ * XXX: MNT_BYFSID and MNT_NONBUSY collide with MNT_ACLS and MNT_MULTILABEL,
+ * but because MNT_ACLS and MNT_MULTILABEL are only used for mount(2),
+ * and MNT_BYFSID and MNT_NONBUSY are only used for unmount(2),
+ * it's harmless.
*/
#define MNT_UPDATE 0x0000000000010000ULL /* not real mount, just update */
#define MNT_DELEXPORT 0x0000000000020000ULL /* delete export host lists */
#define MNT_RELOAD 0x0000000000040000ULL /* reload filesystem data */
#define MNT_FORCE 0x0000000000080000ULL /* force unmount or readonly */
#define MNT_SNAPSHOT 0x0000000001000000ULL /* snapshot the filesystem */
+#define MNT_NONBUSY 0x0000000004000000ULL /* check vnode use counts. */
#define MNT_BYFSID 0x0000000008000000ULL /* specify filesystem by ID. */
#define MNT_CMDFLAGS (MNT_UPDATE | MNT_DELEXPORT | MNT_RELOAD | \
- MNT_FORCE | MNT_SNAPSHOT | MNT_BYFSID)
+ MNT_FORCE | MNT_SNAPSHOT | MNT_NONBUSY | \
+ MNT_BYFSID)
/*
* Internal filesystem control flags stored in mnt_kern_flag.
*
@@ -376,18 +359,32 @@ void __mnt_vnode_markerfree(struct vnode **mvp, struct mount *mp);
#define MNTK_LOOKUP_EXCL_DOTDOT 0x00000800
#define MNTK_MARKER 0x00001000
#define MNTK_UNMAPPED_BUFS 0x00002000
+#define MNTK_USES_BCACHE 0x00004000 /* FS uses the buffer cache. */
#define MNTK_NOASYNC 0x00800000 /* disable async */
#define MNTK_UNMOUNT 0x01000000 /* unmount in progress */
#define MNTK_MWAIT 0x02000000 /* waiting for unmount to finish */
#define MNTK_SUSPEND 0x08000000 /* request write suspension */
#define MNTK_SUSPEND2 0x04000000 /* block secondary writes */
#define MNTK_SUSPENDED 0x10000000 /* write operations are suspended */
-#define MNTK_MPSAFE 0x20000000 /* Filesystem is MPSAFE. */
+#define MNTK_UNUSED1 0x20000000
#define MNTK_LOOKUP_SHARED 0x40000000 /* FS supports shared lock lookups */
#define MNTK_NOKNOTE 0x80000000 /* Don't send KNOTEs from VOP hooks */
-#define MNT_SHARED_WRITES(mp) (((mp) != NULL) && \
- ((mp)->mnt_kern_flag & MNTK_SHARED_WRITES))
+#ifdef _KERNEL
+static inline int
+MNT_SHARED_WRITES(struct mount *mp)
+{
+
+ return (mp != NULL && (mp->mnt_kern_flag & MNTK_SHARED_WRITES) != 0);
+}
+
+static inline int
+MNT_EXTENDED_SHARED(struct mount *mp)
+{
+
+ return (mp != NULL && (mp->mnt_kern_flag & MNTK_EXTENDED_SHARED) != 0);
+}
+#endif
/*
* Sysctl CTL_VFS definitions.
@@ -597,7 +594,6 @@ struct uio;
MALLOC_DECLARE(M_MOUNT);
#endif
extern int maxvfsconf; /* highest defined filesystem type */
-extern int nfs_mount_type; /* vfc_typenum for nfs, or -1 */
TAILQ_HEAD(vfsconfhead, vfsconf);
extern struct vfsconfhead vfsconf;
@@ -633,6 +629,7 @@ typedef int vfs_sysctl_t(struct mount *mp, fsctlop_t op,
struct sysctl_req *req);
typedef void vfs_susp_clean_t(struct mount *mp);
typedef void vfs_notify_lowervp_t(struct mount *mp, struct vnode *lowervp);
+typedef void vfs_purge_t(struct mount *mp);
struct vfsops {
vfs_mount_t *vfs_mount;
@@ -652,54 +649,23 @@ struct vfsops {
vfs_susp_clean_t *vfs_susp_clean;
vfs_notify_lowervp_t *vfs_reclaim_lowervp;
vfs_notify_lowervp_t *vfs_unlink_lowervp;
+ vfs_purge_t *vfs_purge;
+ vfs_mount_t *vfs_spare[6]; /* spares for ABI compat */
};
vfs_statfs_t __vfs_statfs;
-#define VFS_NEEDSGIANT_(MP) \
- ((MP) != NULL && ((MP)->mnt_kern_flag & MNTK_MPSAFE) == 0)
-
-#define VFS_NEEDSGIANT(MP) __extension__ \
-({ \
- struct mount *_mp; \
- _mp = (MP); \
- VFS_NEEDSGIANT_(_mp); \
-})
-
-#define VFS_LOCK_GIANT(MP) __extension__ \
-({ \
- int _locked; \
- struct mount *_mp; \
- _mp = (MP); \
- if (VFS_NEEDSGIANT_(_mp)) { \
- mtx_lock(&Giant); \
- _locked = 1; \
- } else \
- _locked = 0; \
- _locked; \
-})
-#define VFS_UNLOCK_GIANT(locked) do \
-{ \
- if ((locked)) \
- mtx_unlock(&Giant); \
-} while (0)
-#define VFS_ASSERT_GIANT(MP) do \
-{ \
- struct mount *_mp; \
- _mp = (MP); \
- if (VFS_NEEDSGIANT_(_mp)) \
- mtx_assert(&Giant, MA_OWNED); \
-} while (0)
-
#define VFS_PROLOGUE(MP) do { \
- int _enable_stops; \
+ struct mount *mp__; \
+ int _prev_stops; \
\
- _enable_stops = ((MP) != NULL && \
- ((MP)->mnt_vfc->vfc_flags & VFCF_SBDRY) && sigdeferstop())
+ mp__ = (MP); \
+ _prev_stops = sigdeferstop((mp__ != NULL && \
+ (mp__->mnt_vfc->vfc_flags & VFCF_SBDRY) != 0) ? \
+ SIGDEFERSTOP_SILENT : SIGDEFERSTOP_NOP);
#define VFS_EPILOGUE(MP) \
- if (_enable_stops) \
- sigallowstop(); \
+ sigallowstop(_prev_stops); \
} while (0)
#define VFS_MOUNT(MP) ({ \
@@ -815,6 +781,14 @@ vfs_statfs_t __vfs_statfs;
} \
} while (0)
+#define VFS_PURGE(MP) do { \
+ if (*(MP)->mnt_op->vfs_purge != NULL) { \
+ VFS_PROLOGUE(MP); \
+ (*(MP)->mnt_op->vfs_purge)(MP); \
+ VFS_EPILOGUE(MP); \
+ } \
+} while (0)
+
#define VFS_KNOTE_LOCKED(vp, hint) do \
{ \
if (((vp)->v_vflag & VV_NOKNOTE) == 0) \
@@ -836,7 +810,8 @@ vfs_statfs_t __vfs_statfs;
* Version numbers.
*/
#define VFS_VERSION_00 0x19660120
-#define VFS_VERSION VFS_VERSION_00
+#define VFS_VERSION_01 0x20121030
+#define VFS_VERSION VFS_VERSION_01
#define VFS_SET(vfsops, fsname, flags) \
static struct vfsconf fsname ## _vfsconf = { \
@@ -853,8 +828,6 @@ vfs_statfs_t __vfs_statfs;
}; \
DECLARE_MODULE(fsname, fsname ## _mod, SI_SUB_VFS, SI_ORDER_MIDDLE)
-extern char *mountrootfsname;
-
/*
* exported vnode operations
*/
@@ -879,6 +852,8 @@ int vfs_flagopt(struct vfsoptlist *opts, const char *name, uint64_t *w,
uint64_t val);
int vfs_getopt(struct vfsoptlist *, const char *, void **, int *);
int vfs_getopt_pos(struct vfsoptlist *opts, const char *name);
+int vfs_getopt_size(struct vfsoptlist *opts, const char *name,
+ off_t *value);
char *vfs_getopts(struct vfsoptlist *, const char *, int *error);
int vfs_copyopt(struct vfsoptlist *, const char *, void *, int);
int vfs_filteropt(struct vfsoptlist *, const char **legal);
@@ -921,11 +896,17 @@ void vfs_unmountall(void);
extern TAILQ_HEAD(mntlist, mount) mountlist; /* mounted filesystem list */
extern struct mtx mountlist_mtx;
extern struct nfs_public nfs_pub;
+extern struct sx vfsconf_sx;
+#define vfsconf_lock() sx_xlock(&vfsconf_sx)
+#define vfsconf_unlock() sx_xunlock(&vfsconf_sx)
+#define vfsconf_slock() sx_slock(&vfsconf_sx)
+#define vfsconf_sunlock() sx_sunlock(&vfsconf_sx)
/*
* Declarations for these vfs default operations are located in
- * kern/vfs_default.c, they should be used instead of making "dummy"
- * functions or casting entries in the VFS op table to "enopnotsupp()".
+ * kern/vfs_default.c. They will be automatically used to replace
+ * null entries in VFS ops tables when registering a new filesystem
+ * type in the global table.
*/
vfs_root_t vfs_stdroot;
vfs_quotactl_t vfs_stdquotactl;
@@ -940,6 +921,9 @@ vfs_uninit_t vfs_stduninit;
vfs_extattrctl_t vfs_stdextattrctl;
vfs_sysctl_t vfs_stdsysctl;
+void syncer_suspend(void);
+void syncer_resume(void);
+
#else /* !_KERNEL */
#include <sys/cdefs.h>
diff --git a/freebsd/sys/sys/mutex.h b/freebsd/sys/sys/mutex.h
index 0e356e15..84feea7c 100644
--- a/freebsd/sys/sys/mutex.h
+++ b/freebsd/sys/sys/mutex.h
@@ -55,6 +55,7 @@
#define MTX_RECURSE 0x00000004 /* Option: lock allowed to recurse */
#define MTX_NOWITNESS 0x00000008 /* Don't do any witness checking. */
#define MTX_NOPROFILE 0x00000020 /* Don't profile this lock */
+#define MTX_NEW 0x00000040 /* Don't check for double-init */
/*
* Option flags passed to certain lock/unlock routines, through the use
@@ -82,7 +83,8 @@
*
* NOTE: Functions prepended with `_' (underscore) are exported to other parts
* of the kernel via macros, thus allowing us to use the cpp LOCK_FILE
- * and LOCK_LINE. These functions should not be called directly by any
+ * and LOCK_LINE or for hiding the lock cookie crunching to the
+ * consumers. These functions should not be called directly by any
* code using the API. Their macros cover their functionality.
* Functions with a `_' suffix are the entrypoint for the common
* KPI covering both compat shims and fast path case. These can be
@@ -92,52 +94,102 @@
* [See below for descriptions]
*
*/
-void mtx_init(struct mtx *m, const char *name, const char *type, int opts);
-void mtx_destroy(struct mtx *m);
+#ifndef __rtems__
+void _mtx_init(volatile uintptr_t *c, const char *name, const char *type,
+ int opts);
+void _mtx_destroy(volatile uintptr_t *c);
+#endif /* __rtems__ */
void mtx_sysinit(void *arg);
+#ifndef __rtems__
+int _mtx_trylock_flags_(volatile uintptr_t *c, int opts, const char *file,
+ int line);
void mutex_init(void);
-void _mtx_lock_sleep(struct mtx *m, uintptr_t tid, int opts,
+void __mtx_lock_sleep(volatile uintptr_t *c, uintptr_t tid, int opts,
const char *file, int line);
-void _mtx_unlock_sleep(struct mtx *m, int opts, const char *file, int line);
+void __mtx_unlock_sleep(volatile uintptr_t *c, int opts, const char *file,
+ int line);
#ifdef SMP
-void _mtx_lock_spin(struct mtx *m, uintptr_t tid, int opts,
+void _mtx_lock_spin_cookie(volatile uintptr_t *c, uintptr_t tid, int opts,
const char *file, int line);
#endif
-void _mtx_unlock_spin(struct mtx *m, int opts, const char *file, int line);
-int _mtx_trylock(struct mtx *m, int opts, const char *file, int line);
+void __mtx_lock_flags(volatile uintptr_t *c, int opts, const char *file,
+ int line);
+void __mtx_unlock_flags(volatile uintptr_t *c, int opts, const char *file,
+ int line);
+void __mtx_lock_spin_flags(volatile uintptr_t *c, int opts, const char *file,
+ int line);
+int __mtx_trylock_spin_flags(volatile uintptr_t *c, int opts,
+ const char *file, int line);
+void __mtx_unlock_spin_flags(volatile uintptr_t *c, int opts,
+ const char *file, int line);
+#else /* __rtems__ */
+void mtx_init(struct mtx *m, const char *name, const char *type, int opts);
+void mtx_destroy(struct mtx *m);
+void mtx_sysinit(void *arg);
+int mtx_trylock_flags_(struct mtx *m, int opts, const char *file, int line);
void _mtx_lock_flags(struct mtx *m, int opts, const char *file, int line);
void _mtx_unlock_flags(struct mtx *m, int opts, const char *file, int line);
+#define _mtx_lock_spin_flags _mtx_lock_flags
+#define _mtx_unlock_spin_flags _mtx_unlock_flags
+#endif /* __rtems__ */
+#if defined(INVARIANTS) || defined(INVARIANT_SUPPORT)
#ifndef __rtems__
-void _mtx_lock_spin_flags(struct mtx *m, int opts, const char *file,
- int line);
-void _mtx_unlock_spin_flags(struct mtx *m, int opts, const char *file,
- int line);
+void __mtx_assert(const volatile uintptr_t *c, int what, const char *file,
+ int line);
#else /* __rtems__ */
-#define _mtx_lock_spin_flags _mtx_lock_flags
-#define _mtx_unlock_spin_flags _mtx_unlock_flags
-#endif /* __rtems__ */
-#if defined(INVARIANTS) || defined(INVARIANT_SUPPORT)
void _mtx_assert(struct mtx *m, int what, const char *file, int line);
+#endif /* __rtems__ */
#endif
-void _thread_lock_flags(struct thread *, int, const char *, int);
-
-#define mtx_trylock_flags_(m, opts, file, line) \
- _mtx_trylock((m), (opts), (file), (line))
-
#ifndef __rtems__
-#define thread_lock_flags_(tdp, opts, file, line) \
- _thread_lock_flags((tdp), (opts), (file), (line))
+void thread_lock_flags_(struct thread *, int, const char *, int);
+
#define thread_lock(tdp) \
- _thread_lock_flags((tdp), 0, __FILE__, __LINE__)
+ thread_lock_flags_((tdp), 0, __FILE__, __LINE__)
#define thread_lock_flags(tdp, opt) \
- _thread_lock_flags((tdp), (opt), __FILE__, __LINE__)
+ thread_lock_flags_((tdp), (opt), __FILE__, __LINE__)
#define thread_unlock(tdp) \
mtx_unlock_spin((tdp)->td_lock)
-#else
+#else /* __rtems__ */
#define thread_lock(tdp)
#define thread_lock_flags(tdp, opt)
#define thread_unlock(tdp)
+#endif /* __rtems__ */
+
+#ifndef __rtems__
+/*
+ * Top-level macros to provide lock cookie once the actual mtx is passed.
+ * They will also prevent passing a malformed object to the mtx KPI by
+ * failing compilation as the mtx_lock reserved member will not be found.
+ */
+#define mtx_init(m, n, t, o) \
+ _mtx_init(&(m)->mtx_lock, n, t, o)
+#define mtx_destroy(m) \
+ _mtx_destroy(&(m)->mtx_lock)
+#define mtx_trylock_flags_(m, o, f, l) \
+ _mtx_trylock_flags_(&(m)->mtx_lock, o, f, l)
+#define _mtx_lock_sleep(m, t, o, f, l) \
+ __mtx_lock_sleep(&(m)->mtx_lock, t, o, f, l)
+#define _mtx_unlock_sleep(m, o, f, l) \
+ __mtx_unlock_sleep(&(m)->mtx_lock, o, f, l)
+#ifdef SMP
+#define _mtx_lock_spin(m, t, o, f, l) \
+ _mtx_lock_spin_cookie(&(m)->mtx_lock, t, o, f, l)
+#endif
+#define _mtx_lock_flags(m, o, f, l) \
+ __mtx_lock_flags(&(m)->mtx_lock, o, f, l)
+#define _mtx_unlock_flags(m, o, f, l) \
+ __mtx_unlock_flags(&(m)->mtx_lock, o, f, l)
+#define _mtx_lock_spin_flags(m, o, f, l) \
+ __mtx_lock_spin_flags(&(m)->mtx_lock, o, f, l)
+#define _mtx_trylock_spin_flags(m, o, f, l) \
+ __mtx_trylock_spin_flags(&(m)->mtx_lock, o, f, l)
+#define _mtx_unlock_spin_flags(m, o, f, l) \
+ __mtx_unlock_spin_flags(&(m)->mtx_lock, o, f, l)
+#if defined(INVARIANTS) || defined(INVARIANT_SUPPORT)
+#define _mtx_assert(m, w, f, l) \
+ __mtx_assert(&(m)->mtx_lock, w, f, l)
#endif
+#endif /* __rtems__ */
#define mtx_recurse lock_object.lo_data
@@ -165,11 +217,11 @@ void _thread_lock_flags(struct thread *, int, const char *, int);
#define __mtx_lock(mp, tid, opts, file, line) do { \
uintptr_t _tid = (uintptr_t)(tid); \
\
- if (!_mtx_obtain_lock((mp), _tid)) \
+ if (((mp)->mtx_lock != MTX_UNOWNED || !_mtx_obtain_lock((mp), _tid)))\
_mtx_lock_sleep((mp), _tid, (opts), (file), (line)); \
else \
- LOCKSTAT_PROFILE_OBTAIN_LOCK_SUCCESS(LS_MTX_LOCK_ACQUIRE, \
- mp, 0, 0, (file), (line)); \
+ LOCKSTAT_PROFILE_OBTAIN_LOCK_SUCCESS(adaptive__acquire, \
+ mp, 0, 0, file, line); \
} while (0)
/*
@@ -183,15 +235,30 @@ void _thread_lock_flags(struct thread *, int, const char *, int);
uintptr_t _tid = (uintptr_t)(tid); \
\
spinlock_enter(); \
- if (!_mtx_obtain_lock((mp), _tid)) { \
+ if (((mp)->mtx_lock != MTX_UNOWNED || !_mtx_obtain_lock((mp), _tid))) {\
if ((mp)->mtx_lock == _tid) \
(mp)->mtx_recurse++; \
else \
_mtx_lock_spin((mp), _tid, (opts), (file), (line)); \
} else \
- LOCKSTAT_PROFILE_OBTAIN_LOCK_SUCCESS(LS_MTX_SPIN_LOCK_ACQUIRE, \
- mp, 0, 0, (file), (line)); \
+ LOCKSTAT_PROFILE_OBTAIN_LOCK_SUCCESS(spin__acquire, \
+ mp, 0, 0, file, line); \
} while (0)
+#define __mtx_trylock_spin(mp, tid, opts, file, line) __extension__ ({ \
+ uintptr_t _tid = (uintptr_t)(tid); \
+ int _ret; \
+ \
+ spinlock_enter(); \
+ if (((mp)->mtx_lock != MTX_UNOWNED || !_mtx_obtain_lock((mp), _tid))) {\
+ spinlock_exit(); \
+ _ret = 0; \
+ } else { \
+ LOCKSTAT_PROFILE_OBTAIN_LOCK_SUCCESS(spin__acquire, \
+ mp, 0, 0, file, line); \
+ _ret = 1; \
+ } \
+ _ret; \
+})
#else /* SMP */
#define __mtx_lock_spin(mp, tid, opts, file, line) do { \
uintptr_t _tid = (uintptr_t)(tid); \
@@ -204,13 +271,29 @@ void _thread_lock_flags(struct thread *, int, const char *, int);
(mp)->mtx_lock = _tid; \
} \
} while (0)
+#define __mtx_trylock_spin(mp, tid, opts, file, line) __extension__ ({ \
+ uintptr_t _tid = (uintptr_t)(tid); \
+ int _ret; \
+ \
+ spinlock_enter(); \
+ if ((mp)->mtx_lock != MTX_UNOWNED) { \
+ spinlock_exit(); \
+ _ret = 0; \
+ } else { \
+ (mp)->mtx_lock = _tid; \
+ _ret = 1; \
+ } \
+ _ret; \
+})
#endif /* SMP */
/* Unlock a normal mutex. */
#define __mtx_unlock(mp, tid, opts, file, line) do { \
uintptr_t _tid = (uintptr_t)(tid); \
\
- if (!_mtx_release_lock((mp), _tid)) \
+ if ((mp)->mtx_recurse == 0) \
+ LOCKSTAT_PROFILE_RELEASE_LOCK(adaptive__release, mp); \
+ if ((mp)->mtx_lock != _tid || !_mtx_release_lock((mp), _tid)) \
_mtx_unlock_sleep((mp), (opts), (file), (line)); \
} while (0)
@@ -229,21 +312,19 @@ void _thread_lock_flags(struct thread *, int, const char *, int);
if (mtx_recursed((mp))) \
(mp)->mtx_recurse--; \
else { \
- LOCKSTAT_PROFILE_RELEASE_LOCK(LS_MTX_SPIN_UNLOCK_RELEASE, \
- mp); \
+ LOCKSTAT_PROFILE_RELEASE_LOCK(spin__release, mp); \
_mtx_release_lock_quick((mp)); \
- } \
- spinlock_exit(); \
+ } \
+ spinlock_exit(); \
} while (0)
#else /* SMP */
#define __mtx_unlock_spin(mp) do { \
if (mtx_recursed((mp))) \
(mp)->mtx_recurse--; \
else { \
- LOCKSTAT_PROFILE_RELEASE_LOCK(LS_MTX_SPIN_UNLOCK_RELEASE, \
- mp); \
+ LOCKSTAT_PROFILE_RELEASE_LOCK(spin__release, mp); \
(mp)->mtx_lock = MTX_UNOWNED; \
- } \
+ } \
spinlock_exit(); \
} while (0)
#endif /* SMP */
@@ -273,6 +354,10 @@ void _thread_lock_flags(struct thread *, int, const char *, int);
* mtx_trylock_flags(m, opts) is used the same way as mtx_trylock() but accepts
* relevant option flags `opts.'
*
+ * mtx_trylock_spin(m) attempts to acquire MTX_SPIN mutex `m' but doesn't
+ * spin if it cannot. Rather, it returns 0 on failure and non-zero on
+ * success. It always returns failure for recursed lock attempts.
+ *
* mtx_initialized(m) returns non-zero if the lock `m' has been initialized.
*
* mtx_owned(m) returns non-zero if the current thread owns the lock `m'
@@ -282,6 +367,7 @@ void _thread_lock_flags(struct thread *, int, const char *, int);
#define mtx_lock(m) mtx_lock_flags((m), 0)
#define mtx_lock_spin(m) mtx_lock_spin_flags((m), 0)
#define mtx_trylock(m) mtx_trylock_flags((m), 0)
+#define mtx_trylock_spin(m) mtx_trylock_spin_flags((m), 0)
#define mtx_unlock(m) mtx_unlock_flags((m), 0)
#define mtx_unlock_spin(m) mtx_unlock_spin_flags((m), 0)
@@ -301,12 +387,8 @@ struct mtx *mtx_pool_alloc(struct mtx_pool *pool);
mtx_unlock_spin(mtx_pool_find((pool), (ptr)))
/*
- * mtxpool_lockbuilder is a pool of sleep locks that is not witness
- * checked and should only be used for building higher level locks.
- *
* mtxpool_sleep is a general purpose pool of sleep mutexes.
*/
-extern struct mtx_pool *mtxpool_lockbuilder;
extern struct mtx_pool *mtxpool_sleep;
#ifndef LOCK_DEBUG
@@ -319,6 +401,8 @@ extern struct mtx_pool *mtxpool_sleep;
_mtx_unlock_flags((m), (opts), (file), (line))
#define mtx_lock_spin_flags_(m, opts, file, line) \
_mtx_lock_spin_flags((m), (opts), (file), (line))
+#define mtx_trylock_spin_flags_(m, opts, file, line) \
+ _mtx_trylock_spin_flags((m), (opts), (file), (line))
#define mtx_unlock_spin_flags_(m, opts, file, line) \
_mtx_unlock_spin_flags((m), (opts), (file), (line))
#else /* LOCK_DEBUG == 0 && !MUTEX_NOINLINE */
@@ -328,6 +412,8 @@ extern struct mtx_pool *mtxpool_sleep;
__mtx_unlock((m), curthread, (opts), (file), (line))
#define mtx_lock_spin_flags_(m, opts, file, line) \
__mtx_lock_spin((m), curthread, (opts), (file), (line))
+#define mtx_trylock_spin_flags_(m, opts, file, line) \
+ __mtx_trylock_spin((m), curthread, (opts), (file), (line))
#define mtx_unlock_spin_flags_(m, opts, file, line) \
__mtx_unlock_spin((m))
#endif /* LOCK_DEBUG > 0 || MUTEX_NOINLINE */
@@ -353,13 +439,16 @@ extern struct mtx_pool *mtxpool_sleep;
mtx_unlock_spin_flags_((m), (opts), LOCK_FILE, LOCK_LINE)
#define mtx_trylock_flags(m, opts) \
mtx_trylock_flags_((m), (opts), LOCK_FILE, LOCK_LINE)
+#define mtx_trylock_spin_flags(m, opts) \
+ mtx_trylock_spin_flags_((m), (opts), LOCK_FILE, LOCK_LINE)
#define mtx_assert(m, what) \
mtx_assert_((m), (what), __FILE__, __LINE__)
#define mtx_sleep(chan, mtx, pri, wmesg, timo) \
- _sleep((chan), &(mtx)->lock_object, (pri), (wmesg), (timo))
+ _sleep((chan), &(mtx)->lock_object, (pri), (wmesg), \
+ tick_sbt * (timo), 0, C_HARDCLOCK)
-#define mtx_initialized(m) lock_initalized(&(m)->lock_object)
+#define mtx_initialized(m) lock_initialized(&(m)->lock_object)
#ifndef __rtems__
#define mtx_owned(m) (((m)->mtx_lock & ~MTX_FLAGMASK) == (uintptr_t)curthread)
@@ -411,14 +500,8 @@ do { \
}
#endif
-#define UGAR(rval) do { \
- int _val = (rval); \
- mtx_unlock(&Giant); \
- return (_val); \
-} while (0)
-
struct mtx_args {
- struct mtx *ma_mtx;
+ void *ma_mtx;
const char *ma_desc;
int ma_opts;
};
@@ -432,7 +515,7 @@ struct mtx_args {
SYSINIT(name##_mtx_sysinit, SI_SUB_LOCK, SI_ORDER_MIDDLE, \
mtx_sysinit, &name##_args); \
SYSUNINIT(name##_mtx_sysuninit, SI_SUB_LOCK, SI_ORDER_MIDDLE, \
- mtx_destroy, (mtx))
+ _mtx_destroy, __DEVOLATILE(void *, &(mtx)->mtx_lock))
/*
* The INVARIANTS-enabled mtx_assert() functionality.
diff --git a/freebsd/sys/sys/nlist_aout.h b/freebsd/sys/sys/nlist_aout.h
index fc7a3c78..cb3dd859 100644
--- a/freebsd/sys/sys/nlist_aout.h
+++ b/freebsd/sys/sys/nlist_aout.h
@@ -56,8 +56,6 @@ struct nlist {
} n_un;
#else
const char *n_name; /* symbol name (in memory) */
- int : 8 * (sizeof(long) > sizeof(char *) ?
- sizeof(long) - sizeof(char *) : sizeof(char *) - sizeof(long));
#endif
unsigned char n_type; /* type defines */
char n_other; /* ".type" and binding information */
diff --git a/freebsd/sys/sys/osd.h b/freebsd/sys/sys/osd.h
index 14316ae3..c838e97d 100644
--- a/freebsd/sys/sys/osd.h
+++ b/freebsd/sys/sys/osd.h
@@ -59,6 +59,10 @@ int osd_register(u_int type, osd_destructor_t destructor,
void osd_deregister(u_int type, u_int slot);
int osd_set(u_int type, struct osd *osd, u_int slot, void *value);
+void **osd_reserve(u_int slot);
+int osd_set_reserved(u_int type, struct osd *osd, u_int slot, void **rsv,
+ void *value);
+void osd_free_reserved(void **rsv);
void *osd_get(u_int type, struct osd *osd, u_int slot);
void osd_del(u_int type, struct osd *osd, u_int slot);
int osd_call(u_int type, u_int method, void *obj, void *data);
@@ -71,6 +75,8 @@ void osd_exit(u_int type, struct osd *osd);
osd_deregister(OSD_THREAD, (slot))
#define osd_thread_set(td, slot, value) \
osd_set(OSD_THREAD, &(td)->td_osd, (slot), (value))
+#define osd_thread_set_reserved(td, slot, rsv, value) \
+ osd_set_reserved(OSD_THREAD, &(td)->td_osd, (slot), (rsv), (value))
#define osd_thread_get(td, slot) \
osd_get(OSD_THREAD, &(td)->td_osd, (slot))
#define osd_thread_del(td, slot) do { \
@@ -88,6 +94,8 @@ void osd_exit(u_int type, struct osd *osd);
osd_deregister(OSD_JAIL, (slot))
#define osd_jail_set(pr, slot, value) \
osd_set(OSD_JAIL, &(pr)->pr_osd, (slot), (value))
+#define osd_jail_set_reserved(pr, slot, rsv, value) \
+ osd_set_reserved(OSD_JAIL, &(pr)->pr_osd, (slot), (rsv), (value))
#define osd_jail_get(pr, slot) \
osd_get(OSD_JAIL, &(pr)->pr_osd, (slot))
#define osd_jail_del(pr, slot) \
diff --git a/freebsd/sys/sys/pcpu.h b/freebsd/sys/sys/pcpu.h
index ec3f9f94..2d3f3411 100644
--- a/freebsd/sys/sys/pcpu.h
+++ b/freebsd/sys/sys/pcpu.h
@@ -38,7 +38,11 @@
#endif
#include <sys/_cpuset.h>
+#include <sys/_lock.h>
+#include <sys/_mutex.h>
+#include <sys/_sx.h>
#include <sys/queue.h>
+#include <sys/_rmlock.h>
#include <sys/vmmeter.h>
#include <rtems/bsd/sys/resource.h>
#include <machine/pcpu.h>
@@ -141,15 +145,6 @@ extern uintptr_t dpcpu_off[];
#endif /* _KERNEL */
-/*
- * XXXUPS remove as soon as we have per cpu variable
- * linker sets and can define rm_queue in _rm_lock.h
- */
-struct rm_queue {
- struct rm_queue* volatile rmq_next;
- struct rm_queue* volatile rmq_prev;
-};
-
/*
* This structure maps out the global data that needs to be kept on a
* per-cpu basis. The members are accessed via the PCPU_GET/SET/PTR
@@ -157,6 +152,7 @@ struct rm_queue {
* defined in the PCPU_MD_FIELDS macro defined in <machine/pcpu.h>.
*/
struct pcpu {
+#ifndef __rtems__
struct thread *pc_curthread; /* Current thread */
struct thread *pc_idlethread; /* Idle thread */
struct thread *pc_fpcurthread; /* Fp state owner */
@@ -173,17 +169,9 @@ struct pcpu {
long pc_cp_time[CPUSTATES]; /* statclock ticks */
struct device *pc_device;
void *pc_netisr; /* netisr SWI cookie */
- int pc_dnweight; /* vm_page_dontneed() */
+ int pc_unused1; /* unused field */
int pc_domain; /* Memory domain. */
-
- /*
- * Stuff for read mostly lock
- *
- * XXXUPS remove as soon as we have per cpu variable
- * linker sets.
- */
- struct rm_queue pc_rm_queue;
-
+ struct rm_queue pc_rm_queue; /* rmlock list of trackers */
uintptr_t pc_dynamic; /* Dynamic per-cpu data area */
/*
@@ -197,8 +185,19 @@ struct pcpu {
* if only to make kernel debugging easier.
*/
PCPU_MD_FIELDS;
+#else /* __rtems__ */
+ int pc_dummy;
+#endif /* __rtems__ */
} __aligned(CACHE_LINE_SIZE);
+#ifdef CTASSERT
+/*
+ * To minimize memory waste in per-cpu UMA zones, size of struct pcpu
+ * should be denominator of PAGE_SIZE.
+ */
+CTASSERT((PAGE_SIZE / sizeof(struct pcpu)) * sizeof(struct pcpu) == PAGE_SIZE);
+#endif
+
#ifdef _KERNEL
STAILQ_HEAD(cpuhead, pcpu);
@@ -213,6 +212,25 @@ extern struct pcpu *cpuid_to_pcpu[];
#endif
#define curvidata PCPU_GET(vidata)
+/* Accessor to elements allocated via UMA_ZONE_PCPU zone. */
+static inline void *
+zpcpu_get(void *base)
+{
+
+#ifndef __rtems__
+ return ((char *)(base) + sizeof(struct pcpu) * curcpu);
+#else /* __rtems__ */
+ return ((char *)(base) + sizeof(struct pcpu) * _SMP_Get_current_processor());
+#endif /* __rtems__ */
+}
+
+static inline void *
+zpcpu_get_cpu(void *base, int cpu)
+{
+
+ return ((char *)(base) + sizeof(struct pcpu) * cpu);
+}
+
/*
* Machine dependent callouts. cpu_pcpu_init() is responsible for
* initializing machine dependent fields of struct pcpu, and
diff --git a/freebsd/sys/sys/pipe.h b/freebsd/sys/sys/pipe.h
index c59ecc75..d596b3bb 100755
--- a/freebsd/sys/sys/pipe.h
+++ b/freebsd/sys/sys/pipe.h
@@ -54,9 +54,12 @@
#define PIPENPAGES (BIG_PIPE_SIZE / PAGE_SIZE + 1)
/*
- * See sys_pipe.c for info on what these limits mean.
+ * See sys_pipe.c for info on what these limits mean.
*/
extern long maxpipekva;
+#ifndef __rtems__
+extern struct fileops pipeops;
+#endif /* __rtems__ */
/*
* Pipe buffer information.
@@ -96,6 +99,7 @@ struct pipemapping {
#define PIPE_LWANT 0x200 /* Process wants exclusive access to pointers/data. */
#define PIPE_DIRECTW 0x400 /* Pipe direct write active. */
#define PIPE_DIRECTOK 0x800 /* Direct mode ok. */
+#define PIPE_NAMED 0x1000 /* Is a named pipe. */
/*
* Per-pipe data structure.
@@ -114,6 +118,7 @@ struct pipe {
u_int pipe_state; /* pipe status info */
int pipe_busy; /* busy flag, mostly to handle rundown sanely */
int pipe_present; /* still present? */
+ int pipe_wgen; /* writer generation for named pipe */
ino_t pipe_ino; /* fake inode for stat(2) */
};
@@ -140,5 +145,7 @@ struct pipepair {
#define PIPE_UNLOCK(pipe) mtx_unlock(PIPE_MTX(pipe))
#define PIPE_LOCK_ASSERT(pipe, type) mtx_assert(PIPE_MTX(pipe), (type))
-
+void pipe_dtor(struct pipe *dpipe);
+void pipe_named_ctor(struct pipe **ppipe, struct thread *td);
+void pipeselwakeup(struct pipe *cpipe);
#endif /* !_SYS_PIPE_H_ */
diff --git a/freebsd/sys/sys/priv.h b/freebsd/sys/sys/priv.h
index 1d1e8f20..ec0943aa 100644
--- a/freebsd/sys/sys/priv.h
+++ b/freebsd/sys/sys/priv.h
@@ -45,8 +45,9 @@
* loadable kernel module ABI, and should not be changed across minor
* releases.
*
- * When adding a new privilege, remember to determine if it's appropriate for
- * use in jail, and update the privilege switch in kern_jail.c as necessary.
+ * When adding a new privilege, remember to determine if it's appropriate
+ * for use in jail, and update the privilege switch in prison_priv_check()
+ * in kern_jail.c as necessary.
*/
/*
@@ -111,6 +112,7 @@
#define PRIV_DEBUG_DIFFCRED 80 /* Exempt debugging other users. */
#define PRIV_DEBUG_SUGID 81 /* Exempt debugging setuid proc. */
#define PRIV_DEBUG_UNPRIV 82 /* Exempt unprivileged debug limit. */
+#define PRIV_DEBUG_DENIED 83 /* Exempt P2_NOTRACE. */
/*
* Dtrace privileges.
@@ -132,7 +134,7 @@
#define PRIV_JAIL_REMOVE 112 /* Remove a jail. */
/*
- * Kernel environment priveleges.
+ * Kernel environment privileges.
*/
#define PRIV_KENV_SET 120 /* Set kernel env. variables. */
#define PRIV_KENV_UNSET 121 /* Unset kernel env. variables. */
@@ -158,7 +160,8 @@
#define PRIV_PROC_SETRLIMIT 162 /* Can raise resources limits. */
#define PRIV_PROC_SETLOGINCLASS 163 /* Can call setloginclass(2). */
-/* System V IPC privileges.
+/*
+ * System V IPC privileges.
*/
#define PRIV_IPC_READ 170 /* Can override IPC read perm. */
#define PRIV_IPC_WRITE 171 /* Can override IPC write perm. */
@@ -338,6 +341,8 @@
#define PRIV_NET_SETIFVNET 417 /* Move interface to vnet. */
#define PRIV_NET_SETIFDESCR 418 /* Set interface description. */
#define PRIV_NET_SETIFFIB 419 /* Set interface fib. */
+#define PRIV_NET_VXLAN 420 /* Administer vxlan. */
+#define PRIV_NET_SETVLANPCP 421 /* Set VLAN priority. */
/*
* 802.11-related privileges.
@@ -346,9 +351,9 @@
#define PRIV_NET80211_MANAGE 441 /* Administer 802.11. */
/*
- * AppleTalk privileges.
+ * Placeholder for AppleTalk privileges, not supported anymore.
*/
-#define PRIV_NETATALK_RESERVEDPORT 450 /* Bind low port number. */
+#define _PRIV_NETATALK_RESERVEDPORT 450 /* Bind low port number. */
/*
* ATM privileges.
@@ -389,12 +394,13 @@
#define PRIV_NETINET_REUSEPORT 504 /* Allow [rapid] port/address reuse. */
#define PRIV_NETINET_SETHDROPTS 505 /* Set certain IPv4/6 header options. */
#define PRIV_NETINET_BINDANY 506 /* Allow bind to any address. */
+#define PRIV_NETINET_HASHKEY 507 /* Get and set hash keys for IPv4/6. */
/*
- * IPX/SPX privileges.
+ * Placeholders for IPX/SPX privileges, not supported any more.
*/
-#define PRIV_NETIPX_RESERVEDPORT 520 /* Bind low port number. */
-#define PRIV_NETIPX_RAW 521 /* Open netipx raw socket. */
+#define _PRIV_NETIPX_RESERVEDPORT 520 /* Bind low port number. */
+#define _PRIV_NETIPX_RAW 521 /* Open netipx raw socket. */
/*
* NCP privileges.
@@ -494,9 +500,15 @@
#define PRIV_RCTL_REMOVE_RULE 674
/*
+ * mem(4) privileges.
+ */
+#define PRIV_KMEM_READ 680 /* Open mem/kmem for reading. */
+#define PRIV_KMEM_WRITE 681 /* Open mem/kmem for writing. */
+
+/*
* Track end of privilege list.
*/
-#define _PRIV_HIGHEST 675
+#define _PRIV_HIGHEST 682
/*
* Validate that a named privilege is known by the privilege system. Invalid
diff --git a/freebsd/sys/sys/proc.h b/freebsd/sys/sys/proc.h
index e866552c..4a695ef9 100644
--- a/freebsd/sys/sys/proc.h
+++ b/freebsd/sys/sys/proc.h
@@ -63,6 +63,7 @@
#endif
#include <sys/ucontext.h>
#include <sys/ucred.h>
+#include <sys/_vm_domain.h>
#include <machine/proc.h> /* Machine-dependent proc substruct. */
/*
@@ -148,6 +149,8 @@ struct pargs {
* q - td_contested lock
* r - p_peers lock
* t - thread lock
+ * u - process stat lock
+ * w - process timer lock
* x - created at fork, only changes during single threading in exec
* y - created at first aio, doesn't change until exit or exec at which
* point we are single-threaded and only curthread changes it
@@ -158,6 +161,8 @@ struct pargs {
* for write access.
*/
struct cpuset;
+struct filecaps;
+struct filemon;
struct kaioinfo;
struct kaudit_record;
struct kdtrace_proc;
@@ -170,6 +175,7 @@ struct procdesc;
struct racct;
struct sbuf;
struct sleepqueue;
+struct syscall_args;
struct td_sched;
struct thread;
struct trapframe;
@@ -183,14 +189,14 @@ struct turnstile;
* userland asks for rusage info. Backwards compatibility prevents putting
* this directly in the user-visible rusage struct.
*
- * Locking for p_rux: (cj) means (j) for p_rux and (c) for p_crux.
+ * Locking for p_rux: (cu) means (u) for p_rux and (c) for p_crux.
* Locking for td_rux: (t) for all fields.
*/
struct rusage_ext {
- uint64_t rux_runtime; /* (cj) Real time. */
- uint64_t rux_uticks; /* (cj) Statclock hits in user mode. */
- uint64_t rux_sticks; /* (cj) Statclock hits in sys mode. */
- uint64_t rux_iticks; /* (cj) Statclock hits in intr mode. */
+ uint64_t rux_runtime; /* (cu) Real time. */
+ uint64_t rux_uticks; /* (cu) Statclock hits in user mode. */
+ uint64_t rux_sticks; /* (cu) Statclock hits in sys mode. */
+ uint64_t rux_iticks; /* (cu) Statclock hits in intr mode. */
uint64_t rux_uu; /* (c) Previous user time in usec. */
uint64_t rux_su; /* (c) Previous sys time in usec. */
uint64_t rux_tu; /* (c) Previous total time in usec. */
@@ -235,7 +241,9 @@ struct thread {
struct sleepqueue *td_sleepqueue; /* (k) Associated sleep queue. */
#ifndef __rtems__
struct turnstile *td_turnstile; /* (k) Associated turnstile. */
+ struct rl_q_entry *td_rlqe; /* (k) Associated range lock entry. */
struct umtx_q *td_umtxq; /* (c?) Link for when we're blocked. */
+ struct vm_domain_policy td_vm_dom_policy; /* (c) current numa domain policy */
lwpid_t td_tid; /* (b) Thread ID. */
sigqueue_t td_sigqueue; /* (c) Sigs arrived, not delivered. */
#define td_siglist td_sigqueue.sq_signals
@@ -255,11 +263,9 @@ struct thread {
void *td_wchan; /* (t) Sleep address. */
const char *td_wmesg; /* (t) Reason for sleep. */
#ifndef __rtems__
- u_char td_lastcpu; /* (t) Last cpu we were on. */
- u_char td_oncpu; /* (t) Which cpu we are on. */
volatile u_char td_owepreempt; /* (k*) Preempt on last critical_exit */
u_char td_tsqueue; /* (t) Turnstile queue blocked on. */
- short td_locks; /* (k) Count of non-spin locks. */
+ short td_locks; /* (k) Debug: count of non-spin locks */
short td_rw_rlocks; /* (k) Count of rwlock read locks. */
short td_lk_slocks; /* (k) Count of lockmgr shared locks. */
short td_stopsched; /* (k) Scheduler stopped. */
@@ -272,10 +278,12 @@ struct thread {
#endif /* __rtems__ */
struct ucred *td_ucred; /* (k) Reference to credentials. */
#ifndef __rtems__
+ struct plimit *td_limit; /* (k) Resource limits. */
u_int td_estcpu; /* (t) estimated cpu utilization */
int td_slptick; /* (t) Time at sleep. */
int td_blktick; /* (t) Time spent blocked. */
int td_swvoltick; /* (t) Time at last SW_VOL switch. */
+ int td_swinvoltick; /* (t) Time at last SW_INVOL switch. */
u_int td_cow; /* (*) Number of copy-on-write faults */
struct rusage td_ru; /* (t) rusage information. */
struct rusage_ext td_rux; /* (t) Internal rusage information. */
@@ -287,7 +295,6 @@ struct thread {
u_int td_uticks; /* (t) Statclock hits in user mode. */
int td_intrval; /* (t) Return value for sleepq. */
sigset_t td_oldsigmask; /* (k) Saved mask from pre sigpause. */
- sigset_t td_sigmask; /* (c) Current signal mask. */
volatile u_int td_generation; /* (k) For detection of preemption */
stack_t td_sigstk; /* (k) Stack ptr and on-stack flag. */
int td_xsig; /* (c) Signal for ptrace */
@@ -301,20 +308,31 @@ struct thread {
struct osd td_osd; /* (k) Object specific data. */
struct vm_map_entry *td_map_def_user; /* (k) Deferred entries. */
pid_t td_dbg_forked; /* (c) Child pid for debugger. */
-#define td_endzero td_rqindex
+ u_int td_vp_reserv; /* (k) Count of reserved vnodes. */
+ int td_no_sleeping; /* (k) Sleeping disabled count. */
+ int td_dom_rr_idx; /* (k) RR Numa domain selection. */
+ void *td_su; /* (k) FFS SU private */
+ sbintime_t td_sleeptimo; /* (t) Sleep timeout. */
+#define td_endzero td_sigmask
-/* Copied during fork1() or thread_sched_upcall(). */
+/* Copied during fork1() or create_thread(). */
#define td_startcopy td_endzero
+ sigset_t td_sigmask; /* (c) Current signal mask. */
u_char td_rqindex; /* (t) Run queue index. */
u_char td_base_pri; /* (t) Thread base kernel priority. */
u_char td_priority; /* (t) Thread active priority. */
u_char td_pri_class; /* (t) Scheduling class. */
u_char td_user_pri; /* (t) User pri from estcpu and nice. */
u_char td_base_user_pri; /* (t) Base user pri */
+ u_int td_dbg_sc_code; /* (c) Syscall code to debugger. */
+ u_int td_dbg_sc_narg; /* (c) Syscall arg count to debugger.*/
+ uintptr_t td_rb_list; /* (k) Robust list head. */
+ uintptr_t td_rbp_list; /* (k) Robust priv list head. */
+ uintptr_t td_rb_inact; /* (k) Current in-action mutex loc. */
#define td_endcopy td_pcb
/*
- * Fields that must be manually set in fork1() or thread_sched_upcall()
+ * Fields that must be manually set in fork1() or create_thread()
* or already have been set in the allocator, constructor, etc.
*/
struct pcb *td_pcb; /* (k) Kernel VA of pcb and kstack. */
@@ -325,9 +343,16 @@ struct thread {
TDS_RUNQ,
TDS_RUNNING
} td_state; /* (t) thread state */
-#endif /* __rtems__ */
+ union {
+ register_t tdu_retval[2];
+ off_t tdu_off;
+ } td_uretoff; /* (k) Syscall aux returns. */
+#else /* __rtems__ */
register_t td_retval[2]; /* (k) Syscall aux returns. */
+#endif /* __rtems__ */
#ifndef __rtems__
+#define td_retval td_uretoff.tdu_retval
+ u_int td_cowgen; /* (k) Generation of COW pointers. */
struct callout td_slpcallout; /* (h) Callout for sleep. */
struct trapframe *td_frame; /* (k) */
struct vm_object *td_kstack_obj;/* (a) Kstack object. */
@@ -335,7 +360,6 @@ struct thread {
int td_kstack_pages; /* (a) Size of the kstack. */
volatile u_int td_critnest; /* (k*) Critical section nest level. */
struct mdthread td_md; /* (k) Any machine-dependent fields. */
- struct td_sched *td_sched; /* (*) Scheduler-specific data. */
struct kaudit_record *td_ar; /* (k) Active audit record, if any. */
struct lpohead td_lprof[2]; /* (a) lock profiling objects. */
struct kdtrace_thread *td_dtrace; /* (*) DTrace-specific data. */
@@ -346,11 +370,17 @@ struct thread {
struct proc *td_rfppwait_p; /* (k) The vforked child */
struct vm_page **td_ma; /* (k) uio pages held */
int td_ma_cnt; /* (k) size of *td_ma */
- struct rl_q_entry *td_rlqe; /* (k) Associated range lock entry. */
- u_int td_vp_reserv; /* (k) Count of reserved vnodes. */
+ void *td_emuldata; /* Emulator state data */
+ int td_lastcpu; /* (t) Last cpu we were on. */
+ int td_oncpu; /* (t) Which cpu we are on. */
#endif /* __rtems__ */
};
+struct thread0_storage {
+ struct thread t0st_thread;
+ uint64_t t0st_sched[10];
+};
+
struct mtx *thread_lock_block(struct thread *);
void thread_lock_unblock(struct thread *, struct mtx *);
void thread_lock_set(struct thread *, struct mtx *);
@@ -372,12 +402,15 @@ do { \
KASSERT((__m == &blocked_lock || __m == (lock)), \
("Thread %p lock %p does not match %p", td, __m, (lock))); \
} while (0)
+
+#define TD_LOCKS_INC(td) ((td)->td_locks++)
+#define TD_LOCKS_DEC(td) ((td)->td_locks--)
#else
#define THREAD_LOCKPTR_ASSERT(td, lock)
-#endif
-#define CRITICAL_ASSERT(td) \
- KASSERT((td)->td_critnest >= 1, ("Not in critical section"));
+#define TD_LOCKS_INC(td)
+#define TD_LOCKS_DEC(td)
+#endif
/*
* Flags kept in td_flags:
@@ -392,19 +425,19 @@ do { \
#define TDF_CANSWAP 0x00000040 /* Thread can be swapped. */
#define TDF_SLEEPABORT 0x00000080 /* sleepq_abort was called. */
#define TDF_KTH_SUSP 0x00000100 /* kthread is suspended */
-#define TDF_UNUSED09 0x00000200 /* --available-- */
+#define TDF_ALLPROCSUSP 0x00000200 /* suspended by SINGLE_ALLPROC */
#define TDF_BOUNDARY 0x00000400 /* Thread suspended at user boundary */
#define TDF_ASTPENDING 0x00000800 /* Thread has some asynchronous events. */
-#define TDF_TIMOFAIL 0x00001000 /* Timeout from sleep after we were awake. */
+#define TDF_UNUSED12 0x00001000 /* --available-- */
#define TDF_SBDRY 0x00002000 /* Stop only on usermode boundary. */
#define TDF_UPIBLOCKED 0x00004000 /* Thread blocked on user PI mutex. */
#define TDF_NEEDSUSPCHK 0x00008000 /* Thread may need to suspend. */
#define TDF_NEEDRESCHED 0x00010000 /* Thread needs to yield. */
#define TDF_NEEDSIGCHK 0x00020000 /* Thread may need signal delivery. */
#define TDF_NOLOAD 0x00040000 /* Ignore during load avg calculations. */
-#define TDF_UNUSED19 0x00080000 /* --available-- */
+#define TDF_SERESTART 0x00080000 /* ERESTART on stop attempts. */
#define TDF_THRWAKEUP 0x00100000 /* Libthr thread must not suspend itself. */
-#define TDF_UNUSED21 0x00200000 /* --available-- */
+#define TDF_SEINTR 0x00200000 /* EINTR on stop attempts. */
#define TDF_SWAPINREQ 0x00400000 /* Swapin request due to wakeup. */
#define TDF_UNUSED23 0x00800000 /* --available-- */
#define TDF_SCHED0 0x01000000 /* Reserved for scheduler private use */
@@ -427,6 +460,10 @@ do { \
#define TDB_STOPATFORK 0x00000080 /* Stop at the return from fork (child
only) */
#define TDB_CHILD 0x00000100 /* New child indicator for ptrace() */
+#define TDB_BORN 0x00000200 /* New LWP indicator for ptrace() */
+#define TDB_EXIT 0x00000400 /* Exiting LWP indicator for ptrace() */
+#define TDB_VFORK 0x00000800 /* vfork indicator for ptrace() */
+#define TDB_FSTP 0x00001000 /* The thread is PT_ATTACH leader */
/*
* "Private" flags kept in td_pflags:
@@ -438,9 +475,9 @@ do { \
#define TDP_BUFNEED 0x00000008 /* Do not recurse into the buf flush */
#define TDP_COWINPROGRESS 0x00000010 /* Snapshot copy-on-write in progress. */
#define TDP_ALTSTACK 0x00000020 /* Have alternate signal stack. */
-#define TDP_DEADLKTREAT 0x00000040 /* Lock aquisition - deadlock treatment. */
+#define TDP_DEADLKTREAT 0x00000040 /* Lock acquisition - deadlock treatment. */
#define TDP_NOFAULTING 0x00000080 /* Do not handle page faults. */
-#define TDP_NOSLEEPING 0x00000100 /* Thread is not allowed to sleep on a sq. */
+#define TDP_UNUSED9 0x00000100 /* --available-- */
#define TDP_OWEUPC 0x00000200 /* Call addupc() at next AST. */
#define TDP_ITHREAD 0x00000400 /* Thread is an interrupt thread. */
#define TDP_SYNCIO 0x00000800 /* Local override, disable async i/o. */
@@ -461,7 +498,7 @@ do { \
#define TDP_RESETSPUR 0x04000000 /* Reset spurious page fault history. */
#define TDP_NERRNO 0x08000000 /* Last errno is already in td_errno */
#define TDP_UIOHELD 0x10000000 /* Current uio has pages held in td_ma */
-#define TDP_DEVMEMIO 0x20000000 /* Accessing memory for /dev/mem */
+#define TDP_FORKING 0x20000000 /* Thread is being created through fork() */
#define TDP_EXECVMSPC 0x40000000 /* Execve destroyed old vmspace */
/*
@@ -520,6 +557,11 @@ do { \
#define TD_SET_RUNQ(td) (td)->td_state = TDS_RUNQ
#define TD_SET_CAN_RUN(td) (td)->td_state = TDS_CAN_RUN
+#define TD_SBDRY_INTR(td) \
+ (((td)->td_flags & (TDF_SEINTR | TDF_SERESTART)) != 0)
+#define TD_SBDRY_ERRNO(td) \
+ (((td)->td_flags & TDF_SEINTR) != 0 ? EINTR : ERESTART)
+
/*
* Process structure.
*/
@@ -532,7 +574,7 @@ struct proc {
struct filedesc *p_fd; /* (b) Open files. */
struct filedesc_to_leader *p_fdtol; /* (b) Tracking node */
struct pstats *p_stats; /* (b) Accounting/statistics (CPU). */
- struct plimit *p_limit; /* (c) Process limits. */
+ struct plimit *p_limit; /* (c) Resource limits. */
struct callout p_limco; /* (c) Limit callout handle */
struct sigacts *p_sigacts; /* (x) Signal actions, state (CPU). */
@@ -549,7 +591,15 @@ struct proc {
struct proc *p_pptr; /* (c + e) Pointer to parent process. */
LIST_ENTRY(proc) p_sibling; /* (e) List of sibling processes. */
LIST_HEAD(, proc) p_children; /* (e) Pointer to list of children. */
+ struct proc *p_reaper; /* (e) My reaper. */
+ LIST_HEAD(, proc) p_reaplist; /* (e) List of my descendants
+ (if I am reaper). */
+ LIST_ENTRY(proc) p_reapsibling; /* (e) List of siblings - descendants of
+ the same reaper. */
struct mtx p_mtx; /* (n) Lock for this struct. */
+ struct mtx p_statmtx; /* Lock for the stats */
+ struct mtx p_itimmtx; /* Lock for the virt/prof timers */
+ struct mtx p_profmtx; /* Lock for the profiling */
struct ksiginfo *p_ksi; /* Locked by parent proc lock */
sigqueue_t p_sigqueue; /* (c) Sigs not delivered to a td. */
#define p_siglist p_sigqueue.sq_signals
@@ -557,12 +607,12 @@ struct proc {
/* The following fields are all zeroed upon creation in fork. */
#define p_startzero p_oppid
pid_t p_oppid; /* (c + e) Save ppid in ptrace. XXX */
- int p_pad_dbg_child;
struct vmspace *p_vmspace; /* (b) Address space. */
u_int p_swtick; /* (c) Tick when swapped in or out. */
+ u_int p_cowgen; /* (c) Generation of COW pointers. */
struct itimerval p_realtimer; /* (c) Alarm timer. */
struct rusage p_ru; /* (a) Exit information. */
- struct rusage_ext p_rux; /* (cj) Internal resource usage. */
+ struct rusage_ext p_rux; /* (cu) Internal resource usage. */
struct rusage_ext p_crux; /* (c) Internal child resource usage. */
int p_profthreads; /* (c) Num threads in addupc_task. */
volatile int p_exitthreads; /* (j) Number of threads exiting */
@@ -579,6 +629,7 @@ struct proc {
u_int p_stype; /* (c) Stop event type. */
char p_step; /* (c) Process is stopped. */
u_char p_pfsflags; /* (c) Procfs flags. */
+ u_int p_ptevents; /* (c) ptrace() event mask. */
struct nlminfo *p_nlminfo; /* (?) Only used by/for lockd. */
struct kaioinfo *p_aioinfo; /* (y) ASYNC I/O info. */
struct thread *p_singlethread;/* (c + j) If single threading this is it */
@@ -588,6 +639,9 @@ struct proc {
int p_pendingcnt; /* how many signals are pending */
struct itimers *p_itimers; /* (c) POSIX interval timers. */
struct procdesc *p_procdesc; /* (e) Process descriptor, if any. */
+ u_int p_treeflag; /* (e) P_TREE flags */
+ int p_pendingexits; /* (c) Count of pending thread exits. */
+ struct filemon *p_filemon; /* (c) filemon-specific data. */
/* End area that is zeroed on creation. */
#define p_endzero p_magic
@@ -596,18 +650,21 @@ struct proc {
u_int p_magic; /* (b) Magic number. */
int p_osrel; /* (x) osreldate for the
binary (from ELF note, if any) */
- char p_comm[MAXCOMLEN + 1]; /* (b) Process name. */
- struct pgrp *p_pgrp; /* (c + e) Pointer to process group. */
+ char p_comm[MAXCOMLEN + 1]; /* (x) Process name. */
struct sysentvec *p_sysent; /* (b) Syscall dispatch info. */
struct pargs *p_args; /* (c) Process arguments. */
rlim_t p_cpulimit; /* (c) Current CPU limit in seconds. */
signed char p_nice; /* (c) Process "nice" value. */
int p_fibnum; /* in this routing domain XXX MRT */
+ pid_t p_reapsubtree; /* (e) Pid of the direct child of the
+ reaper which spawned
+ our subtree. */
+ u_int p_xexit; /* (c) Exit code. */
+ u_int p_xsig; /* (c) Stop/kill sig. */
/* End area that is copied on creation. */
-#define p_endcopy p_xstat
-
- u_short p_xstat; /* (c) Exit status; also stop sig. */
- struct knlist p_klist; /* (c) Knotes attached to this proc. */
+#define p_endcopy p_xsig
+ struct pgrp *p_pgrp; /* (c + e) Pointer to process group. */
+ struct knlist *p_klist; /* (c) Knotes attached to this proc. */
int p_numthreads; /* (c) Number of threads. */
struct mdproc p_md; /* Any machine-dependent fields. */
struct callout p_itcallout; /* (h + c) Interval timer callout. */
@@ -616,7 +673,6 @@ struct proc {
struct proc *p_leader; /* (b) */
void *p_emuldata; /* (c) Emulator state data. */
struct label *p_label; /* (*) Proc (not subject) MAC label. */
- struct p_sched *p_sched; /* (*) Scheduler-specific data. */
STAILQ_HEAD(, ktr_request) p_ktr; /* (o) KTR event queue. */
LIST_HEAD(, mqueue_notifier) p_mqnotifier; /* (c) mqueue notifiers.*/
struct kdtrace_proc *p_dtrace; /* (*) DTrace-specific data. */
@@ -625,6 +681,8 @@ struct proc {
after fork. */
uint64_t p_prev_runtime; /* (c) Resource usage accounting. */
struct racct *p_racct; /* (b) Resource accounting. */
+ int p_throttled; /* (c) Flag for racct pcpu throttling */
+ struct vm_domain_policy p_vm_dom_policy; /* (c) process default VM domain, or -1 */
/*
* An orphan is the child that has beed re-parented to the
* debugger as a result of attaching to it. Need to keep
@@ -633,24 +691,37 @@ struct proc {
*/
LIST_ENTRY(proc) p_orphan; /* (e) List of orphan processes. */
LIST_HEAD(, proc) p_orphans; /* (e) Pointer to list of orphans. */
- u_char p_throttled; /* (c) Flag for racct pcpu throttling */
#endif /* __rtems__ */
};
#define p_session p_pgrp->pg_session
#define p_pgid p_pgrp->pg_id
-#define NOCPU 0xff /* For when we aren't on a CPU. */
+#define NOCPU (-1) /* For when we aren't on a CPU. */
+#define NOCPU_OLD (255)
+#define MAXCPU_OLD (254)
#define PROC_SLOCK(p) mtx_lock_spin(&(p)->p_slock)
#define PROC_SUNLOCK(p) mtx_unlock_spin(&(p)->p_slock)
#define PROC_SLOCK_ASSERT(p, type) mtx_assert(&(p)->p_slock, (type))
+#define PROC_STATLOCK(p) mtx_lock_spin(&(p)->p_statmtx)
+#define PROC_STATUNLOCK(p) mtx_unlock_spin(&(p)->p_statmtx)
+#define PROC_STATLOCK_ASSERT(p, type) mtx_assert(&(p)->p_statmtx, (type))
+
+#define PROC_ITIMLOCK(p) mtx_lock_spin(&(p)->p_itimmtx)
+#define PROC_ITIMUNLOCK(p) mtx_unlock_spin(&(p)->p_itimmtx)
+#define PROC_ITIMLOCK_ASSERT(p, type) mtx_assert(&(p)->p_itimmtx, (type))
+
+#define PROC_PROFLOCK(p) mtx_lock_spin(&(p)->p_profmtx)
+#define PROC_PROFUNLOCK(p) mtx_unlock_spin(&(p)->p_profmtx)
+#define PROC_PROFLOCK_ASSERT(p, type) mtx_assert(&(p)->p_profmtx, (type))
+
/* These flags are kept in p_flag. */
#define P_ADVLOCK 0x00001 /* Process may hold a POSIX advisory lock. */
#define P_CONTROLT 0x00002 /* Has a controlling terminal. */
-#define P_KTHREAD 0x00004 /* Kernel thread (*). */
-#define P_FOLLOWFORK 0x00008 /* Attach parent debugger to children. */
+#define P_KPROC 0x00004 /* Kernel process. */
+#define P_UNUSED3 0x00008 /* --available-- */
#define P_PPWAIT 0x00010 /* Parent is waiting for child to exec/exit. */
#define P_PROFIL 0x00020 /* Has started profiling. */
#define P_STOPPROF 0x00040 /* Has thread requesting to stop profiling. */
@@ -672,7 +743,7 @@ struct proc {
#define P_SINGLE_BOUNDARY 0x400000 /* Threads should suspend at user boundary. */
#define P_HWPMC 0x800000 /* Process is using HWPMCs */
#define P_JAILED 0x1000000 /* Process is in jail. */
-#define P_ORPHAN 0x2000000 /* Orphaned. */
+#define P_TOTAL_STOP 0x2000000 /* Stopped in stop_all_proc. */
#define P_INEXEC 0x4000000 /* Process is in execve(). */
#define P_STATCHILD 0x8000000 /* Child process stopped or exited. */
#define P_INMEM 0x10000000 /* Loaded into memory. */
@@ -686,6 +757,16 @@ struct proc {
/* These flags are kept in p_flag2. */
#define P2_INHERIT_PROTECTED 0x00000001 /* New children get P_PROTECTED. */
+#define P2_NOTRACE 0x00000002 /* No ptrace(2) attach or coredumps. */
+#define P2_NOTRACE_EXEC 0x00000004 /* Keep P2_NOPTRACE on exec(2). */
+#define P2_AST_SU 0x00000008 /* Handles SU ast for kthreads. */
+#define P2_PTRACE_FSTP 0x00000010 /* SIGSTOP from PT_ATTACH not yet handled. */
+
+/* Flags protected by proctree_lock, kept in p_treeflags. */
+#define P_TREE_ORPHANED 0x00000001 /* Reparented, on orphan list */
+#define P_TREE_FIRST_ORPHAN 0x00000002 /* First element of orphan
+ list */
+#define P_TREE_REAPER 0x00000004 /* Reaper of subtree */
/*
* These were process status values (p_stat), now they are only used in
@@ -707,7 +788,7 @@ struct proc {
#define SW_TYPE_MASK 0xff /* First 8 bits are switch type */
#define SWT_NONE 0 /* Unspecified switch. */
#define SWT_PREEMPT 1 /* Switching due to preemption. */
-#define SWT_OWEPREEMPT 2 /* Switching due to opepreempt. */
+#define SWT_OWEPREEMPT 2 /* Switching due to owepreempt. */
#define SWT_TURNSTILE 3 /* Turnstile contention. */
#define SWT_SLEEPQ 4 /* Sleepq wait. */
#define SWT_SLEEPQTIMO 5 /* Sleepq timeout wait. */
@@ -728,6 +809,7 @@ struct proc {
#define SINGLE_NO_EXIT 0
#define SINGLE_EXIT 1
#define SINGLE_BOUNDARY 2
+#define SINGLE_ALLPROC 3
#ifdef MALLOC_DECLARE
MALLOC_DECLARE(M_PARGS);
@@ -755,6 +837,8 @@ extern pid_t pid_max;
#define STOPEVENT(p, e, v) do { \
+ WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL, \
+ "checking stopevent %d", (e)); \
if ((p)->p_stops & (e)) { \
PROC_LOCK(p); \
stopevent((p), (e), (v)); \
@@ -797,8 +881,21 @@ extern pid_t pid_max;
#define SESS_LOCKED(s) mtx_owned(&(s)->s_mtx)
#define SESS_LOCK_ASSERT(s, type) mtx_assert(&(s)->s_mtx, (type))
+/*
+ * Non-zero p_lock ensures that:
+ * - exit1() is not performed until p_lock reaches zero;
+ * - the process' threads stack are not swapped out if they are currently
+ * not (P_INMEM).
+ *
+ * PHOLD() asserts that the process (except the current process) is
+ * not exiting, increments p_lock and swaps threads stacks into memory,
+ * if needed.
+ * _PHOLD() is same as PHOLD(), it takes the process locked.
+ * _PHOLD_LITE() also takes the process locked, but comparing with
+ * _PHOLD(), it only guarantees that exit1() is not executed,
+ * faultin() is not called.
+ */
#ifndef __rtems__
-/* Hold process U-area in memory, normally for ptrace/procfs work. */
#define PHOLD(p) do { \
PROC_LOCK(p); \
_PHOLD(p); \
@@ -807,13 +904,19 @@ extern pid_t pid_max;
#define _PHOLD(p) do { \
PROC_LOCK_ASSERT((p), MA_OWNED); \
KASSERT(!((p)->p_flag & P_WEXIT) || (p) == curproc, \
- ("PHOLD of exiting process")); \
+ ("PHOLD of exiting process %p", p)); \
(p)->p_lock++; \
if (((p)->p_flag & P_INMEM) == 0) \
faultin((p)); \
} while (0)
-#define PROC_ASSERT_HELD(p) do { \
- KASSERT((p)->p_lock > 0, ("process not held")); \
+#define _PHOLD_LITE(p) do { \
+ PROC_LOCK_ASSERT((p), MA_OWNED); \
+ KASSERT(!((p)->p_flag & P_WEXIT) || (p) == curproc, \
+ ("PHOLD of exiting process %p", p)); \
+ (p)->p_lock++; \
+} while (0)
+#define PROC_ASSERT_HELD(p) do { \
+ KASSERT((p)->p_lock > 0, ("process %p not held", p)); \
} while (0)
#define PRELE(p) do { \
@@ -828,8 +931,13 @@ extern pid_t pid_max;
if (((p)->p_flag & P_WEXIT) && (p)->p_lock == 0) \
wakeup(&(p)->p_lock); \
} while (0)
-#define PROC_ASSERT_NOT_HELD(p) do { \
- KASSERT((p)->p_lock == 0, ("process held")); \
+#define PROC_ASSERT_NOT_HELD(p) do { \
+ KASSERT((p)->p_lock == 0, ("process %p held", p)); \
+} while (0)
+
+#define PROC_UPDATE_COW(p) do { \
+ PROC_LOCK_ASSERT((p), MA_OWNED); \
+ (p)->p_cowgen++; \
} while (0)
#else /* __rtems__ */
#define PHOLD(x) do { } while (0)
@@ -840,17 +948,11 @@ extern pid_t pid_max;
#define thread_safetoswapout(td) ((td)->td_flags & TDF_CANSWAP)
/* Control whether or not it is safe for curthread to sleep. */
-#define THREAD_NO_SLEEPING() do { \
- KASSERT(!(curthread->td_pflags & TDP_NOSLEEPING), \
- ("nested no sleeping")); \
- curthread->td_pflags |= TDP_NOSLEEPING; \
-} while (0)
+#define THREAD_NO_SLEEPING() ((curthread)->td_no_sleeping++)
-#define THREAD_SLEEPING_OK() do { \
- KASSERT((curthread->td_pflags & TDP_NOSLEEPING), \
- ("nested sleeping ok")); \
- curthread->td_pflags &= ~TDP_NOSLEEPING; \
-} while (0)
+#define THREAD_SLEEPING_OK() ((curthread)->td_no_sleeping--)
+
+#define THREAD_CAN_SLEEP() ((curthread)->td_no_sleeping == 0)
#define PIDHASH(pid) (&pidhashtbl[(pid) & pidhash])
extern LIST_HEAD(pidhashhead, proc) *pidhashtbl;
@@ -865,10 +967,12 @@ extern LIST_HEAD(pgrphashhead, pgrp) *pgrphashtbl;
extern u_long pgrphash;
extern struct sx allproc_lock;
+extern int allproc_gen;
extern struct sx proctree_lock;
extern struct mtx ppeers_lock;
extern struct proc proc0; /* Process slot for swapper. */
-extern struct thread thread0; /* Primary thread in proc0. */
+extern struct thread0_storage thread0_st; /* Primary thread in proc0. */
+#define thread0 (thread0_st.t0st_thread)
extern struct vmspace vmspace0; /* VM space for proc0. */
extern int hogticks; /* Limit on kernel cpu hogs. */
extern int lastpid;
@@ -890,6 +994,16 @@ struct proc *pfind_locked(pid_t pid);
struct pgrp *pgfind(pid_t); /* Find process group by id. */
struct proc *zpfind(pid_t); /* Find zombie process by id. */
+struct fork_req {
+ int fr_flags;
+ int fr_pages;
+ int *fr_pidp;
+ struct proc **fr_procp;
+ int *fr_pd_fd;
+ int fr_pd_flags;
+ struct filecaps *fr_pd_fcaps;
+};
+
/*
* pget() flags.
*/
@@ -907,13 +1021,22 @@ int pget(pid_t pid, int flags, struct proc **pp);
void ast(struct trapframe *framep);
struct thread *choosethread(void);
+#ifndef __rtems__
+int cr_cansee(struct ucred *u1, struct ucred *u2);
+int cr_canseesocket(struct ucred *cred, struct socket *so);
+#else /* __rtems__ */
+#define cr_cansee(u1, u2) 0
+#define cr_canseesocket(cred, so) 0
+#endif /* __rtems__ */
+int cr_canseeothergids(struct ucred *u1, struct ucred *u2);
+int cr_canseeotheruids(struct ucred *u1, struct ucred *u2);
int cr_cansignal(struct ucred *cred, struct proc *proc, int signum);
int enterpgrp(struct proc *p, pid_t pgid, struct pgrp *pgrp,
struct session *sess);
int enterthispgrp(struct proc *p, struct pgrp *pgrp);
void faultin(struct proc *p);
void fixjobc(struct proc *p, struct pgrp *pgrp, int entering);
-int fork1(struct thread *, int, int, struct proc **, int *, int);
+int fork1(struct thread *, struct fork_req *);
void fork_exit(void (*)(void *, struct trapframe *), void *,
struct trapframe *);
void fork_return(struct thread *, struct trapframe *);
@@ -924,6 +1047,7 @@ void kick_proc0(void);
#else /* __rtems__ */
#define kick_proc0()
#endif /* __rtems__ */
+void killjobc(void);
int leavepgrp(struct proc *p);
int maybe_preempt(struct thread *td);
void maybe_yield(void);
@@ -942,11 +1066,14 @@ int proc_getenvv(struct thread *td, struct proc *p, struct sbuf *sb);
void procinit(void);
void proc_linkup0(struct proc *p, struct thread *td);
void proc_linkup(struct proc *p, struct thread *td);
+struct proc *proc_realparent(struct proc *child);
void proc_reap(struct thread *td, struct proc *p, int *status, int options);
void proc_reparent(struct proc *child, struct proc *newparent);
+void proc_set_traced(struct proc *p, bool stop);
struct pstats *pstats_alloc(void);
void pstats_fork(struct pstats *src, struct pstats *dst);
void pstats_free(struct pstats *ps);
+void reaper_abandon_children(struct proc *p, bool exiting);
#ifndef __rtems__
int securelevel_ge(struct ucred *cr, int level);
int securelevel_gt(struct ucred *cr, int level);
@@ -960,7 +1087,6 @@ int setrunnable(struct thread *);
void setsugid(struct proc *p);
int should_yield(void);
int sigonstack(size_t sp);
-void sleepinit(void);
void stopevent(struct proc *, u_int, u_int);
struct thread *tdfind(lwpid_t, pid_t);
void threadinit(void);
@@ -968,22 +1094,21 @@ void tidhash_add(struct thread *);
void tidhash_remove(struct thread *);
void cpu_idle(int);
int cpu_idle_wakeup(int);
-extern void (*cpu_idle_hook)(void); /* Hook to machdep CPU idler. */
+extern void (*cpu_idle_hook)(sbintime_t); /* Hook to machdep CPU idler. */
void cpu_switch(struct thread *, struct thread *, struct mtx *);
void cpu_throw(struct thread *, struct thread *) __dead2;
void unsleep(struct thread *);
void userret(struct thread *, struct trapframe *);
void cpu_exit(struct thread *);
-void exit1(struct thread *, int) __dead2;
-struct syscall_args;
+void exit1(struct thread *, int, int) __dead2;
+void cpu_copy_thread(struct thread *td, struct thread *td0);
int cpu_fetch_syscall_args(struct thread *td, struct syscall_args *sa);
void cpu_fork(struct thread *, struct proc *, struct thread *, int);
-void cpu_set_fork_handler(struct thread *, void (*)(void *), void *);
+void cpu_fork_kthread_handler(struct thread *, void (*)(void *), void *);
void cpu_set_syscall_retval(struct thread *, int);
-void cpu_set_upcall(struct thread *td, struct thread *td0);
#ifndef __rtems__
-void cpu_set_upcall_kse(struct thread *, void (*)(void *), void *,
+void cpu_set_upcall(struct thread *, void (*)(void *), void *,
stack_t *);
#endif /* __rtems__ */
int cpu_set_user_tls(struct thread *, void *tls_base);
@@ -995,27 +1120,35 @@ void cpu_thread_swapin(struct thread *);
void cpu_thread_swapout(struct thread *);
struct thread *thread_alloc(int pages);
int thread_alloc_stack(struct thread *, int pages);
+void thread_cow_get_proc(struct thread *newtd, struct proc *p);
+void thread_cow_get(struct thread *newtd, struct thread *td);
+void thread_cow_free(struct thread *td);
+void thread_cow_update(struct thread *td);
+int thread_create(struct thread *td, struct rtprio *rtp,
+ int (*initialize_thread)(struct thread *, void *), void *thunk);
void thread_exit(void) __dead2;
void thread_free(struct thread *td);
void thread_link(struct thread *td, struct proc *p);
void thread_reap(void);
-int thread_single(int how);
-void thread_single_end(void);
+int thread_single(struct proc *p, int how);
+void thread_single_end(struct proc *p, int how);
void thread_stash(struct thread *td);
void thread_stopped(struct proc *p);
void childproc_stopped(struct proc *child, int reason);
void childproc_continued(struct proc *child);
void childproc_exited(struct proc *child);
int thread_suspend_check(int how);
-void thread_suspend_switch(struct thread *);
+bool thread_suspend_check_needed(void);
+void thread_suspend_switch(struct thread *, struct proc *p);
void thread_suspend_one(struct thread *td);
void thread_unlink(struct thread *td);
void thread_unsuspend(struct proc *p);
-int thread_unsuspend_one(struct thread *td);
-void thread_unthread(struct thread *td);
void thread_wait(struct proc *p);
struct thread *thread_find(struct proc *p, lwpid_t tid);
+void stop_all_proc(void);
+void resume_all_proc(void);
+
#ifndef __rtems__
static __inline int
curthread_pflags_set(int flags)
@@ -1035,6 +1168,13 @@ curthread_pflags_restore(int save)
curthread->td_pflags &= save;
}
+
+static __inline __pure2 struct td_sched *
+td_get_sched(struct thread *td)
+{
+
+ return ((struct td_sched *)&td[1]);
+}
#endif /* __rtems__ */
#endif /* _KERNEL */
diff --git a/freebsd/sys/sys/protosw.h b/freebsd/sys/sys/protosw.h
index b55af4b7..896ec253 100644
--- a/freebsd/sys/sys/protosw.h
+++ b/freebsd/sys/sys/protosw.h
@@ -34,6 +34,7 @@
#define _SYS_PROTOSW_H_
/* Forward declare these structures referenced from prototypes below. */
+struct kaiocb;
struct mbuf;
struct thread;
struct sockaddr;
@@ -64,13 +65,11 @@ struct sockopt;
* similar to the vnode VOP interface.
*/
/* USE THESE FOR YOUR PROTOTYPES ! */
-typedef void pr_input_t (struct mbuf *, int);
-typedef int pr_input6_t (struct mbuf **, int*, int); /* XXX FIX THIS */
-typedef int pr_output_t (struct mbuf *, struct socket *);
+typedef int pr_input_t (struct mbuf **, int*, int);
+typedef int pr_output_t (struct mbuf *, struct socket *, ...);
typedef void pr_ctlinput_t (int, struct sockaddr *, void *);
typedef int pr_ctloutput_t (struct socket *, struct sockopt *);
typedef void pr_init_t (void);
-typedef void pr_destroy_t (void);
typedef void pr_fasttimo_t (void);
typedef void pr_slowtimo_t (void);
typedef void pr_drain_t (void);
@@ -87,7 +86,6 @@ struct protosw {
pr_ctloutput_t *pr_ctloutput; /* control output (from above) */
/* utility hooks */
pr_init_t *pr_init;
- pr_destroy_t *pr_destroy;
pr_fasttimo_t *pr_fasttimo; /* fast timeout (200ms) */
pr_slowtimo_t *pr_slowtimo; /* slow timeout (500ms) */
pr_drain_t *pr_drain; /* flush any excess space possible */
@@ -203,15 +201,17 @@ struct pr_usrreqs {
int (*pru_peeraddr)(struct socket *so, struct sockaddr **nam);
int (*pru_rcvd)(struct socket *so, int flags);
int (*pru_rcvoob)(struct socket *so, struct mbuf *m, int flags);
- int (*pru_send)(struct socket *so, int flags, struct mbuf *m,
+ int (*pru_send)(struct socket *so, int flags, struct mbuf *m,
struct sockaddr *addr, struct mbuf *control,
struct thread *td);
#define PRUS_OOB 0x1
#define PRUS_EOF 0x2
#define PRUS_MORETOCOME 0x4
+#define PRUS_NOTREADY 0x8
+ int (*pru_ready)(struct socket *so, struct mbuf *m, int count);
int (*pru_sense)(struct socket *so, struct stat *sb);
- int (*pru_shutdown)(struct socket *so);
- int (*pru_flush)(struct socket *so, int direction);
+ int (*pru_shutdown)(struct socket *so);
+ int (*pru_flush)(struct socket *so, int direction);
int (*pru_sockaddr)(struct socket *so, struct sockaddr **nam);
int (*pru_sosend)(struct socket *so, struct sockaddr *addr,
struct uio *uio, struct mbuf *top, struct mbuf *control,
@@ -223,17 +223,27 @@ struct pr_usrreqs {
struct ucred *cred, struct thread *td);
void (*pru_sosetlabel)(struct socket *so);
void (*pru_close)(struct socket *so);
+ int (*pru_bindat)(int fd, struct socket *so, struct sockaddr *nam,
+ struct thread *td);
+ int (*pru_connectat)(int fd, struct socket *so,
+ struct sockaddr *nam, struct thread *td);
+ int (*pru_aio_queue)(struct socket *so, struct kaiocb *job);
};
/*
* All nonvoid pru_*() functions below return EOPNOTSUPP.
*/
int pru_accept_notsupp(struct socket *so, struct sockaddr **nam);
+int pru_aio_queue_notsupp(struct socket *so, struct kaiocb *job);
int pru_attach_notsupp(struct socket *so, int proto, struct thread *td);
int pru_bind_notsupp(struct socket *so, struct sockaddr *nam,
struct thread *td);
+int pru_bindat_notsupp(int fd, struct socket *so, struct sockaddr *nam,
+ struct thread *td);
int pru_connect_notsupp(struct socket *so, struct sockaddr *nam,
struct thread *td);
+int pru_connectat_notsupp(int fd, struct socket *so, struct sockaddr *nam,
+ struct thread *td);
int pru_connect2_notsupp(struct socket *so1, struct socket *so2);
int pru_control_notsupp(struct socket *so, u_long cmd, caddr_t data,
struct ifnet *ifp, struct thread *td);
@@ -244,6 +254,7 @@ int pru_rcvd_notsupp(struct socket *so, int flags);
int pru_rcvoob_notsupp(struct socket *so, struct mbuf *m, int flags);
int pru_send_notsupp(struct socket *so, int flags, struct mbuf *m,
struct sockaddr *addr, struct mbuf *control, struct thread *td);
+int pru_ready_notsupp(struct socket *so, struct mbuf *m, int count);
int pru_sense_null(struct socket *so, struct stat *sb);
int pru_shutdown_notsupp(struct socket *so);
int pru_sockaddr_notsupp(struct socket *so, struct sockaddr **nam);
@@ -266,9 +277,9 @@ int pru_sopoll_notsupp(struct socket *so, int events, struct ucred *cred,
*/
#define PRC_IFDOWN 0 /* interface transition */
#define PRC_ROUTEDEAD 1 /* select new route if possible ??? */
-#define PRC_IFUP 2 /* interface has come back up */
-#define PRC_QUENCH2 3 /* DEC congestion bit says slow down */
-#define PRC_QUENCH 4 /* some one said to slow down */
+#define PRC_IFUP 2 /* interface has come back up */
+/* was PRC_QUENCH2 3 DEC congestion bit says slow down */
+/* was PRC_QUENCH 4 Deprecated by RFC 6633 */
#define PRC_MSGSIZE 5 /* message size forced drop */
#define PRC_HOSTDEAD 6 /* host appears to be down */
#define PRC_HOSTUNREACH 7 /* deprecated (use PRC_UNREACH_HOST) */
@@ -330,6 +341,7 @@ char *prcorequests[] = {
#ifdef _KERNEL
void pfctlinput(int, struct sockaddr *);
void pfctlinput2(int, struct sockaddr *, void *);
+struct domain *pffinddomain(int family);
struct protosw *pffindproto(int family, int protocol, int type);
struct protosw *pffindtype(int family, int type);
int pf_proto_register(int family, struct protosw *npr);
diff --git a/freebsd/sys/sys/racct.h b/freebsd/sys/sys/racct.h
index 3b34891a..9b8143f2 100644
--- a/freebsd/sys/sys/racct.h
+++ b/freebsd/sys/sys/racct.h
@@ -37,9 +37,12 @@
#define _RACCT_H_
#include <sys/cdefs.h>
-#include <sys/queue.h>
#include <sys/types.h>
+#include <sys/queue.h>
+#include <sys/stdint.h>
+#include <sys/sysctl.h>
+struct buf;
struct proc;
struct rctl_rule_link;
struct ucred;
@@ -69,7 +72,11 @@ struct ucred;
#define RACCT_SHMSIZE 18
#define RACCT_WALLCLOCK 19
#define RACCT_PCTCPU 20
-#define RACCT_MAX RACCT_PCTCPU
+#define RACCT_READBPS 21
+#define RACCT_WRITEBPS 22
+#define RACCT_READIOPS 23
+#define RACCT_WRITEIOPS 24
+#define RACCT_MAX RACCT_WRITEIOPS
/*
* Resource properties.
@@ -82,17 +89,22 @@ struct ucred;
#define RACCT_DECAYING 0x20
extern int racct_types[];
+extern int racct_enable;
+
+#define ASSERT_RACCT_ENABLED() KASSERT(racct_enable, \
+ ("%s called with !racct_enable", __func__))
/*
* Amount stored in c_resources[] is 10**6 times bigger than what's
* visible to the userland. It gets fixed up when retrieving resource
* usage or adding rules.
*/
-#define RACCT_IS_IN_MILLIONS(X) (racct_types[X] & RACCT_IN_MILLIONS)
+#define RACCT_IS_IN_MILLIONS(X) \
+ ((X) != RACCT_UNDEFINED && (racct_types[(X)] & RACCT_IN_MILLIONS) != 0)
/*
* Resource usage can drop, as opposed to only grow. When the process
- * terminates, its resource usage is freed from the respective
+ * terminates, its resource usage is subtracted from the respective
* per-credential racct containers.
*/
#define RACCT_IS_RECLAIMABLE(X) (racct_types[X] & RACCT_RECLAIMABLE)
@@ -120,8 +132,7 @@ extern int racct_types[];
* When a process terminates, its resource usage is not automatically
* subtracted from per-credential racct containers. Instead, the resource
* usage of per-credential racct containers decays in time.
- * Resource usage can olso drop for such resource.
- * So far, the only such resource is RACCT_PCTCPU.
+ * Resource usage can also drop for such resource.
*/
#define RACCT_IS_DECAYING(X) (racct_types[X] & RACCT_DECAYING)
@@ -141,9 +152,20 @@ struct racct {
LIST_HEAD(, rctl_rule_link) r_rule_links;
};
+SYSCTL_DECL(_kern_racct);
+
+#ifdef RACCT
+
+extern struct mtx racct_lock;
+
+#define RACCT_LOCK() mtx_lock(&racct_lock)
+#define RACCT_UNLOCK() mtx_unlock(&racct_lock)
+#define RACCT_LOCK_ASSERT() mtx_assert(&racct_lock, MA_OWNED)
+
int racct_add(struct proc *p, int resource, uint64_t amount);
void racct_add_cred(struct ucred *cred, int resource, uint64_t amount);
void racct_add_force(struct proc *p, int resource, uint64_t amount);
+void racct_add_buf(struct proc *p, const struct buf *bufp, int is_write);
int racct_set(struct proc *p, int resource, uint64_t amount);
void racct_set_force(struct proc *p, int resource, uint64_t amount);
void racct_sub(struct proc *p, int resource, uint64_t amount);
@@ -161,5 +183,83 @@ void racct_proc_exit(struct proc *p);
void racct_proc_ucred_changed(struct proc *p, struct ucred *oldcred,
struct ucred *newcred);
void racct_move(struct racct *dest, struct racct *src);
+void racct_proc_throttle(struct proc *p, int timeout);
+
+#else
+
+static inline int
+racct_add(struct proc *p, int resource, uint64_t amount)
+{
+
+ return (0);
+}
+
+static inline void
+racct_add_cred(struct ucred *cred, int resource, uint64_t amount)
+{
+}
+
+static inline void
+racct_add_force(struct proc *p, int resource, uint64_t amount)
+{
+}
+
+static inline int
+racct_set(struct proc *p, int resource, uint64_t amount)
+{
+
+ return (0);
+}
+
+static inline void
+racct_set_force(struct proc *p, int resource, uint64_t amount)
+{
+}
+
+static inline void
+racct_sub(struct proc *p, int resource, uint64_t amount)
+{
+}
+
+static inline void
+racct_sub_cred(struct ucred *cred, int resource, uint64_t amount)
+{
+}
+
+static inline uint64_t
+racct_get_limit(struct proc *p, int resource)
+{
+
+ return (UINT64_MAX);
+}
+
+static inline uint64_t
+racct_get_available(struct proc *p, int resource)
+{
+
+ return (UINT64_MAX);
+}
+
+#define racct_create(x)
+#define racct_destroy(x)
+
+static inline int
+racct_proc_fork(struct proc *parent, struct proc *child)
+{
+
+ return (0);
+}
+
+static inline void
+racct_proc_fork_done(struct proc *child)
+{
+}
+
+static inline void
+racct_proc_exit(struct proc *p)
+{
+}
+
+#endif
#endif /* !_RACCT_H_ */
diff --git a/freebsd/sys/sys/random.h b/freebsd/sys/sys/random.h
index 5cf1611e..396ec2b1 100644
--- a/freebsd/sys/sys/random.h
+++ b/freebsd/sys/sys/random.h
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2000 Mark R. V. Murray
+ * Copyright (c) 2000-2015 Mark R. V. Murray
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -31,35 +31,86 @@
#ifdef _KERNEL
-int read_random(void *, int);
+#include <sys/types.h>
+
+#if !defined(KLD_MODULE)
+#if defined(RANDOM_LOADABLE) && defined(RANDOM_YARROW)
+#error "Cannot define both RANDOM_LOADABLE and RANDOM_YARROW"
+#endif
+#endif
+
+struct uio;
+
+#if defined(DEV_RANDOM)
+u_int read_random(void *, u_int);
+int read_random_uio(struct uio *, bool);
+#else
+static __inline int
+read_random_uio(void *a __unused, u_int b __unused)
+{
+ return (0);
+}
+static __inline u_int
+read_random(void *a __unused, u_int b __unused)
+{
+ return (0);
+}
+#endif
/*
- * Note: if you add or remove members of esource, remember to also update the
- * KASSERT regarding what valid members are in random_harvest_internal().
+ * Note: if you add or remove members of random_entropy_source, remember to also update the
+ * KASSERT regarding what valid members are in random_harvest_internal(), and remember the
+ * strings in the static array random_source_descr[] in random_harvestq.c.
+ *
+ * NOTE: complain loudly to markm@ or on the lists if this enum gets more than 32
+ * distinct values (0-31)! ENTROPYSOURCE may be == 32, but not > 32.
*/
-enum esource {
+enum random_entropy_source {
RANDOM_START = 0,
- RANDOM_WRITE = 0,
+ RANDOM_CACHED = 0,
+ /* Environmental sources */
+ RANDOM_ATTACH,
RANDOM_KEYBOARD,
RANDOM_MOUSE,
- RANDOM_NET,
+ RANDOM_NET_TUN,
+ RANDOM_NET_ETHER,
+ RANDOM_NET_NG,
RANDOM_INTERRUPT,
- RANDOM_PURE,
+ RANDOM_SWI,
+ RANDOM_FS_ATIME,
+ RANDOM_UMA, /* Special!! UMA/SLAB Allocator */
+ RANDOM_ENVIRONMENTAL_END = RANDOM_UMA,
+ /* Fast hardware random-number sources from here on. */
+ RANDOM_PURE_OCTEON,
+ RANDOM_PURE_SAFE,
+ RANDOM_PURE_GLXSB,
+ RANDOM_PURE_UBSEC,
+ RANDOM_PURE_HIFN,
+ RANDOM_PURE_RDRAND,
+ RANDOM_PURE_NEHEMIAH,
+ RANDOM_PURE_RNDTEST,
+ RANDOM_PURE_VIRTIO,
+ RANDOM_PURE_BROADCOM,
ENTROPYSOURCE
};
-void random_harvest(void *, u_int, u_int, u_int, enum esource);
-/* Allow the sysadmin to select the broad category of
- * entropy types to harvest
- */
-struct harvest_select {
- int ethernet;
- int point_to_point;
- int interrupt;
- int swi;
-};
+#define RANDOM_HARVEST_EVERYTHING_MASK ((1 << (RANDOM_ENVIRONMENTAL_END + 1)) - 1)
+
+#if defined(DEV_RANDOM)
+void random_harvest_queue(const void *, u_int, u_int, enum random_entropy_source);
+void random_harvest_fast(const void *, u_int, u_int, enum random_entropy_source);
+void random_harvest_direct(const void *, u_int, u_int, enum random_entropy_source);
+#else
+#define random_harvest_queue(a, b, c, d) do {} while (0)
+#define random_harvest_fast(a, b, c, d) do {} while (0)
+#define random_harvest_direct(a, b, c, d) do {} while (0)
+#endif
-extern struct harvest_select harvest;
+#if defined(RANDOM_ENABLE_UMA)
+#define random_harvest_fast_uma(a, b, c, d) random_harvest_fast(a, b, c, d)
+#else /* !defined(RANDOM_ENABLE_UMA) */
+#define random_harvest_fast_uma(a, b, c, d) do {} while (0)
+#endif /* defined(RANDOM_ENABLE_UMA) */
#endif /* _KERNEL */
diff --git a/freebsd/sys/sys/reboot.h b/freebsd/sys/sys/reboot.h
index 6b8e25e6..ebe688e8 100644
--- a/freebsd/sys/sys/reboot.h
+++ b/freebsd/sys/sys/reboot.h
@@ -59,6 +59,7 @@
#define RB_RESERVED1 0x40000 /* reserved for internal use of boot blocks */
#define RB_RESERVED2 0x80000 /* reserved for internal use of boot blocks */
#define RB_PAUSE 0x100000 /* pause after each output line during probe */
+#define RB_REROOT 0x200000 /* unmount the rootfs and mount it again */
#define RB_MULTIPLE 0x20000000 /* use multiple consoles */
#define RB_BOOTINFO 0x80000000 /* have `struct bootinfo *' arg */
diff --git a/freebsd/sys/sys/refcount.h b/freebsd/sys/sys/refcount.h
index b169f542..4611664e 100644
--- a/freebsd/sys/sys/refcount.h
+++ b/freebsd/sys/sys/refcount.h
@@ -29,6 +29,7 @@
#ifndef __SYS_REFCOUNT_H__
#define __SYS_REFCOUNT_H__
+#include <sys/limits.h>
#include <machine/atomic.h>
#ifdef _KERNEL
@@ -48,11 +49,8 @@ static __inline void
refcount_acquire(volatile u_int *count)
{
-#ifndef __rtems__
+ KASSERT(*count < UINT_MAX, ("refcount %p overflowed", count));
atomic_add_acq_int(count, 1);
-#else /* __rtems__ */
- atomic_add_acq_int((volatile int *) count, 1);
-#endif /* __rtems__ */
}
static __inline int
@@ -61,11 +59,7 @@ refcount_release(volatile u_int *count)
u_int old;
/* XXX: Should this have a rel membar? */
-#ifndef __rtems__
old = atomic_fetchadd_int(count, -1);
-#else /* __rtems__ */
- old = atomic_fetchadd_int((volatile int *) count, -1);
-#endif /* __rtems__ */
KASSERT(old > 0, ("negative refcount %p", count));
return (old == 1);
}
diff --git a/freebsd/sys/sys/resourcevar.h b/freebsd/sys/sys/resourcevar.h
index 3dead510..1d290aaa 100644
--- a/freebsd/sys/sys/resourcevar.h
+++ b/freebsd/sys/sys/resourcevar.h
@@ -47,21 +47,22 @@
* Locking key:
* b - created at fork, never changes
* c - locked by proc mtx
- * j - locked by proc slock
* k - only accessed by curthread
+ * w - locked by proc itim lock
+ * w2 - locked by proc prof lock
*/
struct pstats {
#define pstat_startzero p_cru
struct rusage p_cru; /* Stats for reaped children. */
- struct itimerval p_timer[3]; /* (j) Virtual-time timers. */
+ struct itimerval p_timer[3]; /* (w) Virtual-time timers. */
#define pstat_endzero pstat_startcopy
#define pstat_startcopy p_prof
struct uprof { /* Profile arguments. */
- caddr_t pr_base; /* (c + j) Buffer base. */
- u_long pr_size; /* (c + j) Buffer size. */
- u_long pr_off; /* (c + j) PC offset. */
- u_long pr_scale; /* (c + j) PC scaling. */
+ caddr_t pr_base; /* (c + w2) Buffer base. */
+ u_long pr_size; /* (c + w2) Buffer size. */
+ u_long pr_off; /* (c + w2) PC offset. */
+ u_long pr_scale; /* (c + w2) PC scaling. */
} p_prof;
#define pstat_endcopy p_start
struct timeval p_start; /* (b) Starting time. */
@@ -89,7 +90,7 @@ struct racct;
* Locking guide:
* (a) Constant from inception
* (b) Lockless, updated using atomics
- * (c) Locked by global uihashtbl_mtx
+ * (c) Locked by global uihashtbl_lock
* (d) Locked by the ui_vmsize_mtx
*/
struct uidinfo {
@@ -99,9 +100,13 @@ struct uidinfo {
long ui_sbsize; /* (b) socket buffer space consumed */
long ui_proccnt; /* (b) number of processes */
long ui_ptscnt; /* (b) number of pseudo-terminals */
+ long ui_kqcnt; /* (b) number of kqueues */
+ long ui_umtxcnt; /* (b) number of shared umtxs */
uid_t ui_uid; /* (a) uid */
u_int ui_ref; /* (b) reference count */
+#ifdef RACCT
struct racct *ui_racct; /* (a) resource accounting */
+#endif
};
#define UIDINFO_VMSIZE_LOCK(ui) mtx_lock(&((ui)->ui_vmsize_mtx))
@@ -115,6 +120,11 @@ void addupc_intr(struct thread *td, uintfptr_t pc, u_int ticks);
void addupc_task(struct thread *td, uintfptr_t pc, u_int ticks);
void calccru(struct proc *p, struct timeval *up, struct timeval *sp);
void calcru(struct proc *p, struct timeval *up, struct timeval *sp);
+#ifndef __rtems__
+int chgkqcnt(struct uidinfo *uip, int diff, rlim_t max);
+#else /* __rtems__ */
+#define chgkqcnt(uip, diff, max) 0
+#endif /* __rtems__ */
int chgproccnt(struct uidinfo *uip, int diff, rlim_t maxval);
#ifndef __rtems__
int chgsbsize(struct uidinfo *uip, u_int *hiwat, u_int to,
@@ -130,19 +140,23 @@ rtems_bsd_chgsbsize(u_int *hiwat, u_int to)
#define chgsbsize(uip, hiwat, to, maxval) rtems_bsd_chgsbsize(hiwat, to)
#endif /* __rtems__ */
int chgptscnt(struct uidinfo *uip, int diff, rlim_t maxval);
+int chgumtxcnt(struct uidinfo *uip, int diff, rlim_t maxval);
int fuswintr(void *base);
int kern_proc_setrlimit(struct thread *td, struct proc *p, u_int which,
struct rlimit *limp);
struct plimit
*lim_alloc(void);
void lim_copy(struct plimit *dst, struct plimit *src);
-rlim_t lim_cur(struct proc *p, int which);
+rlim_t lim_cur(struct thread *td, int which);
+rlim_t lim_cur_proc(struct proc *p, int which);
void lim_fork(struct proc *p1, struct proc *p2);
void lim_free(struct plimit *limp);
struct plimit
*lim_hold(struct plimit *limp);
-rlim_t lim_max(struct proc *p, int which);
-void lim_rlimit(struct proc *p, int which, struct rlimit *rlp);
+rlim_t lim_max(struct thread *td, int which);
+rlim_t lim_max_proc(struct proc *p, int which);
+void lim_rlimit(struct thread *td, int which, struct rlimit *rlp);
+void lim_rlimit_proc(struct proc *p, int which, struct rlimit *rlp);
void ruadd(struct rusage *ru, struct rusage_ext *rux, struct rusage *ru2,
struct rusage_ext *rux2);
void rucollect(struct rusage *ru, struct rusage *ru2);
@@ -157,8 +171,11 @@ struct uidinfo
void uifree(struct uidinfo *uip);
void uihashinit(void);
void uihold(struct uidinfo *uip);
+#ifdef RACCT
void ui_racct_foreach(void (*callback)(struct racct *racct,
- void *arg2, void *arg3), void *arg2, void *arg3);
+ void *arg2, void *arg3), void (*pre)(void), void (*post)(void),
+ void *arg2, void *arg3);
+#endif
#endif /* _KERNEL */
#endif /* !_SYS_RESOURCEVAR_H_ */
diff --git a/freebsd/sys/sys/rman.h b/freebsd/sys/sys/rman.h
index 547ff843..4de6022f 100644
--- a/freebsd/sys/sys/rman.h
+++ b/freebsd/sys/sys/rman.h
@@ -47,10 +47,11 @@
#define RF_FIRSTSHARE 0x0020 /* first in sharing list */
#define RF_PREFETCHABLE 0x0040 /* resource is prefetchable */
#define RF_OPTIONAL 0x0080 /* for bus_alloc_resources() */
+#define RF_UNMAPPED 0x0100 /* don't map resource when activating */
#define RF_ALIGNMENT_SHIFT 10 /* alignment size bit starts bit 10 */
#define RF_ALIGNMENT_MASK (0x003F << RF_ALIGNMENT_SHIFT)
- /* resource address alignemnt size bit mask */
+ /* resource address alignment size bit mask */
#define RF_ALIGNMENT_LOG2(x) ((x) << RF_ALIGNMENT_SHIFT)
#define RF_ALIGNMENT(x) (((x) & RF_ALIGNMENT_MASK) >> RF_ALIGNMENT_SHIFT)
@@ -61,6 +62,10 @@ enum rman_type { RMAN_UNINIT = 0, RMAN_GAUGE, RMAN_ARRAY };
*/
#define RM_TEXTLEN 32
+#define RM_MAX_END (~(rman_res_t)0)
+
+#define RMAN_IS_DEFAULT_RANGE(s,e) ((s) == 0 && (e) == RM_MAX_END)
+
/*
* Userspace-exported structures.
*/
@@ -70,8 +75,8 @@ struct u_resource {
uintptr_t r_device; /* device owning this resource */
char r_devname[RM_TEXTLEN]; /* device name XXX obsolete */
- u_long r_start; /* offset in resource space */
- u_long r_size; /* size in resource space */
+ rman_res_t r_start; /* offset in resource space */
+ rman_res_t r_size; /* size in resource space */
u_int r_flags; /* RF_* flags */
};
@@ -79,8 +84,8 @@ struct u_rman {
uintptr_t rm_handle; /* rman uniquifier */
char rm_descr[RM_TEXTLEN]; /* rman description */
- u_long rm_start; /* base of managed region */
- u_long rm_size; /* size of managed region */
+ rman_res_t rm_start; /* base of managed region */
+ rman_res_t rm_size; /* size of managed region */
enum rman_type rm_type; /* region type */
};
@@ -101,6 +106,7 @@ struct resource {
};
struct resource_i;
+struct resource_map;
TAILQ_HEAD(resource_head, resource_i);
@@ -108,47 +114,48 @@ struct rman {
struct resource_head rm_list;
struct mtx *rm_mtx; /* mutex used to protect rm_list */
TAILQ_ENTRY(rman) rm_link; /* link in list of all rmans */
- u_long rm_start; /* index of globally first entry */
- u_long rm_end; /* index of globally last entry */
+ rman_res_t rm_start; /* index of globally first entry */
+ rman_res_t rm_end; /* index of globally last entry */
enum rman_type rm_type; /* what type of resource this is */
const char *rm_descr; /* text descripion of this resource */
};
TAILQ_HEAD(rman_head, rman);
int rman_activate_resource(struct resource *r);
-int rman_adjust_resource(struct resource *r, u_long start, u_long end);
-int rman_await_resource(struct resource *r, int pri, int timo);
-int rman_first_free_region(struct rman *rm, u_long *start, u_long *end);
+int rman_adjust_resource(struct resource *r, rman_res_t start, rman_res_t end);
+int rman_first_free_region(struct rman *rm, rman_res_t *start, rman_res_t *end);
bus_space_handle_t rman_get_bushandle(struct resource *);
bus_space_tag_t rman_get_bustag(struct resource *);
-u_long rman_get_end(struct resource *);
-struct device *rman_get_device(struct resource *);
+rman_res_t rman_get_end(struct resource *);
+device_t rman_get_device(struct resource *);
u_int rman_get_flags(struct resource *);
+void rman_get_mapping(struct resource *, struct resource_map *);
int rman_get_rid(struct resource *);
-u_long rman_get_size(struct resource *);
-u_long rman_get_start(struct resource *);
+rman_res_t rman_get_size(struct resource *);
+rman_res_t rman_get_start(struct resource *);
void *rman_get_virtual(struct resource *);
int rman_deactivate_resource(struct resource *r);
int rman_fini(struct rman *rm);
int rman_init(struct rman *rm);
int rman_init_from_resource(struct rman *rm, struct resource *r);
-int rman_last_free_region(struct rman *rm, u_long *start, u_long *end);
+int rman_last_free_region(struct rman *rm, rman_res_t *start, rman_res_t *end);
uint32_t rman_make_alignment_flags(uint32_t size);
-int rman_manage_region(struct rman *rm, u_long start, u_long end);
+int rman_manage_region(struct rman *rm, rman_res_t start, rman_res_t end);
int rman_is_region_manager(struct resource *r, struct rman *rm);
int rman_release_resource(struct resource *r);
-struct resource *rman_reserve_resource(struct rman *rm, u_long start,
- u_long end, u_long count,
- u_int flags, struct device *dev);
-struct resource *rman_reserve_resource_bound(struct rman *rm, u_long start,
- u_long end, u_long count, u_long bound,
- u_int flags, struct device *dev);
+struct resource *rman_reserve_resource(struct rman *rm, rman_res_t start,
+ rman_res_t end, rman_res_t count,
+ u_int flags, device_t dev);
+struct resource *rman_reserve_resource_bound(struct rman *rm, rman_res_t start,
+ rman_res_t end, rman_res_t count, rman_res_t bound,
+ u_int flags, device_t dev);
void rman_set_bushandle(struct resource *_r, bus_space_handle_t _h);
void rman_set_bustag(struct resource *_r, bus_space_tag_t _t);
-void rman_set_device(struct resource *_r, struct device *_dev);
-void rman_set_end(struct resource *_r, u_long _end);
+void rman_set_device(struct resource *_r, device_t _dev);
+void rman_set_end(struct resource *_r, rman_res_t _end);
+void rman_set_mapping(struct resource *, struct resource_map *);
void rman_set_rid(struct resource *_r, int _rid);
-void rman_set_start(struct resource *_r, u_long _start);
+void rman_set_start(struct resource *_r, rman_res_t _start);
void rman_set_virtual(struct resource *_r, void *_v);
extern struct rman_head rman_head;
diff --git a/freebsd/sys/sys/rmlock.h b/freebsd/sys/sys/rmlock.h
index e71789ac..efd60597 100644
--- a/freebsd/sys/sys/rmlock.h
+++ b/freebsd/sys/sys/rmlock.h
@@ -40,17 +40,18 @@
#ifdef _KERNEL
/*
- * Flags passed to rm_init(9).
+ * Flags passed to rm_init_flags(9).
*/
#define RM_NOWITNESS 0x00000001
#define RM_RECURSE 0x00000002
#define RM_SLEEPABLE 0x00000004
+#define RM_NEW 0x00000008
#ifndef __rtems__
void rm_init(struct rmlock *rm, const char *name);
void rm_init_flags(struct rmlock *rm, const char *name, int opts);
void rm_destroy(struct rmlock *rm);
-int rm_wowned(struct rmlock *rm);
+int rm_wowned(const struct rmlock *rm);
void rm_sysinit(void *arg);
void rm_sysinit_flags(void *arg);
@@ -67,7 +68,7 @@ int _rm_rlock(struct rmlock *rm, struct rm_priotracker *tracker,
int trylock);
void _rm_runlock(struct rmlock *rm, struct rm_priotracker *tracker);
#if defined(INVARIANTS) || defined(INVARIANT_SUPPORT)
-void _rm_assert(struct rmlock *rm, int what, const char *file,
+void _rm_assert(const struct rmlock *rm, int what, const char *file,
int line);
#endif
@@ -99,17 +100,18 @@ void _rm_assert(struct rmlock *rm, int what, const char *file,
tick_sbt * (timo), 0, C_HARDCLOCK)
#else /* __rtems__ */
- #define rm_init(rm, name) rw_init(rm, name)
- #define rm_init_flags(rm, name, opts) rw_init_flags(rm, name, opts)
- #define rm_destroy(rm) rw_destroy(rm)
- #define rm_wowned(rm) rw_wowned(rm)
- #define rm_sysinit(arg) rw_sysinit(arg)
- #define rm_sysinit_flags(arg) rw_sysinit_flags(arg)
-
- #define rm_wlock(rm) rw_wlock((rm))
- #define rm_wunlock(rm) rw_wunlock((rm))
- #define rm_rlock(rm,tracker) rw_rlock((rm))
- #define rm_runlock(rm,tracker) rw_runlock((rm))
+#include <sys/rwlock.h>
+#define rm_init rw_init
+#define rm_init_flags rw_init_flags
+#define rm_destroy rw_destroy
+#define rm_wowned rw_wowned
+#define rm_sysinit rw_sysinit
+#define rm_sysinit_flags rw_sysinit_flags
+#define rm_wlock rw_wlock
+#define rm_wunlock rw_wunlock
+#define rm_rlock(rm, tracker) do { (void)tracker; rw_rlock(rm); } while (0)
+#define rm_runlock(rm, tracker) do { (void)tracker; rw_runlock(rm); } while (0)
+#define rm_sleep rw_sleep
#endif /* __rtems__ */
diff --git a/freebsd/sys/sys/rwlock.h b/freebsd/sys/sys/rwlock.h
index 2dd1a257..e0003840 100644
--- a/freebsd/sys/sys/rwlock.h
+++ b/freebsd/sys/sys/rwlock.h
@@ -99,12 +99,12 @@
/* Acquire a write lock. */
#define __rw_wlock(rw, tid, file, line) do { \
uintptr_t _tid = (uintptr_t)(tid); \
- \
- if (!_rw_write_lock((rw), _tid)) \
+ \
+ if ((rw)->rw_lock != RW_UNLOCKED || !_rw_write_lock((rw), _tid))\
_rw_wlock_hard((rw), _tid, (file), (line)); \
else \
- LOCKSTAT_PROFILE_OBTAIN_LOCK_SUCCESS(LS_RW_WLOCK_ACQUIRE, \
- rw, 0, 0, (file), (line)); \
+ LOCKSTAT_PROFILE_OBTAIN_RWLOCK_SUCCESS(rw__acquire, rw, \
+ 0, 0, file, line, LOCKSTAT_WRITER); \
} while (0)
/* Release a write lock. */
@@ -113,8 +113,12 @@
\
if ((rw)->rw_recurse) \
(rw)->rw_recurse--; \
- else if (!_rw_write_unlock((rw), _tid)) \
- _rw_wunlock_hard((rw), _tid, (file), (line)); \
+ else { \
+ LOCKSTAT_PROFILE_RELEASE_RWLOCK(rw__release, rw, \
+ LOCKSTAT_WRITER); \
+ if ((rw)->rw_lock != _tid || !_rw_write_unlock((rw), _tid))\
+ _rw_wunlock_hard((rw), _tid, (file), (line)); \
+ } \
} while (0)
#endif /* __rtems__ */
@@ -123,8 +127,30 @@
* external API and should not be called directly. Wrapper macros should
* be used instead.
*/
-
-#define rw_init(rw, name) rw_init_flags((rw), (name), 0)
+#ifndef __rtems__
+void _rw_init_flags(volatile uintptr_t *c, const char *name, int opts);
+void _rw_destroy(volatile uintptr_t *c);
+void rw_sysinit(void *arg);
+void rw_sysinit_flags(void *arg);
+int _rw_wowned(const volatile uintptr_t *c);
+void _rw_wlock_cookie(volatile uintptr_t *c, const char *file, int line);
+int __rw_try_wlock(volatile uintptr_t *c, const char *file, int line);
+void _rw_wunlock_cookie(volatile uintptr_t *c, const char *file, int line);
+void __rw_rlock(volatile uintptr_t *c, const char *file, int line);
+int __rw_try_rlock(volatile uintptr_t *c, const char *file, int line);
+void _rw_runlock_cookie(volatile uintptr_t *c, const char *file, int line);
+void __rw_wlock_hard(volatile uintptr_t *c, uintptr_t tid, const char *file,
+ int line);
+void __rw_wunlock_hard(volatile uintptr_t *c, uintptr_t tid,
+ const char *file, int line);
+int __rw_try_upgrade(volatile uintptr_t *c, const char *file, int line);
+void __rw_downgrade(volatile uintptr_t *c, const char *file, int line);
+#if defined(INVARIANTS) || defined(INVARIANT_SUPPORT)
+void __rw_assert(const volatile uintptr_t *c, int what, const char *file,
+ int line);
+#endif
+#else /* __rtems__ */
+#define rw_init(rw, n) rw_init_flags(rw, n, 0)
void rw_init_flags(struct rwlock *rw, const char *name, int opts);
void rw_destroy(struct rwlock *rw);
void rw_sysinit(void *arg);
@@ -136,15 +162,50 @@ void _rw_wunlock(struct rwlock *rw, const char *file, int line);
void _rw_rlock(struct rwlock *rw, const char *file, int line);
int _rw_try_rlock(struct rwlock *rw, const char *file, int line);
void _rw_runlock(struct rwlock *rw, const char *file, int line);
-void _rw_wlock_hard(struct rwlock *rw, uintptr_t tid, const char *file,
- int line);
-void _rw_wunlock_hard(struct rwlock *rw, uintptr_t tid, const char *file,
- int line);
int _rw_try_upgrade(struct rwlock *rw, const char *file, int line);
void _rw_downgrade(struct rwlock *rw, const char *file, int line);
+#endif /* __rtems__ */
+
+#ifndef __rtems__
+/*
+ * Top-level macros to provide lock cookie once the actual rwlock is passed.
+ * They will also prevent passing a malformed object to the rwlock KPI by
+ * failing compilation as the rw_lock reserved member will not be found.
+ */
+#define rw_init(rw, n) \
+ _rw_init_flags(&(rw)->rw_lock, n, 0)
+#define rw_init_flags(rw, n, o) \
+ _rw_init_flags(&(rw)->rw_lock, n, o)
+#define rw_destroy(rw) \
+ _rw_destroy(&(rw)->rw_lock)
+#define rw_wowned(rw) \
+ _rw_wowned(&(rw)->rw_lock)
+#define _rw_wlock(rw, f, l) \
+ _rw_wlock_cookie(&(rw)->rw_lock, f, l)
+#define _rw_try_wlock(rw, f, l) \
+ __rw_try_wlock(&(rw)->rw_lock, f, l)
+#define _rw_wunlock(rw, f, l) \
+ _rw_wunlock_cookie(&(rw)->rw_lock, f, l)
+#define _rw_rlock(rw, f, l) \
+ __rw_rlock(&(rw)->rw_lock, f, l)
+#define _rw_try_rlock(rw, f, l) \
+ __rw_try_rlock(&(rw)->rw_lock, f, l)
+#define _rw_runlock(rw, f, l) \
+ _rw_runlock_cookie(&(rw)->rw_lock, f, l)
+#define _rw_wlock_hard(rw, t, f, l) \
+ __rw_wlock_hard(&(rw)->rw_lock, t, f, l)
+#define _rw_wunlock_hard(rw, t, f, l) \
+ __rw_wunlock_hard(&(rw)->rw_lock, t, f, l)
+#define _rw_try_upgrade(rw, f, l) \
+ __rw_try_upgrade(&(rw)->rw_lock, f, l)
+#define _rw_downgrade(rw, f, l) \
+ __rw_downgrade(&(rw)->rw_lock, f, l)
#if defined(INVARIANTS) || defined(INVARIANT_SUPPORT)
-void _rw_assert(struct rwlock *rw, int what, const char *file, int line);
+#define _rw_assert(rw, w, f, l) \
+ __rw_assert(&(rw)->rw_lock, w, f, l)
#endif
+#endif /* __rtems__ */
+
/*
* Public interface for lock operations.
@@ -175,17 +236,18 @@ void _rw_assert(struct rwlock *rw, int what, const char *file, int line);
rw_runlock(rw); \
} while (0)
#define rw_sleep(chan, rw, pri, wmesg, timo) \
- _sleep((chan), &(rw)->lock_object, (pri), (wmesg), (timo))
+ _sleep((chan), &(rw)->lock_object, (pri), (wmesg), \
+ tick_sbt * (timo), 0, C_HARDCLOCK)
-#define rw_initialized(rw) lock_initalized(&(rw)->lock_object)
+#define rw_initialized(rw) lock_initialized(&(rw)->lock_object)
struct rw_args {
- struct rwlock *ra_rw;
+ void *ra_rw;
const char *ra_desc;
};
struct rw_args_flags {
- struct rwlock *ra_rw;
+ void *ra_rw;
const char *ra_desc;
int ra_flags;
};
@@ -198,7 +260,7 @@ struct rw_args_flags {
SYSINIT(name##_rw_sysinit, SI_SUB_LOCK, SI_ORDER_MIDDLE, \
rw_sysinit, &name##_args); \
SYSUNINIT(name##_rw_sysuninit, SI_SUB_LOCK, SI_ORDER_MIDDLE, \
- rw_destroy, (rw))
+ _rw_destroy, __DEVOLATILE(void *, &(rw)->rw_lock))
#define RW_SYSINIT_FLAGS(name, rw, desc, flags) \
@@ -210,7 +272,7 @@ struct rw_args_flags {
SYSINIT(name##_rw_sysinit, SI_SUB_LOCK, SI_ORDER_MIDDLE, \
rw_sysinit_flags, &name##_args); \
SYSUNINIT(name##_rw_sysuninit, SI_SUB_LOCK, SI_ORDER_MIDDLE, \
- rw_destroy, (rw))
+ _rw_destroy, __DEVOLATILE(void *, &(rw)->rw_lock))
/*
* Options passed to rw_init_flags().
@@ -220,6 +282,7 @@ struct rw_args_flags {
#define RW_NOWITNESS 0x04
#define RW_QUIET 0x08
#define RW_RECURSE 0x10
+#define RW_NEW 0x20
/*
* The INVARIANTS-enabled rw_assert() functionality.
diff --git a/freebsd/sys/sys/sbuf.h b/freebsd/sys/sys/sbuf.h
index 9816a4cd..580cbd2e 100644
--- a/freebsd/sys/sys/sbuf.h
+++ b/freebsd/sys/sys/sbuf.h
@@ -48,6 +48,7 @@ struct sbuf {
ssize_t s_len; /* current length of string */
#define SBUF_FIXEDLEN 0x00000000 /* fixed length buffer (default) */
#define SBUF_AUTOEXTEND 0x00000001 /* automatically extend buffer */
+#define SBUF_INCLUDENUL 0x00000002 /* nulterm byte is counted in len */
#define SBUF_USRFLAGMSK 0x0000ffff /* mask of flags the user may specify */
#define SBUF_DYNAMIC 0x00010000 /* s_buf must be freed */
#define SBUF_FINISHED 0x00020000 /* set by sbuf_finish() */
@@ -57,6 +58,14 @@ struct sbuf {
ssize_t s_sect_len; /* current length of section */
};
+#ifndef HD_COLUMN_MASK
+#define HD_COLUMN_MASK 0xff
+#define HD_DELIM_MASK 0xff00
+#define HD_OMIT_COUNT (1 << 16)
+#define HD_OMIT_HEX (1 << 17)
+#define HD_OMIT_CHARS (1 << 18)
+#endif /* HD_COLUMN_MASK */
+
__BEGIN_DECLS
/*
* API functions
@@ -64,6 +73,9 @@ __BEGIN_DECLS
struct sbuf *sbuf_new(struct sbuf *, char *, int, int);
#define sbuf_new_auto() \
sbuf_new(NULL, NULL, 0, SBUF_AUTOEXTEND)
+int sbuf_get_flags(struct sbuf *);
+void sbuf_clear_flags(struct sbuf *, int);
+void sbuf_set_flags(struct sbuf *, int);
void sbuf_clear(struct sbuf *);
int sbuf_setpos(struct sbuf *, ssize_t);
int sbuf_bcat(struct sbuf *, const void *, size_t);
@@ -85,6 +97,8 @@ int sbuf_done(const struct sbuf *);
void sbuf_delete(struct sbuf *);
void sbuf_start_section(struct sbuf *, ssize_t *);
ssize_t sbuf_end_section(struct sbuf *, ssize_t, size_t, int);
+void sbuf_hexdump(struct sbuf *, const void *, int, const char *,
+ int);
#ifdef _KERNEL
struct uio;
diff --git a/freebsd/sys/sys/sdt.h b/freebsd/sys/sys/sdt.h
index ca820f68..25423d76 100644
--- a/freebsd/sys/sys/sdt.h
+++ b/freebsd/sys/sys/sdt.h
@@ -161,7 +161,7 @@ SET_DECLARE(sdt_argtypes_set, struct sdt_argtype);
extern struct sdt_probe sdt_##prov##_##mod##_##func##_##name[1]
#define SDT_PROBE(prov, mod, func, name, arg0, arg1, arg2, arg3, arg4) do { \
- if (sdt_##prov##_##mod##_##func##_##name->id) \
+ if (__predict_false(sdt_##prov##_##mod##_##func##_##name->id)) \
(*sdt_probe_func)(sdt_##prov##_##mod##_##func##_##name->id, \
(uintptr_t) arg0, (uintptr_t) arg1, (uintptr_t) arg2, \
(uintptr_t) arg3, (uintptr_t) arg4); \
@@ -398,7 +398,7 @@ struct sdt_probe {
struct sdt_provider *prov; /* Ptr to the provider structure. */
TAILQ_ENTRY(sdt_probe)
probe_entry; /* SDT probe list entry. */
- TAILQ_HEAD(argtype_list_head, sdt_argtype) argtype_list;
+ TAILQ_HEAD(, sdt_argtype) argtype_list;
const char *mod;
const char *func;
const char *name;
diff --git a/freebsd/sys/sys/seq.h b/freebsd/sys/sys/seq.h
new file mode 100644
index 00000000..82efbdf1
--- /dev/null
+++ b/freebsd/sys/sys/seq.h
@@ -0,0 +1,129 @@
+/*-
+ * 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_SEQ_H_
+#define _SYS_SEQ_H_
+
+#ifdef _KERNEL
+#include <sys/systm.h>
+#endif
+#include <sys/types.h>
+
+/*
+ * seq_t may be included in structs visible to userspace
+ */
+typedef uint32_t seq_t;
+
+#ifdef _KERNEL
+
+/*
+ * Typical usage:
+ *
+ * writers:
+ * lock_exclusive(&obj->lock);
+ * seq_write_begin(&obj->seq);
+ * .....
+ * seq_write_end(&obj->seq);
+ * unlock_exclusive(&obj->unlock);
+ *
+ * readers:
+ * obj_t lobj;
+ * seq_t seq;
+ *
+ * for (;;) {
+ * seq = seq_read(&gobj->seq);
+ * lobj = gobj;
+ * if (seq_consistent(&gobj->seq, seq))
+ * break;
+ * cpu_spinwait();
+ * }
+ * foo(lobj);
+ */
+
+/* A hack to get MPASS macro */
+#include <rtems/bsd/sys/lock.h>
+
+#include <machine/cpu.h>
+
+static __inline bool
+seq_in_modify(seq_t seqp)
+{
+
+ return (seqp & 1);
+}
+
+static __inline void
+seq_write_begin(seq_t *seqp)
+{
+
+ MPASS(!seq_in_modify(*seqp));
+ *seqp += 1;
+ atomic_thread_fence_rel();
+}
+
+static __inline void
+seq_write_end(seq_t *seqp)
+{
+
+ atomic_store_rel_int(seqp, *seqp + 1);
+ MPASS(!seq_in_modify(*seqp));
+}
+
+static __inline seq_t
+seq_read(const seq_t *seqp)
+{
+ seq_t ret;
+
+ for (;;) {
+ ret = atomic_load_acq_int(__DECONST(seq_t *, seqp));
+ if (seq_in_modify(ret)) {
+ cpu_spinwait();
+ continue;
+ }
+ break;
+ }
+
+ return (ret);
+}
+
+static __inline seq_t
+seq_consistent_nomb(const seq_t *seqp, seq_t oldseq)
+{
+
+ return (*seqp == oldseq);
+}
+
+static __inline seq_t
+seq_consistent(const seq_t *seqp, seq_t oldseq)
+{
+
+ atomic_thread_fence_acq();
+ return (seq_consistent_nomb(seqp, oldseq));
+}
+
+#endif /* _KERNEL */
+#endif /* _SYS_SEQ_H_ */
diff --git a/freebsd/sys/sys/sf_buf.h b/freebsd/sys/sys/sf_buf.h
index af420652..b5970d95 100644
--- a/freebsd/sys/sys/sf_buf.h
+++ b/freebsd/sys/sys/sf_buf.h
@@ -1,4 +1,5 @@
/*-
+ * Copyright (c) 2014 Gleb Smirnoff <glebius@FreeBSD.org>
* Copyright (c) 2003-2004 Alan L. Cox <alc@cs.rice.edu>
* All rights reserved.
*
@@ -29,7 +30,158 @@
#ifndef _SYS_SF_BUF_H_
#define _SYS_SF_BUF_H_
+struct sfstat { /* sendfile statistics */
+ uint64_t sf_syscalls; /* times sendfile was called */
+ uint64_t sf_noiocnt; /* times sendfile didn't require I/O */
+ uint64_t sf_iocnt; /* times sendfile had to do disk I/O */
+ uint64_t sf_pages_read; /* pages read as part of a request */
+ uint64_t sf_pages_valid; /* pages were valid for a request */
+ uint64_t sf_rhpages_requested; /* readahead pages requested */
+ uint64_t sf_rhpages_read; /* readahead pages read */
+ uint64_t sf_busy; /* times aborted on a busy page */
+ uint64_t sf_allocfail; /* times sfbuf allocation failed */
+ uint64_t sf_allocwait; /* times sfbuf allocation had to wait */
+};
+
+#ifdef _KERNEL
+#include <sys/types.h>
+#include <sys/systm.h>
+#include <sys/counter.h>
+#include <vm/vm.h>
+#include <vm/vm_param.h>
+#include <vm/vm_page.h>
+
+/*
+ * Sf_bufs, or sendfile(2) buffers provide a vm_page that is mapped
+ * into kernel address space. Note, that they aren't used only
+ * by sendfile(2)!
+ *
+ * Sf_bufs could be implemented as a feature of vm_page_t, but that
+ * would require growth of the structure. That's why they are implemented
+ * as a separate hash indexed by vm_page address. Implementation lives in
+ * kern/subr_sfbuf.c. Meanwhile, most 64-bit machines have a physical map,
+ * so they don't require this hash at all, thus ignore subr_sfbuf.c.
+ *
+ * Different 32-bit architectures demand different requirements on sf_buf
+ * hash and functions. They request features in machine/vmparam.h, which
+ * enable parts of this file. They can also optionally provide helpers in
+ * machine/sf_buf.h
+ *
+ * Defines are:
+ * SFBUF This machine requires sf_buf hash.
+ * subr_sfbuf.c should be compiled.
+ * SFBUF_CPUSET This machine can perform SFB_CPUPRIVATE mappings,
+ * that do no invalidate cache on the rest of CPUs.
+ * SFBUF_NOMD This machine doesn't have machine/sf_buf.h
+ *
+ * SFBUF_OPTIONAL_DIRECT_MAP Value of this define is used as boolean
+ * variable that tells whether machine is
+ * capable of direct map or not at runtime.
+ * SFBUF_MAP This machine provides its own sf_buf_map() and
+ * sf_buf_unmap().
+ * SFBUF_PROCESS_PAGE This machine provides sf_buf_process_page()
+ * function.
+ */
+
+#ifdef SFBUF
+#if defined(SMP) && defined(SFBUF_CPUSET)
+#include <sys/_cpuset.h>
+#endif
+#include <sys/queue.h>
+
+struct sf_buf {
+ LIST_ENTRY(sf_buf) list_entry; /* list of buffers */
+ TAILQ_ENTRY(sf_buf) free_entry; /* list of buffers */
+ vm_page_t m; /* currently mapped page */
+ vm_offset_t kva; /* va of mapping */
+ int ref_count; /* usage of this mapping */
+#if defined(SMP) && defined(SFBUF_CPUSET)
+ cpuset_t cpumask; /* where mapping is valid */
+#endif
+};
+#else /* ! SFBUF */
+struct sf_buf;
+#endif /* SFBUF */
+
+#ifndef SFBUF_NOMD
#include <machine/sf_buf.h>
+#endif
+#ifdef SFBUF_OPTIONAL_DIRECT_MAP
+#include <machine/md_var.h>
+#endif
+
+#ifdef SFBUF
+struct sf_buf *sf_buf_alloc(struct vm_page *, int);
+void sf_buf_free(struct sf_buf *);
+void sf_buf_ref(struct sf_buf *);
+
+static inline vm_offset_t
+sf_buf_kva(struct sf_buf *sf)
+{
+#ifdef SFBUF_OPTIONAL_DIRECT_MAP
+ if (SFBUF_OPTIONAL_DIRECT_MAP)
+ return (SFBUF_PHYS_DMAP(VM_PAGE_TO_PHYS((vm_page_t)sf)));
+#endif
+
+ return (sf->kva);
+}
+
+static inline vm_page_t
+sf_buf_page(struct sf_buf *sf)
+{
+#ifdef SFBUF_OPTIONAL_DIRECT_MAP
+ if (SFBUF_OPTIONAL_DIRECT_MAP)
+ return ((vm_page_t)sf);
+#endif
+
+ return (sf->m);
+}
+
+#ifndef SFBUF_MAP
+#include <vm/pmap.h>
+
+static inline void
+sf_buf_map(struct sf_buf *sf, int flags)
+{
+
+ pmap_qenter(sf->kva, &sf->m, 1);
+}
+
+static inline int
+sf_buf_unmap(struct sf_buf *sf)
+{
+
+ return (0);
+}
+#endif /* SFBUF_MAP */
+
+#if defined(SMP) && defined(SFBUF_CPUSET)
+void sf_buf_shootdown(struct sf_buf *, int);
+#endif
+
+#ifdef SFBUF_PROCESS_PAGE
+boolean_t sf_buf_process_page(vm_page_t, void (*)(struct sf_buf *));
+#endif
+
+#else /* ! SFBUF */
+
+static inline struct sf_buf *
+sf_buf_alloc(struct vm_page *m, int pri)
+{
+
+ return ((struct sf_buf *)m);
+}
+
+static inline void
+sf_buf_free(struct sf_buf *sf)
+{
+}
+
+static inline void
+sf_buf_ref(struct sf_buf *sf)
+{
+}
+#endif /* SFBUF */
/*
* Options to sf_buf_alloc() are specified through its flags argument. This
@@ -42,15 +194,10 @@
#define SFB_DEFAULT 0
#define SFB_NOWAIT 4 /* Return NULL if all bufs are used. */
-struct vm_page;
-
-extern int nsfbufs; /* Number of sendfile(2) bufs alloced */
-extern int nsfbufspeak; /* Peak of nsfbufsused */
-extern int nsfbufsused; /* Number of sendfile(2) bufs in use */
-
-struct sf_buf *
- sf_buf_alloc(struct vm_page *m, int flags);
-void sf_buf_free(struct sf_buf *sf);
-void sf_buf_mext(void *addr, void *args);
-
+extern counter_u64_t sfstat[sizeof(struct sfstat) / sizeof(uint64_t)];
+#define SFSTAT_ADD(name, val) \
+ counter_u64_add(sfstat[offsetof(struct sfstat, name) / sizeof(uint64_t)],\
+ (val))
+#define SFSTAT_INC(name) SFSTAT_ADD(name, 1)
+#endif /* _KERNEL */
#endif /* !_SYS_SF_BUF_H_ */
diff --git a/freebsd/sys/sys/signalvar.h b/freebsd/sys/sys/signalvar.h
new file mode 100644
index 00000000..a2a1d0d8
--- /dev/null
+++ b/freebsd/sys/sys/signalvar.h
@@ -0,0 +1,403 @@
+/*-
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ * @(#)signalvar.h 8.6 (Berkeley) 2/19/95
+ * $FreeBSD$
+ */
+
+#ifndef _SYS_SIGNALVAR_H_
+#define _SYS_SIGNALVAR_H_
+
+#include <sys/queue.h>
+#include <sys/_lock.h>
+#include <sys/_mutex.h>
+#include <sys/signal.h>
+
+#ifndef __rtems__
+/*
+ * Kernel signal definitions and data structures.
+ */
+
+/*
+ * Logical process signal actions and state, needed only within the process
+ * The mapping between sigacts and proc structures is 1:1 except for rfork()
+ * processes masquerading as threads which use one structure for the whole
+ * group. All members are locked by the included mutex. The reference count
+ * and mutex must be last for the bcopy in sigacts_copy() to work.
+ */
+struct sigacts {
+ sig_t ps_sigact[_SIG_MAXSIG]; /* Disposition of signals. */
+ sigset_t ps_catchmask[_SIG_MAXSIG]; /* Signals to be blocked. */
+ sigset_t ps_sigonstack; /* Signals to take on sigstack. */
+ sigset_t ps_sigintr; /* Signals that interrupt syscalls. */
+ sigset_t ps_sigreset; /* Signals that reset when caught. */
+ sigset_t ps_signodefer; /* Signals not masked while handled. */
+ sigset_t ps_siginfo; /* Signals that want SA_SIGINFO args. */
+ sigset_t ps_sigignore; /* Signals being ignored. */
+ sigset_t ps_sigcatch; /* Signals being caught by user. */
+ sigset_t ps_freebsd4; /* Signals using freebsd4 ucontext. */
+ sigset_t ps_osigset; /* Signals using <= 3.x osigset_t. */
+ sigset_t ps_usertramp; /* SunOS compat; libc sigtramp. XXX */
+ int ps_flag;
+ u_int ps_refcnt;
+ struct mtx ps_mtx;
+};
+
+#define PS_NOCLDWAIT 0x0001 /* No zombies if child dies */
+#define PS_NOCLDSTOP 0x0002 /* No SIGCHLD when children stop. */
+#define PS_CLDSIGIGN 0x0004 /* The SIGCHLD handler is SIG_IGN. */
+
+#ifdef _KERNEL
+
+#ifdef COMPAT_43
+typedef struct {
+ struct osigcontext si_sc;
+ int si_signo;
+ int si_code;
+ union sigval si_value;
+} osiginfo_t;
+
+struct osigaction {
+ union {
+ void (*__sa_handler)(int);
+ void (*__sa_sigaction)(int, osiginfo_t *, void *);
+ } __sigaction_u; /* signal handler */
+ osigset_t sa_mask; /* signal mask to apply */
+ int sa_flags; /* see signal options below */
+};
+
+typedef void __osiginfohandler_t(int, osiginfo_t *, void *);
+#endif /* COMPAT_43 */
+
+/* additional signal action values, used only temporarily/internally */
+#define SIG_CATCH ((__sighandler_t *)2)
+/* #define SIG_HOLD ((__sighandler_t *)3) See signal.h */
+
+/*
+ * get signal action for process and signal; currently only for current process
+ */
+#define SIGACTION(p, sig) (p->p_sigacts->ps_sigact[_SIG_IDX(sig)])
+
+#endif /* _KERNEL */
+
+/*
+ * sigset_t manipulation macros.
+ */
+#define SIGADDSET(set, signo) \
+ ((set).__bits[_SIG_WORD(signo)] |= _SIG_BIT(signo))
+
+#define SIGDELSET(set, signo) \
+ ((set).__bits[_SIG_WORD(signo)] &= ~_SIG_BIT(signo))
+
+#define SIGEMPTYSET(set) \
+ do { \
+ int __i; \
+ for (__i = 0; __i < _SIG_WORDS; __i++) \
+ (set).__bits[__i] = 0; \
+ } while (0)
+
+#define SIGFILLSET(set) \
+ do { \
+ int __i; \
+ for (__i = 0; __i < _SIG_WORDS; __i++) \
+ (set).__bits[__i] = ~0U; \
+ } while (0)
+
+#define SIGISMEMBER(set, signo) \
+ ((set).__bits[_SIG_WORD(signo)] & _SIG_BIT(signo))
+
+#define SIGISEMPTY(set) (__sigisempty(&(set)))
+#define SIGNOTEMPTY(set) (!__sigisempty(&(set)))
+
+#define SIGSETEQ(set1, set2) (__sigseteq(&(set1), &(set2)))
+#define SIGSETNEQ(set1, set2) (!__sigseteq(&(set1), &(set2)))
+
+#define SIGSETOR(set1, set2) \
+ do { \
+ int __i; \
+ for (__i = 0; __i < _SIG_WORDS; __i++) \
+ (set1).__bits[__i] |= (set2).__bits[__i]; \
+ } while (0)
+
+#define SIGSETAND(set1, set2) \
+ do { \
+ int __i; \
+ for (__i = 0; __i < _SIG_WORDS; __i++) \
+ (set1).__bits[__i] &= (set2).__bits[__i]; \
+ } while (0)
+
+#define SIGSETNAND(set1, set2) \
+ do { \
+ int __i; \
+ for (__i = 0; __i < _SIG_WORDS; __i++) \
+ (set1).__bits[__i] &= ~(set2).__bits[__i]; \
+ } while (0)
+
+#define SIGSETLO(set1, set2) ((set1).__bits[0] = (set2).__bits[0])
+#define SIGSETOLD(set, oset) ((set).__bits[0] = (oset))
+
+#define SIG_CANTMASK(set) \
+ SIGDELSET(set, SIGKILL), SIGDELSET(set, SIGSTOP)
+
+#define SIG_STOPSIGMASK(set) \
+ SIGDELSET(set, SIGSTOP), SIGDELSET(set, SIGTSTP), \
+ SIGDELSET(set, SIGTTIN), SIGDELSET(set, SIGTTOU)
+
+#define SIG_CONTSIGMASK(set) \
+ SIGDELSET(set, SIGCONT)
+
+#define sigcantmask (sigmask(SIGKILL) | sigmask(SIGSTOP))
+
+#define SIG2OSIG(sig, osig) (osig = (sig).__bits[0])
+#define OSIG2SIG(osig, sig) SIGEMPTYSET(sig); (sig).__bits[0] = osig
+
+static __inline int
+__sigisempty(sigset_t *set)
+{
+ int i;
+
+ for (i = 0; i < _SIG_WORDS; i++) {
+ if (set->__bits[i])
+ return (0);
+ }
+ return (1);
+}
+
+static __inline int
+__sigseteq(sigset_t *set1, sigset_t *set2)
+{
+ int i;
+
+ for (i = 0; i < _SIG_WORDS; i++) {
+ if (set1->__bits[i] != set2->__bits[i])
+ return (0);
+ }
+ return (1);
+}
+
+#ifdef COMPAT_FREEBSD6
+struct osigevent {
+ int sigev_notify; /* Notification type */
+ union {
+ int __sigev_signo; /* Signal number */
+ int __sigev_notify_kqueue;
+ } __sigev_u;
+ union sigval sigev_value; /* Signal value */
+};
+#endif
+
+typedef struct ksiginfo {
+ TAILQ_ENTRY(ksiginfo) ksi_link;
+ siginfo_t ksi_info;
+ int ksi_flags;
+ struct sigqueue *ksi_sigq;
+} ksiginfo_t;
+
+#define ksi_signo ksi_info.si_signo
+#define ksi_errno ksi_info.si_errno
+#define ksi_code ksi_info.si_code
+#define ksi_pid ksi_info.si_pid
+#define ksi_uid ksi_info.si_uid
+#define ksi_status ksi_info.si_status
+#define ksi_addr ksi_info.si_addr
+#define ksi_value ksi_info.si_value
+#define ksi_band ksi_info.si_band
+#define ksi_trapno ksi_info.si_trapno
+#define ksi_overrun ksi_info.si_overrun
+#define ksi_timerid ksi_info.si_timerid
+#define ksi_mqd ksi_info.si_mqd
+
+/* bits for ksi_flags */
+#define KSI_TRAP 0x01 /* Generated by trap. */
+#define KSI_EXT 0x02 /* Externally managed ksi. */
+#define KSI_INS 0x04 /* Directly insert ksi, not the copy */
+#define KSI_SIGQ 0x08 /* Generated by sigqueue, might ret EGAIN. */
+#define KSI_HEAD 0x10 /* Insert into head, not tail. */
+#define KSI_COPYMASK (KSI_TRAP|KSI_SIGQ)
+
+#define KSI_ONQ(ksi) ((ksi)->ksi_sigq != NULL)
+
+typedef struct sigqueue {
+ sigset_t sq_signals; /* All pending signals. */
+ sigset_t sq_kill; /* Legacy depth 1 queue. */
+ TAILQ_HEAD(, ksiginfo) sq_list;/* Queued signal info. */
+ struct proc *sq_proc;
+ int sq_flags;
+} sigqueue_t;
+
+/* Flags for ksi_flags */
+#define SQ_INIT 0x01
+
+#ifdef _KERNEL
+
+/* Return nonzero if process p has an unmasked pending signal. */
+#define SIGPENDING(td) \
+ ((!SIGISEMPTY((td)->td_siglist) && \
+ !sigsetmasked(&(td)->td_siglist, &(td)->td_sigmask)) || \
+ (!SIGISEMPTY((td)->td_proc->p_siglist) && \
+ !sigsetmasked(&(td)->td_proc->p_siglist, &(td)->td_sigmask)))
+/*
+ * Return the value of the pseudo-expression ((*set & ~*mask) != 0). This
+ * is an optimized version of SIGISEMPTY() on a temporary variable
+ * containing SIGSETNAND(*set, *mask).
+ */
+static __inline int
+sigsetmasked(sigset_t *set, sigset_t *mask)
+{
+ int i;
+
+ for (i = 0; i < _SIG_WORDS; i++) {
+ if (set->__bits[i] & ~mask->__bits[i])
+ return (0);
+ }
+ return (1);
+}
+
+#define ksiginfo_init(ksi) \
+do { \
+ bzero(ksi, sizeof(ksiginfo_t)); \
+} while(0)
+
+#define ksiginfo_init_trap(ksi) \
+do { \
+ ksiginfo_t *kp = ksi; \
+ bzero(kp, sizeof(ksiginfo_t)); \
+ kp->ksi_flags |= KSI_TRAP; \
+} while(0)
+
+static __inline void
+ksiginfo_copy(ksiginfo_t *src, ksiginfo_t *dst)
+{
+ (dst)->ksi_info = src->ksi_info;
+ (dst)->ksi_flags = (src->ksi_flags & KSI_COPYMASK);
+}
+
+static __inline void
+ksiginfo_set_sigev(ksiginfo_t *dst, struct sigevent *sigev)
+{
+ dst->ksi_signo = sigev->sigev_signo;
+ dst->ksi_value = sigev->sigev_value;
+}
+
+struct pgrp;
+struct proc;
+struct sigio;
+struct thread;
+
+/*
+ * Lock the pointers for a sigio object in the underlying objects of
+ * a file descriptor.
+ */
+#define SIGIO_LOCK() mtx_lock(&sigio_lock)
+#define SIGIO_TRYLOCK() mtx_trylock(&sigio_lock)
+#define SIGIO_UNLOCK() mtx_unlock(&sigio_lock)
+#define SIGIO_LOCKED() mtx_owned(&sigio_lock)
+#define SIGIO_ASSERT(type) mtx_assert(&sigio_lock, type)
+
+extern struct mtx sigio_lock;
+
+/* Flags for kern_sigprocmask(). */
+#define SIGPROCMASK_OLD 0x0001
+#define SIGPROCMASK_PROC_LOCKED 0x0002
+#define SIGPROCMASK_PS_LOCKED 0x0004
+
+/*
+ * Modes for sigdeferstop(). Manages behaviour of
+ * thread_suspend_check() in the region delimited by
+ * sigdeferstop()/sigallowstop(). Must be restored to
+ * SIGDEFERSTOP_OFF before returning to userspace.
+ */
+#define SIGDEFERSTOP_NOP 0 /* continue doing whatever is done now */
+#define SIGDEFERSTOP_OFF 1 /* stop ignoring STOPs */
+#define SIGDEFERSTOP_SILENT 2 /* silently ignore STOPs */
+#define SIGDEFERSTOP_EINTR 3 /* ignore STOPs, return EINTR */
+#define SIGDEFERSTOP_ERESTART 4 /* ignore STOPs, return ERESTART */
+
+#define SIGDEFERSTOP_VAL_NCHG (-1) /* placeholder indicating no state change */
+int sigdeferstop_impl(int mode);
+void sigallowstop_impl(int prev);
+
+static inline int
+sigdeferstop(int mode)
+{
+
+ if (mode == SIGDEFERSTOP_NOP)
+ return (SIGDEFERSTOP_VAL_NCHG);
+ return (sigdeferstop_impl(mode));
+}
+
+static inline void
+sigallowstop(int prev)
+{
+
+ if (prev == SIGDEFERSTOP_VAL_NCHG)
+ return;
+ sigallowstop_impl(prev);
+}
+
+int cursig(struct thread *td);
+void execsigs(struct proc *p);
+void gsignal(int pgid, int sig, ksiginfo_t *ksi);
+void killproc(struct proc *p, char *why);
+ksiginfo_t * ksiginfo_alloc(int wait);
+void ksiginfo_free(ksiginfo_t *ksi);
+int pksignal(struct proc *p, int sig, ksiginfo_t *ksi);
+void pgsigio(struct sigio **sigiop, int sig, int checkctty);
+void pgsignal(struct pgrp *pgrp, int sig, int checkctty, ksiginfo_t *ksi);
+int postsig(int sig);
+void kern_psignal(struct proc *p, int sig);
+int ptracestop(struct thread *td, int sig);
+void sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *retmask);
+struct sigacts *sigacts_alloc(void);
+void sigacts_copy(struct sigacts *dest, struct sigacts *src);
+void sigacts_free(struct sigacts *ps);
+struct sigacts *sigacts_hold(struct sigacts *ps);
+int sigacts_shared(struct sigacts *ps);
+void sigexit(struct thread *td, int sig) __dead2;
+int sigev_findtd(struct proc *p, struct sigevent *sigev, struct thread **);
+int sig_ffs(sigset_t *set);
+void siginit(struct proc *p);
+void signotify(struct thread *td);
+void sigqueue_delete(struct sigqueue *queue, int sig);
+void sigqueue_delete_proc(struct proc *p, int sig);
+void sigqueue_flush(struct sigqueue *queue);
+void sigqueue_init(struct sigqueue *queue, struct proc *p);
+void sigqueue_take(ksiginfo_t *ksi);
+void tdksignal(struct thread *td, int sig, ksiginfo_t *ksi);
+int tdsendsignal(struct proc *p, struct thread *td, int sig,
+ ksiginfo_t *ksi);
+void tdsigcleanup(struct thread *td);
+void tdsignal(struct thread *td, int sig);
+void trapsignal(struct thread *td, ksiginfo_t *ksi);
+
+#endif /* _KERNEL */
+#else /* __rtems__ */
+typedef int ksiginfo_t;
+#endif /* __rtems__ */
+
+#endif /* !_SYS_SIGNALVAR_H_ */
diff --git a/freebsd/sys/sys/sleepqueue.h b/freebsd/sys/sys/sleepqueue.h
index 4c4ea651..d59dc7e5 100644
--- a/freebsd/sys/sys/sleepqueue.h
+++ b/freebsd/sys/sys/sleepqueue.h
@@ -83,8 +83,6 @@ struct thread;
#define SLEEPQ_SX 0x03 /* Used by an sx lock. */
#define SLEEPQ_LK 0x04 /* Used by a lockmgr. */
#define SLEEPQ_INTERRUPTIBLE 0x100 /* Sleep is interruptible. */
-#define SLEEPQ_STOP_ON_BDRY 0x200 /* Stop sleeping thread on
- user mode boundary */
void init_sleepqueues(void);
int sleepq_abort(struct thread *td, int intrval);
@@ -98,7 +96,10 @@ struct sleepqueue *sleepq_lookup(void *wchan);
void sleepq_release(void *wchan);
void sleepq_remove(struct thread *td, void *wchan);
int sleepq_signal(void *wchan, int flags, int pri, int queue);
-void sleepq_set_timeout(void *wchan, int timo);
+void sleepq_set_timeout_sbt(void *wchan, sbintime_t sbt,
+ sbintime_t pr, int flags);
+#define sleepq_set_timeout(wchan, timo) \
+ sleepq_set_timeout_sbt((wchan), tick_sbt * (timo), 0, C_HARDCLOCK)
u_int sleepq_sleepcnt(void *wchan, int queue);
int sleepq_timedwait(void *wchan, int pri);
int sleepq_timedwait_sig(void *wchan, int pri);
@@ -106,5 +107,11 @@ int sleepq_type(void *wchan);
void sleepq_wait(void *wchan, int pri);
int sleepq_wait_sig(void *wchan, int pri);
+#ifdef STACK
+struct sbuf;
+int sleepq_sbuf_print_stacks(struct sbuf *sb, void *wchan, int queue,
+ int *count_stacks_printed);
+#endif
+
#endif /* _KERNEL */
#endif /* !_SYS_SLEEPQUEUE_H_ */
diff --git a/freebsd/sys/sys/smp.h b/freebsd/sys/sys/smp.h
index 776fc3a1..96a3fe59 100644
--- a/freebsd/sys/sys/smp.h
+++ b/freebsd/sys/sys/smp.h
@@ -17,9 +17,52 @@
#ifndef LOCORE
#include <rtems/bsd/sys/cpuset.h>
+#include <sys/queue.h>
/*
- * Topology of a NUMA or HTT system.
+ * Types of nodes in the topological tree.
+ */
+typedef enum {
+ /* No node has this type; can be used in topo API calls. */
+ TOPO_TYPE_DUMMY,
+ /* Processing unit aka computing unit aka logical CPU. */
+ TOPO_TYPE_PU,
+ /* Physical subdivision of a package. */
+ TOPO_TYPE_CORE,
+ /* CPU L1/L2/L3 cache. */
+ TOPO_TYPE_CACHE,
+ /* Package aka chip, equivalent to socket. */
+ TOPO_TYPE_PKG,
+ /* NUMA node. */
+ TOPO_TYPE_NODE,
+ /* Other logical or physical grouping of PUs. */
+ /* E.g. PUs on the same dye, or PUs sharing an FPU. */
+ TOPO_TYPE_GROUP,
+ /* The whole system. */
+ TOPO_TYPE_SYSTEM
+} topo_node_type;
+
+/* Hardware indenitifier of a topology component. */
+typedef unsigned int hwid_t;
+/* Logical CPU idenitifier. */
+typedef int cpuid_t;
+
+/* A node in the topology. */
+struct topo_node {
+ struct topo_node *parent;
+ TAILQ_HEAD(topo_children, topo_node) children;
+ TAILQ_ENTRY(topo_node) siblings;
+ cpuset_t cpuset;
+ topo_node_type type;
+ uintptr_t subtype;
+ hwid_t hwid;
+ cpuid_t id;
+ int nchildren;
+ int cpu_count;
+};
+
+/*
+ * Scheduling topology of a NUMA or SMP system.
*
* The top level topology is an array of pointers to groups. Each group
* contains a bitmask of cpus in its group or subgroups. It may also
@@ -52,6 +95,8 @@ typedef struct cpu_group *cpu_group_t;
#define CG_SHARE_L2 2
#define CG_SHARE_L3 3
+#define MAX_CACHE_LEVELS CG_SHARE_L3
+
/*
* Behavior modifiers for load balancing and affinity.
*/
@@ -60,10 +105,29 @@ typedef struct cpu_group *cpu_group_t;
#define CG_FLAG_THREAD (CG_FLAG_HTT | CG_FLAG_SMT) /* Any threading. */
/*
- * Convenience routines for building topologies.
+ * Convenience routines for building and traversing topologies.
*/
#ifdef SMP
+void topo_init_node(struct topo_node *node);
+void topo_init_root(struct topo_node *root);
+struct topo_node * topo_add_node_by_hwid(struct topo_node *parent, int hwid,
+ topo_node_type type, uintptr_t subtype);
+struct topo_node * topo_find_node_by_hwid(struct topo_node *parent, int hwid,
+ topo_node_type type, uintptr_t subtype);
+void topo_promote_child(struct topo_node *child);
+struct topo_node * topo_next_node(struct topo_node *top,
+ struct topo_node *node);
+struct topo_node * topo_next_nonchild_node(struct topo_node *top,
+ struct topo_node *node);
+void topo_set_pu_id(struct topo_node *node, cpuid_t id);
+int topo_analyze(struct topo_node *topo_root, int all, int *pkg_count,
+ int *cores_per_pkg, int *thrs_per_core);
+
+#define TOPO_FOREACH(i, root) \
+ for (i = root; i != NULL; i = topo_next_node(root, i))
+
struct cpu_group *smp_topo(void);
+struct cpu_group *smp_topo_alloc(u_int count);
struct cpu_group *smp_topo_none(void);
struct cpu_group *smp_topo_1level(int l1share, int l1count, int l1flags);
struct cpu_group *smp_topo_2level(int l2share, int l2count, int l1share,
@@ -71,10 +135,10 @@ struct cpu_group *smp_topo_2level(int l2share, int l2count, int l1share,
struct cpu_group *smp_topo_find(struct cpu_group *top, int cpu);
extern void (*cpustop_restartfunc)(void);
-extern int smp_active;
extern int smp_cpus;
extern volatile cpuset_t started_cpus;
extern volatile cpuset_t stopped_cpus;
+extern volatile cpuset_t suspended_cpus;
extern cpuset_t hlt_cpus_mask;
extern cpuset_t logical_cpus_mask;
#endif /* SMP */
@@ -86,6 +150,7 @@ extern int mp_ncpus;
extern volatile int smp_started;
extern cpuset_t all_cpus;
+extern cpuset_t cpuset_domain[MAXMEMDOM]; /* CPUs in each NUMA domain. */
#else /* __rtems__ */
#define mp_maxid 0U
#define mp_maxcpus 1
@@ -151,7 +216,7 @@ cpu_next(int i)
* cpu_mp_start() will be called so that MP can be enabled. This function
* should do things such as startup secondary processors. It should also
* setup mp_ncpus, all_cpus, and smp_cpus. It should also ensure that
- * smp_active and smp_started are initialized at the appropriate time.
+ * smp_started is initialized at the appropriate time.
* Once cpu_mp_start() returns, machine independent MP startup code will be
* executed and a simple message will be output to the console. Finally,
* cpu_mp_announce() will be called so that machine dependent messages about
@@ -176,11 +241,16 @@ int stop_cpus(cpuset_t);
int stop_cpus_hard(cpuset_t);
#if defined(__amd64__) || defined(__i386__)
int suspend_cpus(cpuset_t);
+int resume_cpus(cpuset_t);
#endif
+
void smp_rendezvous_action(void);
extern struct mtx smp_ipi_mtx;
#endif /* SMP */
+
+int quiesce_all_cpus(const char *, int);
+int quiesce_cpus(cpuset_t, const char *, int);
void smp_no_rendevous_barrier(void *);
void smp_rendezvous(void (*)(void *),
void (*)(void *),
diff --git a/freebsd/sys/sys/sockbuf.h b/freebsd/sys/sys/sockbuf.h
index 76197aea..2c03b3ed 100644
--- a/freebsd/sys/sys/sockbuf.h
+++ b/freebsd/sys/sys/sockbuf.h
@@ -36,6 +36,7 @@
#include <sys/_lock.h>
#include <sys/_mutex.h>
#include <sys/_sx.h>
+#include <sys/_task.h>
#define SB_MAX (2*1024*1024) /* default for max chars in sockbuf */
@@ -52,6 +53,8 @@
#define SB_NOCOALESCE 0x200 /* don't coalesce new data into existing mbufs */
#define SB_IN_TOE 0x400 /* socket buffer is in the middle of an operation */
#define SB_AUTOSIZE 0x800 /* automatically size socket buffer */
+#define SB_STOP 0x1000 /* backpressure indicator */
+#define SB_AIO_RUNNING 0x2000 /* AIO operation running */
#define SBS_CANTSENDMORE 0x0010 /* can't send more data to peer */
#define SBS_CANTRCVMORE 0x0020 /* can't receive more data from peer */
@@ -76,31 +79,40 @@ struct xsockbuf {
/*
* Variables for socket buffering.
+ *
+ * Locking key to struct sockbuf:
+ * (a) locked by SOCKBUF_LOCK().
*/
struct sockbuf {
struct selinfo sb_sel; /* process selecting read/write */
struct mtx sb_mtx; /* sockbuf lock */
struct sx sb_sx; /* prevent I/O interlacing */
- short sb_state; /* (c/d) socket state on sockbuf */
+ short sb_state; /* (a) socket state on sockbuf */
#define sb_startzero sb_mb
- struct mbuf *sb_mb; /* (c/d) the mbuf chain */
- struct mbuf *sb_mbtail; /* (c/d) the last mbuf in the chain */
- struct mbuf *sb_lastrecord; /* (c/d) first mbuf of last
+ struct mbuf *sb_mb; /* (a) the mbuf chain */
+ struct mbuf *sb_mbtail; /* (a) the last mbuf in the chain */
+ struct mbuf *sb_lastrecord; /* (a) first mbuf of last
* record in socket buffer */
- struct mbuf *sb_sndptr; /* (c/d) pointer into mbuf chain */
- u_int sb_sndptroff; /* (c/d) byte offset of ptr into chain */
- u_int sb_cc; /* (c/d) actual chars in buffer */
- u_int sb_hiwat; /* (c/d) max actual char count */
- u_int sb_mbcnt; /* (c/d) chars of mbufs used */
- u_int sb_mcnt; /* (c/d) number of mbufs in buffer */
- u_int sb_ccnt; /* (c/d) number of clusters in buffer */
- u_int sb_mbmax; /* (c/d) max chars of mbufs to use */
- u_int sb_ctl; /* (c/d) non-data chars in buffer */
- int sb_lowat; /* (c/d) low water mark */
- int sb_timeo; /* (c/d) timeout for read/write */
- short sb_flags; /* (c/d) flags, see below */
- int (*sb_upcall)(struct socket *, void *, int); /* (c/d) */
- void *sb_upcallarg; /* (c/d) */
+ struct mbuf *sb_sndptr; /* (a) pointer into mbuf chain */
+ struct mbuf *sb_fnrdy; /* (a) pointer to first not ready buffer */
+ u_int sb_sndptroff; /* (a) byte offset of ptr into chain */
+ u_int sb_acc; /* (a) available chars in buffer */
+ u_int sb_ccc; /* (a) claimed chars in buffer */
+ u_int sb_hiwat; /* (a) max actual char count */
+ u_int sb_mbcnt; /* (a) chars of mbufs used */
+ u_int sb_mcnt; /* (a) number of mbufs in buffer */
+ u_int sb_ccnt; /* (a) number of clusters in buffer */
+ u_int sb_mbmax; /* (a) max chars of mbufs to use */
+ u_int sb_ctl; /* (a) non-data chars in buffer */
+ int sb_lowat; /* (a) low water mark */
+ sbintime_t sb_timeo; /* (a) timeout for read/write */
+ short sb_flags; /* (a) flags, see below */
+ int (*sb_upcall)(struct socket *, void *, int); /* (a) */
+ void *sb_upcallarg; /* (a) */
+#ifndef __rtems__
+ TAILQ_HEAD(, kaiocb) sb_aiojobq; /* (a) pending AIO ops */
+ struct task sb_aiotask; /* AIO task */
+#endif /* __rtems__ */
};
#ifdef _KERNEL
@@ -119,10 +131,17 @@ struct sockbuf {
#define SOCKBUF_LOCK_ASSERT(_sb) mtx_assert(SOCKBUF_MTX(_sb), MA_OWNED)
#define SOCKBUF_UNLOCK_ASSERT(_sb) mtx_assert(SOCKBUF_MTX(_sb), MA_NOTOWNED)
-void sbappend(struct sockbuf *sb, struct mbuf *m);
-void sbappend_locked(struct sockbuf *sb, struct mbuf *m);
-void sbappendstream(struct sockbuf *sb, struct mbuf *m);
-void sbappendstream_locked(struct sockbuf *sb, struct mbuf *m);
+/*
+ * Socket buffer private mbuf(9) flags.
+ */
+#define M_NOTREADY M_PROTO1 /* m_data not populated yet */
+#define M_BLOCKED M_PROTO2 /* M_NOTREADY in front of m */
+#define M_NOTAVAIL (M_NOTREADY | M_BLOCKED)
+
+void sbappend(struct sockbuf *sb, struct mbuf *m, int flags);
+void sbappend_locked(struct sockbuf *sb, struct mbuf *m, int flags);
+void sbappendstream(struct sockbuf *sb, struct mbuf *m, int flags);
+void sbappendstream_locked(struct sockbuf *sb, struct mbuf *m, int flags);
int sbappendaddr(struct sockbuf *sb, const struct sockaddr *asa,
struct mbuf *m0, struct mbuf *control);
int sbappendaddr_locked(struct sockbuf *sb, const struct sockaddr *asa,
@@ -135,13 +154,14 @@ int sbappendcontrol_locked(struct sockbuf *sb, struct mbuf *m0,
struct mbuf *control);
void sbappendrecord(struct sockbuf *sb, struct mbuf *m0);
void sbappendrecord_locked(struct sockbuf *sb, struct mbuf *m0);
-void sbcheck(struct sockbuf *sb);
void sbcompress(struct sockbuf *sb, struct mbuf *m, struct mbuf *n);
struct mbuf *
sbcreatecontrol(caddr_t p, int size, int type, int level);
void sbdestroy(struct sockbuf *sb, struct socket *so);
void sbdrop(struct sockbuf *sb, int len);
void sbdrop_locked(struct sockbuf *sb, int len);
+struct mbuf *
+ sbcut_locked(struct sockbuf *sb, int len);
void sbdroprecord(struct sockbuf *sb);
void sbdroprecord_locked(struct sockbuf *sb);
void sbflush(struct sockbuf *sb);
@@ -161,47 +181,59 @@ void sbtoxsockbuf(struct sockbuf *sb, struct xsockbuf *xsb);
int sbwait(struct sockbuf *sb);
int sblock(struct sockbuf *sb, int flags);
void sbunlock(struct sockbuf *sb);
+void sballoc(struct sockbuf *, struct mbuf *);
+void sbfree(struct sockbuf *, struct mbuf *);
+int sbready(struct sockbuf *, struct mbuf *, int);
+
+/*
+ * Return how much data is available to be taken out of socket
+ * buffer right now.
+ */
+static inline u_int
+sbavail(struct sockbuf *sb)
+{
+
+#if 0
+ SOCKBUF_LOCK_ASSERT(sb);
+#endif
+ return (sb->sb_acc);
+}
+
+/*
+ * Return how much data sits there in the socket buffer
+ * It might be that some data is not yet ready to be read.
+ */
+static inline u_int
+sbused(struct sockbuf *sb)
+{
+
+#if 0
+ SOCKBUF_LOCK_ASSERT(sb);
+#endif
+ return (sb->sb_ccc);
+}
/*
* How much space is there in a socket buffer (so->so_snd or so->so_rcv)?
* This is problematical if the fields are unsigned, as the space might
- * still be negative (cc > hiwat or mbcnt > mbmax). Should detect
- * overflow and return 0. Should use "lmin" but it doesn't exist now.
+ * still be negative (ccc > hiwat or mbcnt > mbmax).
*/
-#define sbspace(sb) \
- ((long) imin((int)((sb)->sb_hiwat - (sb)->sb_cc), \
- (int)((sb)->sb_mbmax - (sb)->sb_mbcnt)))
-
-/* adjust counters in sb reflecting allocation of m */
-#define sballoc(sb, m) { \
- (sb)->sb_cc += (m)->m_len; \
- if ((m)->m_type != MT_DATA && (m)->m_type != MT_OOBDATA) \
- (sb)->sb_ctl += (m)->m_len; \
- (sb)->sb_mbcnt += MSIZE; \
- (sb)->sb_mcnt += 1; \
- if ((m)->m_flags & M_EXT) { \
- (sb)->sb_mbcnt += (m)->m_ext.ext_size; \
- (sb)->sb_ccnt += 1; \
- } \
-}
+static inline long
+sbspace(struct sockbuf *sb)
+{
+ int bleft, mleft; /* size should match sockbuf fields */
+
+#if 0
+ SOCKBUF_LOCK_ASSERT(sb);
+#endif
-/* adjust counters in sb reflecting freeing of m */
-#define sbfree(sb, m) { \
- (sb)->sb_cc -= (m)->m_len; \
- if ((m)->m_type != MT_DATA && (m)->m_type != MT_OOBDATA) \
- (sb)->sb_ctl -= (m)->m_len; \
- (sb)->sb_mbcnt -= MSIZE; \
- (sb)->sb_mcnt -= 1; \
- if ((m)->m_flags & M_EXT) { \
- (sb)->sb_mbcnt -= (m)->m_ext.ext_size; \
- (sb)->sb_ccnt -= 1; \
- } \
- if ((sb)->sb_sndptr == (m)) { \
- (sb)->sb_sndptr = NULL; \
- (sb)->sb_sndptroff = 0; \
- } \
- if ((sb)->sb_sndptroff != 0) \
- (sb)->sb_sndptroff -= (m)->m_len; \
+ if (sb->sb_flags & SB_STOP)
+ return(0);
+
+ bleft = sb->sb_hiwat - sb->sb_ccc;
+ mleft = sb->sb_mbmax - sb->sb_mbcnt;
+
+ return ((bleft < mleft) ? bleft : mleft);
}
#define SB_EMPTY_FIXUP(sb) do { \
@@ -213,13 +245,15 @@ void sbunlock(struct sockbuf *sb);
#ifdef SOCKBUF_DEBUG
void sblastrecordchk(struct sockbuf *, const char *, int);
-#define SBLASTRECORDCHK(sb) sblastrecordchk((sb), __FILE__, __LINE__)
-
void sblastmbufchk(struct sockbuf *, const char *, int);
+void sbcheck(struct sockbuf *, const char *, int);
+#define SBLASTRECORDCHK(sb) sblastrecordchk((sb), __FILE__, __LINE__)
#define SBLASTMBUFCHK(sb) sblastmbufchk((sb), __FILE__, __LINE__)
+#define SBCHECK(sb) sbcheck((sb), __FILE__, __LINE__)
#else
-#define SBLASTRECORDCHK(sb) /* nothing */
-#define SBLASTMBUFCHK(sb) /* nothing */
+#define SBLASTRECORDCHK(sb) do {} while (0)
+#define SBLASTMBUFCHK(sb) do {} while (0)
+#define SBCHECK(sb) do {} while (0)
#endif /* SOCKBUF_DEBUG */
#endif /* _KERNEL */
diff --git a/freebsd/sys/sys/socket.h b/freebsd/sys/sys/socket.h
index fb2a2788..f23b5f69 100644
--- a/freebsd/sys/sys/socket.h
+++ b/freebsd/sys/sys/socket.h
@@ -84,6 +84,16 @@ typedef __uid_t uid_t;
#endif
#endif
+#ifndef _UINT32_T_DECLARED
+typedef __uint32_t uint32_t;
+#define _UINT32_T_DECLARED
+#endif
+
+#ifndef _UINTPTR_T_DECLARED
+typedef __uintptr_t uintptr_t;
+#define _UINTPTR_T_DECLARED
+#endif
+
/*
* Types
*/
@@ -95,6 +105,14 @@ typedef __uid_t uid_t;
#endif
#define SOCK_SEQPACKET 5 /* sequenced packet stream */
+#if __BSD_VISIBLE
+/*
+ * Creation flags, OR'ed into socket() and socketpair() type argument.
+ */
+#define SOCK_CLOEXEC 0x10000000
+#define SOCK_NONBLOCK 0x20000000
+#endif
+
/*
* Option flags per-socket.
*/
@@ -346,6 +364,7 @@ struct sockproto {
#define PF_SCLUSTER AF_SCLUSTER
#define PF_ARP AF_ARP
#define PF_BLUETOOTH AF_BLUETOOTH
+#define PF_IEEE80211 AF_IEEE80211
#define PF_INET_SDP AF_INET_SDP
#define PF_INET6_SDP AF_INET6_SDP
@@ -357,47 +376,8 @@ struct sockproto {
* Second level is protocol family.
* Third level is protocol number.
*
- * Further levels are defined by the individual families below.
+ * Further levels are defined by the individual families.
*/
-#define NET_MAXID AF_MAX
-
-#define CTL_NET_NAMES { \
- { 0, 0 }, \
- { "unix", CTLTYPE_NODE }, \
- { "inet", CTLTYPE_NODE }, \
- { "implink", CTLTYPE_NODE }, \
- { "pup", CTLTYPE_NODE }, \
- { "chaos", CTLTYPE_NODE }, \
- { "xerox_ns", CTLTYPE_NODE }, \
- { "iso", CTLTYPE_NODE }, \
- { "emca", CTLTYPE_NODE }, \
- { "datakit", CTLTYPE_NODE }, \
- { "ccitt", CTLTYPE_NODE }, \
- { "ibm_sna", CTLTYPE_NODE }, \
- { "decnet", CTLTYPE_NODE }, \
- { "dec_dli", CTLTYPE_NODE }, \
- { "lat", CTLTYPE_NODE }, \
- { "hylink", CTLTYPE_NODE }, \
- { "appletalk", CTLTYPE_NODE }, \
- { "route", CTLTYPE_NODE }, \
- { "link_layer", CTLTYPE_NODE }, \
- { "xtp", CTLTYPE_NODE }, \
- { "coip", CTLTYPE_NODE }, \
- { "cnt", CTLTYPE_NODE }, \
- { "rtip", CTLTYPE_NODE }, \
- { "ipx", CTLTYPE_NODE }, \
- { "sip", CTLTYPE_NODE }, \
- { "pip", CTLTYPE_NODE }, \
- { "isdn", CTLTYPE_NODE }, \
- { "key", CTLTYPE_NODE }, \
- { "inet6", CTLTYPE_NODE }, \
- { "natm", CTLTYPE_NODE }, \
- { "atm", CTLTYPE_NODE }, \
- { "hdrcomplete", CTLTYPE_NODE }, \
- { "netgraph", CTLTYPE_NODE }, \
- { "snp", CTLTYPE_NODE }, \
- { "scp", CTLTYPE_NODE }, \
-}
/*
* PF_ROUTE - Routing table
@@ -413,16 +393,6 @@ struct sockproto {
#define NET_RT_IFMALIST 4 /* return multicast address list */
#define NET_RT_IFLISTL 5 /* Survey interface list, using 'l'en
* versions of msghdr structs. */
-#define NET_RT_MAXID 6
-
-#define CTL_NET_RT_NAMES { \
- { 0, 0 }, \
- { "dump", CTLTYPE_STRUCT }, \
- { "flags", CTLTYPE_STRUCT }, \
- { "iflist", CTLTYPE_STRUCT }, \
- { "ifmalist", CTLTYPE_STRUCT }, \
- { "iflistl", CTLTYPE_STRUCT }, \
-}
#endif /* __BSD_VISIBLE */
/*
@@ -451,19 +421,21 @@ struct msghdr {
#define MSG_TRUNC 0x10 /* data discarded before delivery */
#define MSG_CTRUNC 0x20 /* control data lost before delivery */
#define MSG_WAITALL 0x40 /* wait for full request or error */
-#define MSG_NOTIFICATION 0x2000 /* SCTP notification */
+#if __POSIX_VISIBLE >= 200809
+#define MSG_NOSIGNAL 0x20000 /* do not generate SIGPIPE on EOF */
+#endif
#if __BSD_VISIBLE
#define MSG_DONTWAIT 0x80 /* this message should be nonblocking */
#define MSG_EOF 0x100 /* data completes connection */
+#define MSG_NOTIFICATION 0x2000 /* SCTP notification */
#define MSG_NBIO 0x4000 /* FIONBIO mode, used by fifofs */
#define MSG_COMPAT 0x8000 /* used in sendit() */
+#define MSG_CMSG_CLOEXEC 0x40000 /* make received fds close-on-exec */
+#define MSG_WAITFORONE 0x80000 /* for recvmmsg() */
#endif
#ifdef _KERNEL
#define MSG_SOCALLBCK 0x10000 /* for use by socket callbacks - soreceive (TCP) */
#endif
-#if __BSD_VISIBLE
-#define MSG_NOSIGNAL 0x20000 /* do not generate SIGPIPE on EOF */
-#endif
/*
* Header for ancillary data objects in msg_control buffer.
@@ -528,7 +500,7 @@ struct sockcred {
/* given pointer to struct cmsghdr, return pointer to next cmsghdr */
#define CMSG_NXTHDR(mhdr, cmsg) \
- ((char *)(cmsg) == NULL ? CMSG_FIRSTHDR(mhdr) : \
+ ((char *)(cmsg) == (char *)0 ? CMSG_FIRSTHDR(mhdr) : \
((char *)(cmsg) + _ALIGN(((struct cmsghdr *)(cmsg))->cmsg_len) + \
_ALIGN(sizeof(struct cmsghdr)) > \
(char *)(mhdr)->msg_control + (mhdr)->msg_controllen) ? \
@@ -543,7 +515,7 @@ struct sockcred {
#define CMSG_FIRSTHDR(mhdr) \
((mhdr)->msg_controllen >= sizeof(struct cmsghdr) ? \
(struct cmsghdr *)(mhdr)->msg_control : \
- (struct cmsghdr *)NULL)
+ (struct cmsghdr *)0)
#if __BSD_VISIBLE
/* RFC 2292 additions */
@@ -592,10 +564,13 @@ struct omsghdr {
#define SHUT_WR 1 /* shut down the writing side */
#define SHUT_RDWR 2 /* shut down both sides */
+#if __BSD_VISIBLE
+/* for SCTP */
/* we cheat and use the SHUT_XX defines for these */
#define PRU_FLUSH_RD SHUT_RD
#define PRU_FLUSH_WR SHUT_WR
#define PRU_FLUSH_RDWR SHUT_RDWR
+#endif
#if __BSD_VISIBLE
@@ -613,9 +588,23 @@ struct sf_hdtr {
* Sendfile-specific flag(s)
*/
#define SF_NODISKIO 0x00000001
-#define SF_MNOWAIT 0x00000002
+#define SF_MNOWAIT 0x00000002 /* obsolete */
#define SF_SYNC 0x00000004
-#endif
+#define SF_NOCACHE 0x00000010
+#define SF_FLAGS(rh, flags) (((rh) << 16) | (flags))
+
+#ifdef _KERNEL
+#define SF_READAHEAD(flags) ((flags) >> 16)
+#endif /* _KERNEL */
+
+/*
+ * Sendmmsg/recvmmsg specific structure(s)
+ */
+struct mmsghdr {
+ struct msghdr msg_hdr; /* message header */
+ ssize_t msg_len; /* message length */
+};
+#endif /* __BSD_VISIBLE */
#ifndef _KERNEL
@@ -625,6 +614,11 @@ __BEGIN_DECLS
int accept(int, struct sockaddr * __restrict, socklen_t * __restrict);
int bind(int, const struct sockaddr *, socklen_t);
int connect(int, const struct sockaddr *, socklen_t);
+#if __BSD_VISIBLE
+int accept4(int, struct sockaddr * __restrict, socklen_t * __restrict, int);
+int bindat(int, int, const struct sockaddr *, socklen_t);
+int connectat(int, int, const struct sockaddr *, socklen_t);
+#endif
int getpeername(int, struct sockaddr * __restrict, socklen_t * __restrict);
int getsockname(int, struct sockaddr * __restrict, socklen_t * __restrict);
int getsockopt(int, int, int, void * __restrict, socklen_t * __restrict);
@@ -632,12 +626,18 @@ int listen(int, int);
ssize_t recv(int, void *, size_t, int);
ssize_t recvfrom(int, void *, size_t, int, struct sockaddr * __restrict, socklen_t * __restrict);
ssize_t recvmsg(int, struct msghdr *, int);
+#if __BSD_VISIBLE
+struct timespec;
+ssize_t recvmmsg(int, struct mmsghdr * __restrict, size_t, int,
+ const struct timespec * __restrict);
+#endif
ssize_t send(int, const void *, size_t, int);
ssize_t sendto(int, const void *,
size_t, int, const struct sockaddr *, socklen_t);
ssize_t sendmsg(int, const struct msghdr *, int);
#if __BSD_VISIBLE
int sendfile(int, int, off_t, size_t, struct sf_hdtr *, off_t *, int);
+ssize_t sendmmsg(int, struct mmsghdr * __restrict, size_t, int);
int setfib(int);
#endif
int setsockopt(int, int, int, const void *, socklen_t);
diff --git a/freebsd/sys/sys/socketvar.h b/freebsd/sys/sys/socketvar.h
index 94c3b24e..72eaa998 100644
--- a/freebsd/sys/sys/socketvar.h
+++ b/freebsd/sys/sys/socketvar.h
@@ -38,10 +38,12 @@
#include <sys/selinfo.h> /* for struct selinfo */
#include <sys/_lock.h>
#include <sys/_mutex.h>
+#include <sys/osd.h>
#include <sys/_sx.h>
#include <sys/sockbuf.h>
#include <sys/sockstate.h>
#ifdef _KERNEL
+#include <sys/caprights.h>
#include <sys/sockopt.h>
#endif
@@ -62,7 +64,6 @@ struct socket;
* (a) constant after allocation, no locking required.
* (b) locked by SOCK_LOCK(so).
* (c) locked by SOCKBUF_LOCK(&so->so_rcv).
- * (d) locked by SOCKBUF_LOCK(&so->so_snd).
* (e) locked by ACCEPT_LOCK().
* (f) not locked since integer reads/writes are atomic.
* (g) used only as a sleep/wakeup address, no value.
@@ -76,7 +77,7 @@ struct socket {
short so_state; /* (b) internal state flags SS_* */
int so_qstate; /* (e) internal state flags SQ_* */
void *so_pcb; /* protocol control block */
- struct vnet *so_vnet; /* network stack instance */
+ struct vnet *so_vnet; /* (a) network stack instance */
struct protosw *so_proto; /* (a) protocol handle */
/*
* Variables for connection queuing.
@@ -93,16 +94,15 @@ struct socket {
TAILQ_HEAD(, socket) so_incomp; /* (e) queue of partial unaccepted connections */
TAILQ_HEAD(, socket) so_comp; /* (e) queue of complete unaccepted connections */
TAILQ_ENTRY(socket) so_list; /* (e) list of unaccepted connections */
- u_short so_qlen; /* (e) number of unaccepted connections */
- u_short so_incqlen; /* (e) number of unaccepted incomplete
+ u_int so_qlen; /* (e) number of unaccepted connections */
+ u_int so_incqlen; /* (e) number of unaccepted incomplete
connections */
- u_short so_qlimit; /* (e) max number queued connections */
+ u_int so_qlimit; /* (e) max number queued connections */
short so_timeo; /* (g) connection timeout */
u_short so_error; /* (f) error affecting connection */
struct sigio *so_sigio; /* [sg] information for async I/O or
out of band data (SIGURG) */
u_long so_oobmark; /* (c) chars to oob mark */
- TAILQ_HEAD(, aiocblist) so_aiojobq; /* AIO ops waiting on socket */
struct sockbuf so_rcv, so_snd;
@@ -117,6 +117,7 @@ struct socket {
void *so_accept_filter_arg; /* saved filter args */
char *so_accept_filter_str; /* saved user args */
} *so_accf;
+ struct osd osd; /* Object Specific extensions */
/*
* so_fibnum, so_user_cookie and friends can be used to attach
* some user-specified metadata to a socket, which then can be
@@ -125,6 +126,9 @@ struct socket {
*/
int so_fibnum; /* routing domain for this socket */
uint32_t so_user_cookie;
+
+ void *so_pspare[2]; /* packet pacing / general use */
+ int so_ispare[2]; /* packet pacing / general use */
};
/*
@@ -169,9 +173,9 @@ struct xsocket {
caddr_t so_pcb; /* another convenient handle */
int xso_protocol;
int xso_family;
- u_short so_qlen;
- u_short so_incqlen;
- u_short so_qlimit;
+ u_int so_qlen;
+ u_int so_incqlen;
+ u_int so_qlimit;
short so_timeo;
u_short so_error;
pid_t so_pgid;
@@ -205,7 +209,7 @@ struct xsocket {
/* can we read something from so? */
#define soreadabledata(so) \
- ((so)->so_rcv.sb_cc >= (so)->so_rcv.sb_lowat || \
+ (sbavail(&(so)->so_rcv) >= (so)->so_rcv.sb_lowat || \
!TAILQ_EMPTY(&(so)->so_comp) || (so)->so_error)
#define soreadable(so) \
(soreadabledata(so) || ((so)->so_rcv.sb_state & SBS_CANTRCVMORE))
@@ -292,11 +296,32 @@ MALLOC_DECLARE(M_PCB);
MALLOC_DECLARE(M_SONAME);
#endif
+/*
+ * Socket specific helper hook point identifiers
+ * Do not leave holes in the sequence, hook registration is a loop.
+ */
+#define HHOOK_SOCKET_OPT 0
+#define HHOOK_SOCKET_CREATE 1
+#define HHOOK_SOCKET_RCV 2
+#define HHOOK_SOCKET_SND 3
+#define HHOOK_FILT_SOREAD 4
+#define HHOOK_FILT_SOWRITE 5
+#define HHOOK_SOCKET_CLOSE 6
+#define HHOOK_SOCKET_LAST HHOOK_SOCKET_CLOSE
+
+struct socket_hhook_data {
+ struct socket *so;
+ struct mbuf *m;
+ void *hctx; /* hook point specific data*/
+ int status;
+};
+
extern int maxsockets;
extern u_long sb_max;
-extern struct uma_zone *socket_zone;
extern so_gen_t so_gencnt;
+struct file;
+struct filedesc;
struct mbuf;
struct sockaddr;
struct ucred;
@@ -313,16 +338,23 @@ struct uio;
/*
* From uipc_socket and friends
*/
-int sockargs(struct mbuf **mp, caddr_t buf, int buflen, int type);
int getsockaddr(struct sockaddr **namp, caddr_t uaddr, size_t len);
+int getsock_cap(struct thread *td, int fd, cap_rights_t *rightsp,
+ struct file **fpp, u_int *fflagp);
void soabort(struct socket *so);
int soaccept(struct socket *so, struct sockaddr **nam);
+void soaio_enqueue(struct task *task);
+void soaio_rcv(void *context, int pending);
+void soaio_snd(void *context, int pending);
int socheckuid(struct socket *so, uid_t uid);
int sobind(struct socket *so, struct sockaddr *nam, struct thread *td);
+int sobindat(int fd, struct socket *so, struct sockaddr *nam,
+ struct thread *td);
int soclose(struct socket *so);
int soconnect(struct socket *so, struct sockaddr *nam, struct thread *td);
+int soconnectat(int fd, struct socket *so, struct sockaddr *nam,
+ struct thread *td);
int soconnect2(struct socket *so1, struct socket *so2);
-int socow_setup(struct mbuf *m0, struct uio *uio);
int socreate(int dom, struct socket **aso, int type, int proto,
struct ucred *cred, struct thread *td);
int sodisconnect(struct socket *so);
@@ -368,6 +400,11 @@ void soupcall_clear(struct socket *so, int which);
void soupcall_set(struct socket *so, int which,
int (*func)(struct socket *, void *, int), void *arg);
void sowakeup(struct socket *so, struct sockbuf *sb);
+#ifndef __rtems__
+void sowakeup_aio(struct socket *so, struct sockbuf *sb);
+#else /* __rtems__ */
+#define sowakeup_aio(so, sb) (void)0
+#endif /* __rtems__ */
int selsocket(struct socket *so, int events, struct timeval *tv,
struct thread *td);
diff --git a/freebsd/sys/sys/stdint.h b/freebsd/sys/sys/stdint.h
index 4c3bbd8e..2b253137 100644
--- a/freebsd/sys/sys/stdint.h
+++ b/freebsd/sys/sys/stdint.h
@@ -58,21 +58,16 @@ typedef __uint_fast16_t uint_fast16_t;
typedef __uint_fast32_t uint_fast32_t;
typedef __uint_fast64_t uint_fast64_t;
-#ifndef _INTMAX_T_DECLARED
-typedef __intmax_t intmax_t;
-#define _INTMAX_T_DECLARED
-#endif
-#ifndef _UINTMAX_T_DECLARED
-typedef __uintmax_t uintmax_t;
-#define _UINTMAX_T_DECLARED
-#endif
-
/* GNU and Darwin define this and people seem to think it's portable */
#if defined(UINTPTR_MAX) && defined(UINT64_MAX) && (UINTPTR_MAX == UINT64_MAX)
#define __WORDSIZE 64
#else
#define __WORDSIZE 32
#endif
+
+/* Limits of wchar_t. */
+#define WCHAR_MIN __WCHAR_MIN
+#define WCHAR_MAX __WCHAR_MAX
#endif /* __rtems__ */
#endif /* !_SYS_STDINT_H_ */
diff --git a/freebsd/sys/sys/sx.h b/freebsd/sys/sys/sx.h
index 53beea07..c285fa77 100644
--- a/freebsd/sys/sys/sx.h
+++ b/freebsd/sys/sys/sx.h
@@ -45,7 +45,7 @@
#ifdef __rtems__
#define SX_NOINLINE 1
#define _sx_slock _bsd__sx_xlock
-#define _sx_try_slock _bsd__sx_try_xlock
+#define sx_try_slock_ _bsd_sx_try_xlock_
#define _sx_sunlock _bsd__sx_xunlock
#endif /* __rtems__ */
/*
@@ -92,6 +92,8 @@
#ifdef _KERNEL
+#define sx_recurse lock_object.lo_data
+
/*
* Function prototipes. Routines that start with an underscore are not part
* of the public interface and are wrappered with a macro.
@@ -100,14 +102,14 @@ void sx_sysinit(void *arg);
#define sx_init(sx, desc) sx_init_flags((sx), (desc), 0)
void sx_init_flags(struct sx *sx, const char *description, int opts);
void sx_destroy(struct sx *sx);
+int sx_try_slock_(struct sx *sx, const char *file, int line);
+int sx_try_xlock_(struct sx *sx, const char *file, int line);
+int sx_try_upgrade_(struct sx *sx, const char *file, int line);
+void sx_downgrade_(struct sx *sx, const char *file, int line);
int _sx_slock(struct sx *sx, int opts, const char *file, int line);
int _sx_xlock(struct sx *sx, int opts, const char *file, int line);
-int _sx_try_slock(struct sx *sx, const char *file, int line);
-int _sx_try_xlock(struct sx *sx, const char *file, int line);
void _sx_sunlock(struct sx *sx, const char *file, int line);
void _sx_xunlock(struct sx *sx, const char *file, int line);
-int _sx_try_upgrade(struct sx *sx, const char *file, int line);
-void _sx_downgrade(struct sx *sx, const char *file, int line);
int _sx_xlock_hard(struct sx *sx, uintptr_t tid, int opts,
const char *file, int line);
int _sx_slock_hard(struct sx *sx, int opts, const char *file, int line);
@@ -115,21 +117,12 @@ void _sx_xunlock_hard(struct sx *sx, uintptr_t tid, const char *file, int
line);
void _sx_sunlock_hard(struct sx *sx, const char *file, int line);
#if defined(INVARIANTS) || defined(INVARIANT_SUPPORT)
-void _sx_assert(struct sx *sx, int what, const char *file, int line);
+void _sx_assert(const struct sx *sx, int what, const char *file, int line);
#endif
#ifdef DDB
int sx_chain(struct thread *td, struct thread **ownerp);
#endif
-#define sx_downgrade_(sx, file, line) \
- _sx_downgrade((sx), (file), (line))
-#define sx_try_slock_(sx, file, line) \
- _sx_try_slock((sx), (file), (line))
-#define sx_try_xlock_(sx, file, line) \
- _sx_try_xlock((sx), (file), (line))
-#define sx_try_upgrade_(sx, file, line) \
- _sx_try_upgrade((sx), (file), (line))
-
struct sx_args {
struct sx *sa_sx;
const char *sa_desc;
@@ -164,11 +157,12 @@ __sx_xlock(struct sx *sx, struct thread *td, int opts, const char *file,
uintptr_t tid = (uintptr_t)td;
int error = 0;
- if (!atomic_cmpset_acq_ptr(&sx->sx_lock, SX_LOCK_UNLOCKED, tid))
+ if (sx->sx_lock != SX_LOCK_UNLOCKED ||
+ !atomic_cmpset_acq_ptr(&sx->sx_lock, SX_LOCK_UNLOCKED, tid))
error = _sx_xlock_hard(sx, tid, opts, file, line);
else
- LOCKSTAT_PROFILE_OBTAIN_LOCK_SUCCESS(LS_SX_XLOCK_ACQUIRE,
- sx, 0, 0, file, line);
+ LOCKSTAT_PROFILE_OBTAIN_RWLOCK_SUCCESS(sx__acquire, sx,
+ 0, 0, file, line, LOCKSTAT_WRITER);
return (error);
}
@@ -179,7 +173,11 @@ __sx_xunlock(struct sx *sx, struct thread *td, const char *file, int line)
{
uintptr_t tid = (uintptr_t)td;
- if (!atomic_cmpset_rel_ptr(&sx->sx_lock, tid, SX_LOCK_UNLOCKED))
+ if (sx->sx_recurse == 0)
+ LOCKSTAT_PROFILE_RELEASE_RWLOCK(sx__release, sx,
+ LOCKSTAT_WRITER);
+ if (sx->sx_lock != tid ||
+ !atomic_cmpset_rel_ptr(&sx->sx_lock, tid, SX_LOCK_UNLOCKED))
_sx_xunlock_hard(sx, tid, file, line);
}
@@ -194,8 +192,8 @@ __sx_slock(struct sx *sx, int opts, const char *file, int line)
!atomic_cmpset_acq_ptr(&sx->sx_lock, x, x + SX_ONE_SHARER))
error = _sx_slock_hard(sx, opts, file, line);
else
- LOCKSTAT_PROFILE_OBTAIN_LOCK_SUCCESS(LS_SX_SLOCK_ACQUIRE, sx, 0,
- 0, file, line);
+ LOCKSTAT_PROFILE_OBTAIN_RWLOCK_SUCCESS(sx__acquire, sx,
+ 0, 0, file, line, LOCKSTAT_READER);
return (error);
}
@@ -212,6 +210,7 @@ __sx_sunlock(struct sx *sx, const char *file, int line)
{
uintptr_t x = sx->sx_lock;
+ LOCKSTAT_PROFILE_RELEASE_RWLOCK(sx__release, sx, LOCKSTAT_READER);
if (x == (SX_SHARERS_LOCK(1) | SX_LOCK_EXCLUSIVE_WAITERS) ||
!atomic_cmpset_rel_ptr(&sx->sx_lock, x, x - SX_ONE_SHARER))
_sx_sunlock_hard(sx, file, line);
@@ -296,7 +295,8 @@ int sx_xlocked(struct sx *sx);
#define sx_unlock(sx) sx_unlock_((sx), LOCK_FILE, LOCK_LINE)
#define sx_sleep(chan, sx, pri, wmesg, timo) \
- _sleep((chan), &(sx)->lock_object, (pri), (wmesg), (timo))
+ _sleep((chan), &(sx)->lock_object, (pri), (wmesg), \
+ tick_sbt * (timo), 0, C_HARDCLOCK)
/*
* Options passed to sx_init_flags().
@@ -307,6 +307,7 @@ int sx_xlocked(struct sx *sx);
#define SX_QUIET 0x08
#define SX_NOADAPTIVE 0x10
#define SX_RECURSE 0x20
+#define SX_NEW 0x40
/*
* Options passed to sx_*lock_hard().
@@ -321,7 +322,7 @@ int sx_xlocked(struct sx *sx);
#define SA_RECURSED LA_RECURSED
#define SA_NOTRECURSED LA_NOTRECURSED
-/* Backwards compatability. */
+/* Backwards compatibility. */
#define SX_LOCKED LA_LOCKED
#define SX_SLOCKED LA_SLOCKED
#define SX_XLOCKED LA_XLOCKED
diff --git a/freebsd/sys/sys/sysctl.h b/freebsd/sys/sys/sysctl.h
index cfbbc7f3..687fb23b 100644
--- a/freebsd/sys/sys/sysctl.h
+++ b/freebsd/sys/sys/sysctl.h
@@ -48,7 +48,7 @@ struct thread;
* respective subsystem header files.
*/
-#define CTL_MAXNAME 24 /* largest number of components supported */
+#define CTL_MAXNAME 24 /* largest number of components supported */
/*
* Each subsystem defined by sysctl defines a list of variables
@@ -59,10 +59,10 @@ struct thread;
*/
struct ctlname {
char *ctl_name; /* subsystem name */
- int ctl_type; /* type of name */
+ int ctl_type; /* type of name */
};
-#define CTLTYPE 0xf /* Mask for the type */
+#define CTLTYPE 0xf /* mask for the type */
#define CTLTYPE_NODE 1 /* name is a node */
#define CTLTYPE_INT 2 /* name describes an integer */
#define CTLTYPE_STRING 3 /* name describes a string */
@@ -73,35 +73,43 @@ struct ctlname {
#define CTLTYPE_LONG 7 /* name describes a long */
#define CTLTYPE_ULONG 8 /* name describes an unsigned long */
#define CTLTYPE_U64 9 /* name describes an unsigned 64-bit number */
-
-#define CTLFLAG_RD 0x80000000 /* Allow reads of variable */
-#define CTLFLAG_WR 0x40000000 /* Allow writes to the variable */
-#define CTLFLAG_RW (CTLFLAG_RD|CTLFLAG_WR)
-#define CTLFLAG_ANYBODY 0x10000000 /* All users can set this var */
-#define CTLFLAG_SECURE 0x08000000 /* Permit set only if securelevel<=0 */
-#define CTLFLAG_PRISON 0x04000000 /* Prisoned roots can fiddle */
-#define CTLFLAG_DYN 0x02000000 /* Dynamic oid - can be freed */
-#define CTLFLAG_SKIP 0x01000000 /* Skip this sysctl when listing */
-#define CTLMASK_SECURE 0x00F00000 /* Secure level */
-#define CTLFLAG_TUN 0x00080000 /* Tunable variable */
+#define CTLTYPE_U8 0xa /* name describes an unsigned 8-bit number */
+#define CTLTYPE_U16 0xb /* name describes an unsigned 16-bit number */
+#define CTLTYPE_S8 0xc /* name describes a signed 8-bit number */
+#define CTLTYPE_S16 0xd /* name describes a signed 16-bit number */
+#define CTLTYPE_S32 0xe /* name describes a signed 32-bit number */
+#define CTLTYPE_U32 0xf /* name describes an unsigned 32-bit number */
+
+#define CTLFLAG_RD 0x80000000 /* Allow reads of variable */
+#define CTLFLAG_WR 0x40000000 /* Allow writes to the variable */
+#define CTLFLAG_RW (CTLFLAG_RD|CTLFLAG_WR)
+#define CTLFLAG_ANYBODY 0x10000000 /* All users can set this var */
+#define CTLFLAG_SECURE 0x08000000 /* Permit set only if securelevel<=0 */
+#define CTLFLAG_PRISON 0x04000000 /* Prisoned roots can fiddle */
+#define CTLFLAG_DYN 0x02000000 /* Dynamic oid - can be freed */
+#define CTLFLAG_SKIP 0x01000000 /* Skip this sysctl when listing */
+#define CTLMASK_SECURE 0x00F00000 /* Secure level */
+#define CTLFLAG_TUN 0x00080000 /* Default value is loaded from getenv() */
#define CTLFLAG_RDTUN (CTLFLAG_RD|CTLFLAG_TUN)
#define CTLFLAG_RWTUN (CTLFLAG_RW|CTLFLAG_TUN)
-#define CTLFLAG_MPSAFE 0x00040000 /* Handler is MP safe */
-#define CTLFLAG_VNET 0x00020000 /* Prisons with vnet can fiddle */
-#define CTLFLAG_DYING 0x00010000 /* oid is being removed */
-#define CTLFLAG_CAPRD 0x00008000 /* Can be read in capability mode */
-#define CTLFLAG_CAPWR 0x00004000 /* Can be written in capability mode */
-#define CTLFLAG_CAPRW (CTLFLAG_CAPRD|CTLFLAG_CAPWR)
+#define CTLFLAG_MPSAFE 0x00040000 /* Handler is MP safe */
+#define CTLFLAG_VNET 0x00020000 /* Prisons with vnet can fiddle */
+#define CTLFLAG_DYING 0x00010000 /* Oid is being removed */
+#define CTLFLAG_CAPRD 0x00008000 /* Can be read in capability mode */
+#define CTLFLAG_CAPWR 0x00004000 /* Can be written in capability mode */
+#define CTLFLAG_STATS 0x00002000 /* Statistics, not a tuneable */
+#define CTLFLAG_NOFETCH 0x00001000 /* Don't fetch tunable from getenv() */
+#define CTLFLAG_CAPRW (CTLFLAG_CAPRD|CTLFLAG_CAPWR)
/*
- * Secure level. Note that CTLFLAG_SECURE == CTLFLAG_SECURE1.
+ * Secure level. Note that CTLFLAG_SECURE == CTLFLAG_SECURE1.
*
* Secure when the securelevel is raised to at least N.
*/
-#define CTLSHIFT_SECURE 20
-#define CTLFLAG_SECURE1 (CTLFLAG_SECURE | (0 << CTLSHIFT_SECURE))
-#define CTLFLAG_SECURE2 (CTLFLAG_SECURE | (1 << CTLSHIFT_SECURE))
-#define CTLFLAG_SECURE3 (CTLFLAG_SECURE | (2 << CTLSHIFT_SECURE))
+#define CTLSHIFT_SECURE 20
+#define CTLFLAG_SECURE1 (CTLFLAG_SECURE | (0 << CTLSHIFT_SECURE))
+#define CTLFLAG_SECURE2 (CTLFLAG_SECURE | (1 << CTLSHIFT_SECURE))
+#define CTLFLAG_SECURE3 (CTLFLAG_SECURE | (2 << CTLSHIFT_SECURE))
/*
* USE THIS instead of a hardwired number from the categories below
@@ -109,14 +117,14 @@ struct ctlname {
* technology. This is the way nearly all new sysctl variables should
* be implemented.
* e.g. SYSCTL_INT(_parent, OID_AUTO, name, CTLFLAG_RW, &variable, 0, "");
- */
-#define OID_AUTO (-1)
+ */
+#define OID_AUTO (-1)
/*
* The starting number for dynamically-assigned entries. WARNING!
* ALL static sysctl entries should have numbers LESS than this!
*/
-#define CTL_AUTO_START 0x100
+#define CTL_AUTO_START 0x100
#ifdef _KERNEL
#include <sys/linker_set.h>
@@ -129,14 +137,15 @@ struct ctlname {
#endif
#define SYSCTL_HANDLER_ARGS struct sysctl_oid *oidp, void *arg1, \
- intptr_t arg2, struct sysctl_req *req
+ intmax_t arg2, struct sysctl_req *req
/* definitions for sysctl_req 'lock' member */
#define REQ_UNWIRED 1
#define REQ_WIRED 2
/* definitions for sysctl_req 'flags' member */
-#if defined(__amd64__) || defined(__ia64__) || defined(__powerpc64__)
+#if defined(__amd64__) || defined(__powerpc64__) ||\
+ (defined(__mips__) && defined(__mips_n64))
#define SCTL_MASK32 1 /* 32 bit emulation */
#endif
@@ -146,21 +155,21 @@ struct ctlname {
*/
struct sysctl_req {
struct thread *td; /* used for access checking */
- int lock; /* wiring state */
+ int lock; /* wiring state */
void *oldptr;
- size_t oldlen;
- size_t oldidx;
+ size_t oldlen;
+ size_t oldidx;
int (*oldfunc)(struct sysctl_req *, const void *, size_t);
#ifndef __rtems__
void *newptr;
#else /* __rtems__ */
const void *newptr;
#endif /* __rtems__ */
- size_t newlen;
- size_t newidx;
+ size_t newlen;
+ size_t newidx;
int (*newfunc)(struct sysctl_req *, void *, size_t);
- size_t validlen;
- int flags;
+ size_t validlen;
+ int flags;
};
SLIST_HEAD(sysctl_oid_list, sysctl_oid);
@@ -170,29 +179,40 @@ SLIST_HEAD(sysctl_oid_list, sysctl_oid);
* be hidden behind it, expanded by the handler.
*/
struct sysctl_oid {
+ struct sysctl_oid_list oid_children;
struct sysctl_oid_list *oid_parent;
SLIST_ENTRY(sysctl_oid) oid_link;
- int oid_number;
- u_int oid_kind;
+ int oid_number;
+ u_int oid_kind;
void *oid_arg1;
- intptr_t oid_arg2;
+ intmax_t oid_arg2;
const char *oid_name;
- int (*oid_handler)(SYSCTL_HANDLER_ARGS);
+ int (*oid_handler)(SYSCTL_HANDLER_ARGS);
const char *oid_fmt;
- int oid_refcnt;
- u_int oid_running;
+ int oid_refcnt;
+ u_int oid_running;
const char *oid_descr;
};
-#define SYSCTL_IN(r, p, l) (r->newfunc)(r, p, l)
-#define SYSCTL_OUT(r, p, l) (r->oldfunc)(r, p, l)
+#define SYSCTL_IN(r, p, l) (r->newfunc)(r, p, l)
+#define SYSCTL_OUT(r, p, l) (r->oldfunc)(r, p, l)
+#define SYSCTL_OUT_STR(r, p) (r->oldfunc)(r, p, strlen(p) + 1)
+int sysctl_handle_bool(SYSCTL_HANDLER_ARGS);
+int sysctl_handle_8(SYSCTL_HANDLER_ARGS);
+int sysctl_handle_16(SYSCTL_HANDLER_ARGS);
+int sysctl_handle_32(SYSCTL_HANDLER_ARGS);
+int sysctl_handle_64(SYSCTL_HANDLER_ARGS);
int sysctl_handle_int(SYSCTL_HANDLER_ARGS);
int sysctl_msec_to_ticks(SYSCTL_HANDLER_ARGS);
int sysctl_handle_long(SYSCTL_HANDLER_ARGS);
-int sysctl_handle_64(SYSCTL_HANDLER_ARGS);
int sysctl_handle_string(SYSCTL_HANDLER_ARGS);
int sysctl_handle_opaque(SYSCTL_HANDLER_ARGS);
+int sysctl_handle_counter_u64(SYSCTL_HANDLER_ARGS);
+int sysctl_handle_counter_u64_array(SYSCTL_HANDLER_ARGS);
+
+int sysctl_handle_uma_zone_max(SYSCTL_HANDLER_ARGS);
+int sysctl_handle_uma_zone_cur(SYSCTL_HANDLER_ARGS);
int sysctl_dpcpu_int(SYSCTL_HANDLER_ARGS);
int sysctl_dpcpu_long(SYSCTL_HANDLER_ARGS);
@@ -206,27 +226,26 @@ void sysctl_unregister_oid(struct sysctl_oid *oidp);
/* Declare a static oid to allow child oids to be added to it. */
#ifndef __rtems__
-#define SYSCTL_DECL(name) \
- extern struct sysctl_oid_list sysctl_##name##_children
+#define SYSCTL_DECL(name) \
+ extern struct sysctl_oid sysctl__##name
#else /* __rtems__ */
-#define SYSCTL_DECL(name) \
- extern struct sysctl_oid_list _bsd_sysctl_##name##_children
+#define SYSCTL_DECL(name) \
+ extern struct sysctl_oid _bsd_sysctl__##name
#endif /* __rtems__ */
-/* Hide these in macros */
-#define SYSCTL_CHILDREN(oid_ptr) (struct sysctl_oid_list *) \
- (oid_ptr)->oid_arg1
-#define SYSCTL_CHILDREN_SET(oid_ptr, val) \
- (oid_ptr)->oid_arg1 = (val);
+/* Hide these in macros. */
+#define SYSCTL_CHILDREN(oid_ptr) (&(oid_ptr)->oid_children)
+#define SYSCTL_PARENT(oid_ptr) \
+ (((oid_ptr)->oid_parent != &sysctl__children) ? \
+ __containerof((oid_ptr)->oid_parent, struct sysctl_oid, \
+ oid_children) : (struct sysctl_oid *)NULL)
#ifndef __rtems__
-#define SYSCTL_STATIC_CHILDREN(oid_name) \
- (&sysctl_##oid_name##_children)
+#define SYSCTL_STATIC_CHILDREN(oid_name) (&sysctl__##oid_name.oid_children)
#else /* __rtems__ */
-#define SYSCTL_STATIC_CHILDREN(oid_name) \
- (&_bsd_sysctl_##oid_name##_children)
+#define SYSCTL_STATIC_CHILDREN(oid_name) (&_bsd_sysctl__##oid_name.oid_children)
#endif /* __rtems__ */
-/* === Structs and macros related to context handling === */
+/* === Structs and macros related to context handling. === */
/* All dynamically created sysctls can be tracked in a context list. */
struct sysctl_ctx_entry {
@@ -237,52 +256,88 @@ struct sysctl_ctx_entry {
TAILQ_HEAD(sysctl_ctx_list, sysctl_ctx_entry);
#ifndef __rtems__
-#define SYSCTL_NODE_CHILDREN(parent, name) \
- sysctl_##parent##_##name##_children
+#define SYSCTL_NODE_CHILDREN(parent, name) \
+ sysctl__##parent##_##name.oid_children
#else /* __rtems__ */
-#define SYSCTL_NODE_CHILDREN(parent, name) \
- _bsd_sysctl_##parent##_##name##_children
+#define SYSCTL_NODE_CHILDREN(parent, name) \
+ _bsd_sysctl__##parent##_##name.oid_children
#endif /* __rtems__ */
#ifndef NO_SYSCTL_DESCR
-#define __DESCR(d) d
+#define __DESCR(d) d
#else
-#define __DESCR(d) ""
+#define __DESCR(d) ""
#endif
-/* This constructs a "raw" MIB oid. */
+/* This macro is only for internal use */
+#define SYSCTL_OID_RAW(id, parent_child_head, nbr, name, kind, a1, a2, handler, fmt, descr) \
+ struct sysctl_oid id = { \
+ .oid_parent = (parent_child_head), \
+ .oid_children = SLIST_HEAD_INITIALIZER(&id.oid_children), \
+ .oid_number = (nbr), \
+ .oid_kind = (kind), \
+ .oid_arg1 = (a1), \
+ .oid_arg2 = (a2), \
+ .oid_name = (name), \
+ .oid_handler = (handler), \
+ .oid_fmt = (fmt), \
+ .oid_descr = __DESCR(descr) \
+ }; \
+ DATA_SET(sysctl_set, id)
+
+/* This constructs a static "raw" MIB oid. */
#ifndef __rtems__
-#define SYSCTL_OID(parent, nbr, name, kind, a1, a2, handler, fmt, descr) \
- static struct sysctl_oid sysctl__##parent##_##name = { \
- &sysctl_##parent##_children, { NULL }, nbr, kind, \
- a1, a2, #name, handler, fmt, 0, 0, __DESCR(descr) }; \
- DATA_SET(sysctl_set, sysctl__##parent##_##name)
+#define SYSCTL_OID(parent, nbr, name, kind, a1, a2, handler, fmt, descr) \
+ static SYSCTL_OID_RAW(sysctl__##parent##_##name, \
+ SYSCTL_CHILDREN(&sysctl__##parent), \
+ nbr, #name, kind, a1, a2, handler, fmt, descr)
#else /* __rtems__ */
-#define SYSCTL_OID(parent, nbr, name, kind, a1, a2, handler, fmt, descr) \
- static struct sysctl_oid sysctl__##parent##_##name = { \
- &_bsd_sysctl_##parent##_children, { NULL }, nbr, kind, \
- a1, a2, #name, handler, fmt, 0, 0, __DESCR(descr) }; \
- DATA_SET(sysctl_set, sysctl__##parent##_##name)
+#define SYSCTL_OID(parent, nbr, name, kind, a1, a2, handler, fmt, descr) \
+ static SYSCTL_OID_RAW(_bsd_sysctl__##parent##_##name, \
+ SYSCTL_CHILDREN(&_bsd_sysctl__##parent), \
+ nbr, #name, kind, a1, a2, handler, fmt, descr)
#endif /* __rtems__ */
-#define SYSCTL_ADD_OID(ctx, parent, nbr, name, kind, a1, a2, handler, fmt, descr) \
+/* This constructs a global "raw" MIB oid. */
+#ifndef __rtems__
+#define SYSCTL_OID_GLOBAL(parent, nbr, name, kind, a1, a2, handler, fmt, descr) \
+ SYSCTL_OID_RAW(sysctl__##parent##_##name, \
+ SYSCTL_CHILDREN(&sysctl__##parent), \
+ nbr, #name, kind, a1, a2, handler, fmt, descr)
+#else /* __rtems__ */
+#define SYSCTL_OID_GLOBAL(parent, nbr, name, kind, a1, a2, handler, fmt, descr) \
+ SYSCTL_OID_RAW(_bsd_sysctl__##parent##_##name, \
+ SYSCTL_CHILDREN(&_bsd_sysctl__##parent), \
+ nbr, #name, kind, a1, a2, handler, fmt, descr)
+#endif /* __rtems__ */
+
+#define SYSCTL_ADD_OID(ctx, parent, nbr, name, kind, a1, a2, handler, fmt, descr) \
sysctl_add_oid(ctx, parent, nbr, name, kind, a1, a2, handler, fmt, __DESCR(descr))
/* This constructs a root node from which other nodes can hang. */
-#define SYSCTL_ROOT_NODE(nbr, name, access, handler, descr) \
- SYSCTL_NODE(, nbr, name, access, handler, descr)
+#ifndef __rtems__
+#define SYSCTL_ROOT_NODE(nbr, name, access, handler, descr) \
+ SYSCTL_OID_RAW(sysctl___##name, &sysctl__children, \
+ nbr, #name, CTLTYPE_NODE|(access), NULL, 0, \
+ handler, "N", descr); \
+ CTASSERT(((access) & CTLTYPE) == 0 || \
+ ((access) & SYSCTL_CT_ASSERT_MASK) == CTLTYPE_NODE)
+#else /* __rtems__ */
+#define SYSCTL_ROOT_NODE(nbr, name, access, handler, descr) \
+ SYSCTL_OID_RAW(_bsd_sysctl___##name, &sysctl__children, \
+ nbr, #name, CTLTYPE_NODE|(access), NULL, 0, \
+ handler, "N", descr); \
+ CTASSERT(((access) & CTLTYPE) == 0 || \
+ ((access) & SYSCTL_CT_ASSERT_MASK) == CTLTYPE_NODE)
+#endif /* __rtems__ */
/* This constructs a node from which other oids can hang. */
-#define SYSCTL_NODE(parent, nbr, name, access, handler, descr) \
- struct sysctl_oid_list SYSCTL_NODE_CHILDREN(parent, name); \
- SYSCTL_OID(parent, nbr, name, CTLTYPE_NODE|(access), \
- (void*)&SYSCTL_NODE_CHILDREN(parent, name), 0, handler, "N", descr); \
+#define SYSCTL_NODE(parent, nbr, name, access, handler, descr) \
+ SYSCTL_OID_GLOBAL(parent, nbr, name, CTLTYPE_NODE|(access), \
+ NULL, 0, handler, "N", descr); \
CTASSERT(((access) & CTLTYPE) == 0 || \
((access) & SYSCTL_CT_ASSERT_MASK) == CTLTYPE_NODE)
-#define SYSCTL_ADD_ROOT_NODE(ctx, nbr, name, access, handler, descr) \
- SYSCTL_ADD_NODE(ctx, SYSCTL_STATIC_CHILDREN(), nbr, name, access, handler, descr)
-
#define SYSCTL_ADD_NODE(ctx, parent, nbr, name, access, handler, descr) \
({ \
CTASSERT(((access) & CTLTYPE) == 0 || \
@@ -291,6 +346,15 @@ TAILQ_HEAD(sysctl_ctx_list, sysctl_ctx_entry);
NULL, 0, handler, "N", __DESCR(descr)); \
})
+#define SYSCTL_ADD_ROOT_NODE(ctx, nbr, name, access, handler, descr) \
+({ \
+ CTASSERT(((access) & CTLTYPE) == 0 || \
+ ((access) & SYSCTL_CT_ASSERT_MASK) == CTLTYPE_NODE); \
+ sysctl_add_oid(ctx, &sysctl__children, nbr, name, \
+ CTLTYPE_NODE|(access), \
+ NULL, 0, handler, "N", __DESCR(descr)); \
+})
+
/* Oid for a string. len can be 0 to indicate '\0' termination. */
#define SYSCTL_STRING(parent, nbr, name, access, arg, len, descr) \
SYSCTL_OID(parent, nbr, name, CTLTYPE_STRING|(access), \
@@ -307,6 +371,184 @@ TAILQ_HEAD(sysctl_ctx_list, sysctl_ctx_entry);
__arg, len, sysctl_handle_string, "A", __DESCR(descr)); \
})
+/* Oid for a bool. If ptr is NULL, val is returned. */
+#define SYSCTL_NULL_BOOL_PTR ((bool *)NULL)
+#define SYSCTL_BOOL(parent, nbr, name, access, ptr, val, descr) \
+ SYSCTL_OID(parent, nbr, name, \
+ CTLTYPE_U8 | CTLFLAG_MPSAFE | (access), \
+ ptr, val, sysctl_handle_bool, "CU", descr); \
+ CTASSERT(((access) & CTLTYPE) == 0 && \
+ sizeof(bool) == sizeof(*(ptr)))
+
+#define SYSCTL_ADD_BOOL(ctx, parent, nbr, name, access, ptr, val, descr) \
+({ \
+ bool *__ptr = (ptr); \
+ CTASSERT(((access) & CTLTYPE) == 0); \
+ sysctl_add_oid(ctx, parent, nbr, name, \
+ CTLTYPE_U8 | CTLFLAG_MPSAFE | (access), \
+ __ptr, val, sysctl_handle_bool, "CU", __DESCR(descr)); \
+})
+
+/* Oid for a signed 8-bit int. If ptr is NULL, val is returned. */
+#define SYSCTL_NULL_S8_PTR ((int8_t *)NULL)
+#define SYSCTL_S8(parent, nbr, name, access, ptr, val, descr) \
+ SYSCTL_OID(parent, nbr, name, \
+ CTLTYPE_S8 | CTLFLAG_MPSAFE | (access), \
+ ptr, val, sysctl_handle_8, "C", descr); \
+ CTASSERT((((access) & CTLTYPE) == 0 || \
+ ((access) & SYSCTL_CT_ASSERT_MASK) == CTLTYPE_S8) && \
+ sizeof(int8_t) == sizeof(*(ptr)))
+
+#define SYSCTL_ADD_S8(ctx, parent, nbr, name, access, ptr, val, descr) \
+({ \
+ int8_t *__ptr = (ptr); \
+ CTASSERT(((access) & CTLTYPE) == 0 || \
+ ((access) & SYSCTL_CT_ASSERT_MASK) == CTLTYPE_S8); \
+ sysctl_add_oid(ctx, parent, nbr, name, \
+ CTLTYPE_S8 | CTLFLAG_MPSAFE | (access), \
+ __ptr, val, sysctl_handle_8, "C", __DESCR(descr)); \
+})
+
+/* Oid for an unsigned 8-bit int. If ptr is NULL, val is returned. */
+#define SYSCTL_NULL_U8_PTR ((uint8_t *)NULL)
+#define SYSCTL_U8(parent, nbr, name, access, ptr, val, descr) \
+ SYSCTL_OID(parent, nbr, name, \
+ CTLTYPE_U8 | CTLFLAG_MPSAFE | (access), \
+ ptr, val, sysctl_handle_8, "CU", descr); \
+ CTASSERT((((access) & CTLTYPE) == 0 || \
+ ((access) & SYSCTL_CT_ASSERT_MASK) == CTLTYPE_U8) && \
+ sizeof(uint8_t) == sizeof(*(ptr)))
+
+#define SYSCTL_ADD_U8(ctx, parent, nbr, name, access, ptr, val, descr) \
+({ \
+ uint8_t *__ptr = (ptr); \
+ CTASSERT(((access) & CTLTYPE) == 0 || \
+ ((access) & SYSCTL_CT_ASSERT_MASK) == CTLTYPE_U8); \
+ sysctl_add_oid(ctx, parent, nbr, name, \
+ CTLTYPE_U8 | CTLFLAG_MPSAFE | (access), \
+ __ptr, val, sysctl_handle_8, "CU", __DESCR(descr)); \
+})
+
+/* Oid for a signed 16-bit int. If ptr is NULL, val is returned. */
+#define SYSCTL_NULL_S16_PTR ((int16_t *)NULL)
+#define SYSCTL_S16(parent, nbr, name, access, ptr, val, descr) \
+ SYSCTL_OID(parent, nbr, name, \
+ CTLTYPE_S16 | CTLFLAG_MPSAFE | (access), \
+ ptr, val, sysctl_handle_16, "S", descr); \
+ CTASSERT((((access) & CTLTYPE) == 0 || \
+ ((access) & SYSCTL_CT_ASSERT_MASK) == CTLTYPE_S16) && \
+ sizeof(int16_t) == sizeof(*(ptr)))
+
+#define SYSCTL_ADD_S16(ctx, parent, nbr, name, access, ptr, val, descr) \
+({ \
+ int16_t *__ptr = (ptr); \
+ CTASSERT(((access) & CTLTYPE) == 0 || \
+ ((access) & SYSCTL_CT_ASSERT_MASK) == CTLTYPE_S16); \
+ sysctl_add_oid(ctx, parent, nbr, name, \
+ CTLTYPE_S16 | CTLFLAG_MPSAFE | (access), \
+ __ptr, val, sysctl_handle_16, "S", __DESCR(descr)); \
+})
+
+/* Oid for an unsigned 16-bit int. If ptr is NULL, val is returned. */
+#define SYSCTL_NULL_U16_PTR ((uint16_t *)NULL)
+#define SYSCTL_U16(parent, nbr, name, access, ptr, val, descr) \
+ SYSCTL_OID(parent, nbr, name, \
+ CTLTYPE_U16 | CTLFLAG_MPSAFE | (access), \
+ ptr, val, sysctl_handle_16, "SU", descr); \
+ CTASSERT((((access) & CTLTYPE) == 0 || \
+ ((access) & SYSCTL_CT_ASSERT_MASK) == CTLTYPE_U16) && \
+ sizeof(uint16_t) == sizeof(*(ptr)))
+
+#define SYSCTL_ADD_U16(ctx, parent, nbr, name, access, ptr, val, descr) \
+({ \
+ uint16_t *__ptr = (ptr); \
+ CTASSERT(((access) & CTLTYPE) == 0 || \
+ ((access) & SYSCTL_CT_ASSERT_MASK) == CTLTYPE_U16); \
+ sysctl_add_oid(ctx, parent, nbr, name, \
+ CTLTYPE_U16 | CTLFLAG_MPSAFE | (access), \
+ __ptr, val, sysctl_handle_16, "SU", __DESCR(descr)); \
+})
+
+/* Oid for a signed 32-bit int. If ptr is NULL, val is returned. */
+#define SYSCTL_NULL_S32_PTR ((int32_t *)NULL)
+#define SYSCTL_S32(parent, nbr, name, access, ptr, val, descr) \
+ SYSCTL_OID(parent, nbr, name, \
+ CTLTYPE_S32 | CTLFLAG_MPSAFE | (access), \
+ ptr, val, sysctl_handle_32, "I", descr); \
+ CTASSERT((((access) & CTLTYPE) == 0 || \
+ ((access) & SYSCTL_CT_ASSERT_MASK) == CTLTYPE_S32) && \
+ sizeof(int32_t) == sizeof(*(ptr)))
+
+#define SYSCTL_ADD_S32(ctx, parent, nbr, name, access, ptr, val, descr) \
+({ \
+ int32_t *__ptr = (ptr); \
+ CTASSERT(((access) & CTLTYPE) == 0 || \
+ ((access) & SYSCTL_CT_ASSERT_MASK) == CTLTYPE_S32); \
+ sysctl_add_oid(ctx, parent, nbr, name, \
+ CTLTYPE_S32 | CTLFLAG_MPSAFE | (access), \
+ __ptr, val, sysctl_handle_32, "I", __DESCR(descr)); \
+})
+
+/* Oid for an unsigned 32-bit int. If ptr is NULL, val is returned. */
+#define SYSCTL_NULL_U32_PTR ((uint32_t *)NULL)
+#define SYSCTL_U32(parent, nbr, name, access, ptr, val, descr) \
+ SYSCTL_OID(parent, nbr, name, \
+ CTLTYPE_U32 | CTLFLAG_MPSAFE | (access), \
+ ptr, val, sysctl_handle_32, "IU", descr); \
+ CTASSERT((((access) & CTLTYPE) == 0 || \
+ ((access) & SYSCTL_CT_ASSERT_MASK) == CTLTYPE_U32) && \
+ sizeof(uint32_t) == sizeof(*(ptr)))
+
+#define SYSCTL_ADD_U32(ctx, parent, nbr, name, access, ptr, val, descr) \
+({ \
+ uint32_t *__ptr = (ptr); \
+ CTASSERT(((access) & CTLTYPE) == 0 || \
+ ((access) & SYSCTL_CT_ASSERT_MASK) == CTLTYPE_U32); \
+ sysctl_add_oid(ctx, parent, nbr, name, \
+ CTLTYPE_U32 | CTLFLAG_MPSAFE | (access), \
+ __ptr, val, sysctl_handle_32, "IU", __DESCR(descr)); \
+})
+
+/* Oid for a signed 64-bit int. If ptr is NULL, val is returned. */
+#define SYSCTL_NULL_S64_PTR ((int64_t *)NULL)
+#define SYSCTL_S64(parent, nbr, name, access, ptr, val, descr) \
+ SYSCTL_OID(parent, nbr, name, \
+ CTLTYPE_S64 | CTLFLAG_MPSAFE | (access), \
+ ptr, val, sysctl_handle_64, "Q", descr); \
+ CTASSERT((((access) & CTLTYPE) == 0 || \
+ ((access) & SYSCTL_CT_ASSERT_MASK) == CTLTYPE_S64) && \
+ sizeof(int64_t) == sizeof(*(ptr)))
+
+#define SYSCTL_ADD_S64(ctx, parent, nbr, name, access, ptr, val, descr) \
+({ \
+ int64_t *__ptr = (ptr); \
+ CTASSERT(((access) & CTLTYPE) == 0 || \
+ ((access) & SYSCTL_CT_ASSERT_MASK) == CTLTYPE_S64); \
+ sysctl_add_oid(ctx, parent, nbr, name, \
+ CTLTYPE_S64 | CTLFLAG_MPSAFE | (access), \
+ __ptr, val, sysctl_handle_64, "Q", __DESCR(descr)); \
+})
+
+/* Oid for an unsigned 64-bit int. If ptr is NULL, val is returned. */
+#define SYSCTL_NULL_U64_PTR ((uint64_t *)NULL)
+#define SYSCTL_U64(parent, nbr, name, access, ptr, val, descr) \
+ SYSCTL_OID(parent, nbr, name, \
+ CTLTYPE_U64 | CTLFLAG_MPSAFE | (access), \
+ ptr, val, sysctl_handle_64, "QU", descr); \
+ CTASSERT((((access) & CTLTYPE) == 0 || \
+ ((access) & SYSCTL_CT_ASSERT_MASK) == CTLTYPE_U64) && \
+ sizeof(uint64_t) == sizeof(*(ptr)))
+
+#define SYSCTL_ADD_U64(ctx, parent, nbr, name, access, ptr, val, descr) \
+({ \
+ uint64_t *__ptr = (ptr); \
+ CTASSERT(((access) & CTLTYPE) == 0 || \
+ ((access) & SYSCTL_CT_ASSERT_MASK) == CTLTYPE_U64); \
+ sysctl_add_oid(ctx, parent, nbr, name, \
+ CTLTYPE_U64 | CTLFLAG_MPSAFE | (access), \
+ __ptr, val, sysctl_handle_64, "QU", __DESCR(descr)); \
+})
+
/* Oid for an int. If ptr is SYSCTL_NULL_INT_PTR, val is returned. */
#define SYSCTL_NULL_INT_PTR ((int *)NULL)
#define SYSCTL_INT(parent, nbr, name, access, ptr, val, descr) \
@@ -426,20 +668,7 @@ TAILQ_HEAD(sysctl_ctx_list, sysctl_ctx_entry);
__ptr, 0, sysctl_handle_64, "QU", __DESCR(descr)); \
})
-/* Oid for a 64-bit unsigned counter(9). The pointer must be non NULL. */
-#define SYSCTL_COUNTER_U64(parent, nbr, name, access, ptr, descr) \
- SYSCTL_ASSERT_TYPE(UINT64, ptr, parent, name); \
- SYSCTL_OID(parent, nbr, name, \
- CTLTYPE_U64 | CTLFLAG_MPSAFE | (access), \
- ptr, 0, sysctl_handle_counter_u64, "QU", descr)
-
-#define SYSCTL_ADD_COUNTER_U64(ctx, parent, nbr, name, access, ptr, descr)\
- sysctl_add_oid(ctx, parent, nbr, name, \
- CTLTYPE_U64 | CTLFLAG_MPSAFE | (access), \
- SYSCTL_ADD_ASSERT_TYPE(UINT64, ptr), 0, \
- sysctl_handle_counter_u64, "QU", __DESCR(descr))
-
-/* Oid for a CPU dependant variable */
+/* Oid for a CPU dependent variable */
#define SYSCTL_ADD_UAUTO(ctx, parent, nbr, name, access, ptr, descr) \
({ \
struct sysctl_oid *__ret; \
@@ -460,6 +689,48 @@ TAILQ_HEAD(sysctl_ctx_list, sysctl_ctx_entry);
__ret; \
})
+/* Oid for a 64-bit unsigned counter(9). The pointer must be non NULL. */
+#define SYSCTL_COUNTER_U64(parent, nbr, name, access, ptr, descr) \
+ SYSCTL_OID(parent, nbr, name, \
+ CTLTYPE_U64 | CTLFLAG_MPSAFE | (access), \
+ (ptr), 0, sysctl_handle_counter_u64, "QU", descr); \
+ CTASSERT((((access) & CTLTYPE) == 0 || \
+ ((access) & SYSCTL_CT_ASSERT_MASK) == CTLTYPE_U64) && \
+ sizeof(counter_u64_t) == sizeof(*(ptr)) && \
+ sizeof(uint64_t) == sizeof(**(ptr)))
+
+#define SYSCTL_ADD_COUNTER_U64(ctx, parent, nbr, name, access, ptr, descr) \
+({ \
+ counter_u64_t *__ptr = (ptr); \
+ CTASSERT(((access) & CTLTYPE) == 0 || \
+ ((access) & SYSCTL_CT_ASSERT_MASK) == CTLTYPE_U64); \
+ sysctl_add_oid(ctx, parent, nbr, name, \
+ CTLTYPE_U64 | CTLFLAG_MPSAFE | (access), \
+ __ptr, 0, sysctl_handle_counter_u64, "QU", __DESCR(descr)); \
+})
+
+/* Oid for an array of counter(9)s. The pointer and length must be non zero. */
+#define SYSCTL_COUNTER_U64_ARRAY(parent, nbr, name, access, ptr, len, descr) \
+ SYSCTL_OID(parent, nbr, name, \
+ CTLTYPE_OPAQUE | CTLFLAG_MPSAFE | (access), \
+ (ptr), (len), sysctl_handle_counter_u64_array, "S", descr); \
+ CTASSERT((((access) & CTLTYPE) == 0 || \
+ ((access) & SYSCTL_CT_ASSERT_MASK) == CTLTYPE_OPAQUE) && \
+ sizeof(counter_u64_t) == sizeof(*(ptr)) && \
+ sizeof(uint64_t) == sizeof(**(ptr)))
+
+#define SYSCTL_ADD_COUNTER_U64_ARRAY(ctx, parent, nbr, name, access, \
+ ptr, len, descr) \
+({ \
+ counter_u64_t *__ptr = (ptr); \
+ CTASSERT(((access) & CTLTYPE) == 0 || \
+ ((access) & SYSCTL_CT_ASSERT_MASK) == CTLTYPE_OPAQUE); \
+ sysctl_add_oid(ctx, parent, nbr, name, \
+ CTLTYPE_OPAQUE | CTLFLAG_MPSAFE | (access), \
+ __ptr, len, sysctl_handle_counter_u64_array, "S", \
+ __DESCR(descr)); \
+})
+
/* Oid for an opaque object. Specified by a pointer and a length. */
#define SYSCTL_OPAQUE(parent, nbr, name, access, ptr, len, fmt, descr) \
SYSCTL_OID(parent, nbr, name, CTLTYPE_OPAQUE|(access), \
@@ -483,7 +754,7 @@ TAILQ_HEAD(sysctl_ctx_list, sysctl_ctx_entry);
CTASSERT(((access) & CTLTYPE) == 0 || \
((access) & SYSCTL_CT_ASSERT_MASK) == CTLTYPE_OPAQUE)
-#define SYSCTL_ADD_STRUCT(ctx, parent, nbr, name, access, ptr, type, descr) \
+#define SYSCTL_ADD_STRUCT(ctx, parent, nbr, name, access, ptr, type, descr) \
({ \
CTASSERT(((access) & CTLTYPE) == 0 || \
((access) & SYSCTL_CT_ASSERT_MASK) == CTLTYPE_OPAQUE); \
@@ -493,20 +764,56 @@ TAILQ_HEAD(sysctl_ctx_list, sysctl_ctx_entry);
})
/* Oid for a procedure. Specified by a pointer and an arg. */
-#define SYSCTL_PROC(parent, nbr, name, access, ptr, arg, handler, fmt, descr) \
+#define SYSCTL_PROC(parent, nbr, name, access, ptr, arg, handler, fmt, descr) \
SYSCTL_OID(parent, nbr, name, (access), \
ptr, arg, handler, fmt, descr); \
CTASSERT(((access) & CTLTYPE) != 0)
-#define SYSCTL_ADD_PROC(ctx, parent, nbr, name, access, ptr, arg, handler, fmt, descr) \
+#define SYSCTL_ADD_PROC(ctx, parent, nbr, name, access, ptr, arg, handler, fmt, descr) \
({ \
CTASSERT(((access) & CTLTYPE) != 0); \
sysctl_add_oid(ctx, parent, nbr, name, (access), \
(ptr), (arg), (handler), (fmt), __DESCR(descr)); \
})
+/* Oid to handle limits on uma(9) zone specified by pointer. */
+#define SYSCTL_UMA_MAX(parent, nbr, name, access, ptr, descr) \
+ SYSCTL_OID(parent, nbr, name, \
+ CTLTYPE_INT | CTLFLAG_MPSAFE | (access), \
+ (ptr), 0, sysctl_handle_uma_zone_max, "I", descr); \
+ CTASSERT(((access) & CTLTYPE) == 0 || \
+ ((access) & SYSCTL_CT_ASSERT_MASK) == CTLTYPE_INT)
+
+#define SYSCTL_ADD_UMA_MAX(ctx, parent, nbr, name, access, ptr, descr) \
+({ \
+ uma_zone_t __ptr = (ptr); \
+ CTASSERT(((access) & CTLTYPE) == 0 || \
+ ((access) & SYSCTL_CT_ASSERT_MASK) == CTLTYPE_INT); \
+ sysctl_add_oid(ctx, parent, nbr, name, \
+ CTLTYPE_INT | CTLFLAG_MPSAFE | (access), \
+ __ptr, 0, sysctl_handle_uma_zone_max, "I", __DESCR(descr)); \
+})
+
+/* Oid to obtain current use of uma(9) zone specified by pointer. */
+#define SYSCTL_UMA_CUR(parent, nbr, name, access, ptr, descr) \
+ SYSCTL_OID(parent, nbr, name, \
+ CTLTYPE_INT | CTLFLAG_MPSAFE | CTLFLAG_RD | (access), \
+ (ptr), 0, sysctl_handle_uma_zone_cur, "I", descr); \
+ CTASSERT(((access) & CTLTYPE) == 0 || \
+ ((access) & SYSCTL_CT_ASSERT_MASK) == CTLTYPE_INT)
+
+#define SYSCTL_ADD_UMA_CUR(ctx, parent, nbr, name, access, ptr, descr) \
+({ \
+ uma_zone_t __ptr = (ptr); \
+ CTASSERT(((access) & CTLTYPE) == 0 || \
+ ((access) & SYSCTL_CT_ASSERT_MASK) == CTLTYPE_INT); \
+ sysctl_add_oid(ctx, parent, nbr, name, \
+ CTLTYPE_INT | CTLFLAG_MPSAFE | CTLFLAG_RD | (access), \
+ __ptr, 0, sysctl_handle_uma_zone_cur, "I", __DESCR(descr)); \
+})
+
/*
- * A macro to generate a read-only sysctl to indicate the presense of optional
+ * A macro to generate a read-only sysctl to indicate the presence of optional
* kernel features.
*/
#define FEATURE(name, desc) \
@@ -528,33 +835,19 @@ TAILQ_HEAD(sysctl_ctx_list, sysctl_ctx_entry);
#define CTL_MACHDEP 7 /* machine dependent */
#define CTL_USER 8 /* user-level */
#define CTL_P1003_1B 9 /* POSIX 1003.1B */
-#define CTL_MAXID 10 /* number of valid top-level ids */
-
-#define CTL_NAMES { \
- { 0, 0 }, \
- { "kern", CTLTYPE_NODE }, \
- { "vm", CTLTYPE_NODE }, \
- { "vfs", CTLTYPE_NODE }, \
- { "net", CTLTYPE_NODE }, \
- { "debug", CTLTYPE_NODE }, \
- { "hw", CTLTYPE_NODE }, \
- { "machdep", CTLTYPE_NODE }, \
- { "user", CTLTYPE_NODE }, \
- { "p1003_1b", CTLTYPE_NODE }, \
-}
/*
* CTL_KERN identifiers
*/
-#define KERN_OSTYPE 1 /* string: system version */
-#define KERN_OSRELEASE 2 /* string: system release */
-#define KERN_OSREV 3 /* int: system revision */
-#define KERN_VERSION 4 /* string: compile time info */
-#define KERN_MAXVNODES 5 /* int: max vnodes */
-#define KERN_MAXPROC 6 /* int: max processes */
-#define KERN_MAXFILES 7 /* int: max open files */
-#define KERN_ARGMAX 8 /* int: max arguments to exec */
-#define KERN_SECURELVL 9 /* int: system security level */
+#define KERN_OSTYPE 1 /* string: system version */
+#define KERN_OSRELEASE 2 /* string: system release */
+#define KERN_OSREV 3 /* int: system revision */
+#define KERN_VERSION 4 /* string: compile time info */
+#define KERN_MAXVNODES 5 /* int: max vnodes */
+#define KERN_MAXPROC 6 /* int: max processes */
+#define KERN_MAXFILES 7 /* int: max open files */
+#define KERN_ARGMAX 8 /* int: max arguments to exec */
+#define KERN_SECURELVL 9 /* int: system security level */
#define KERN_HOSTNAME 10 /* string: hostname */
#define KERN_HOSTID 11 /* int: host identifier */
#define KERN_CLOCKRATE 12 /* struct: struct clockrate */
@@ -567,14 +860,14 @@ TAILQ_HEAD(sysctl_ctx_list, sysctl_ctx_entry);
#define KERN_JOB_CONTROL 19 /* int: is job control available */
#define KERN_SAVED_IDS 20 /* int: saved set-user/group-ID */
#define KERN_BOOTTIME 21 /* struct: time kernel was booted */
-#define KERN_NISDOMAINNAME 22 /* string: YP domain name */
-#define KERN_UPDATEINTERVAL 23 /* int: update process sleep time */
-#define KERN_OSRELDATE 24 /* int: kernel release date */
-#define KERN_NTP_PLL 25 /* node: NTP PLL control */
+#define KERN_NISDOMAINNAME 22 /* string: YP domain name */
+#define KERN_UPDATEINTERVAL 23 /* int: update process sleep time */
+#define KERN_OSRELDATE 24 /* int: kernel release date */
+#define KERN_NTP_PLL 25 /* node: NTP PLL control */
#define KERN_BOOTFILE 26 /* string: name of booted kernel */
#define KERN_MAXFILESPERPROC 27 /* int: max open files per proc */
-#define KERN_MAXPROCPERUID 28 /* int: max processes per uid */
-#define KERN_DUMPDEV 29 /* struct cdev *: device to dump on */
+#define KERN_MAXPROCPERUID 28 /* int: max processes per uid */
+#define KERN_DUMPDEV 29 /* struct cdev *: device to dump on */
#define KERN_IPC 30 /* node: anything related to IPC */
#define KERN_DUMMY 31 /* unused */
#define KERN_PS_STRINGS 32 /* int: address of PS_STRINGS */
@@ -583,59 +876,10 @@ TAILQ_HEAD(sysctl_ctx_list, sysctl_ctx_entry);
#define KERN_IOV_MAX 35 /* int: value of UIO_MAXIOV */
#define KERN_HOSTUUID 36 /* string: host UUID identifier */
#define KERN_ARND 37 /* int: from arc4rand() */
-#define KERN_MAXID 38 /* number of valid kern ids */
-
-#define CTL_KERN_NAMES { \
- { 0, 0 }, \
- { "ostype", CTLTYPE_STRING }, \
- { "osrelease", CTLTYPE_STRING }, \
- { "osrevision", CTLTYPE_INT }, \
- { "version", CTLTYPE_STRING }, \
- { "maxvnodes", CTLTYPE_INT }, \
- { "maxproc", CTLTYPE_INT }, \
- { "maxfiles", CTLTYPE_INT }, \
- { "argmax", CTLTYPE_INT }, \
- { "securelevel", CTLTYPE_INT }, \
- { "hostname", CTLTYPE_STRING }, \
- { "hostid", CTLTYPE_UINT }, \
- { "clockrate", CTLTYPE_STRUCT }, \
- { "vnode", CTLTYPE_STRUCT }, \
- { "proc", CTLTYPE_STRUCT }, \
- { "file", CTLTYPE_STRUCT }, \
- { "profiling", CTLTYPE_NODE }, \
- { "posix1version", CTLTYPE_INT }, \
- { "ngroups", CTLTYPE_INT }, \
- { "job_control", CTLTYPE_INT }, \
- { "saved_ids", CTLTYPE_INT }, \
- { "boottime", CTLTYPE_STRUCT }, \
- { "nisdomainname", CTLTYPE_STRING }, \
- { "update", CTLTYPE_INT }, \
- { "osreldate", CTLTYPE_INT }, \
- { "ntp_pll", CTLTYPE_NODE }, \
- { "bootfile", CTLTYPE_STRING }, \
- { "maxfilesperproc", CTLTYPE_INT }, \
- { "maxprocperuid", CTLTYPE_INT }, \
- { "ipc", CTLTYPE_NODE }, \
- { "dummy", CTLTYPE_INT }, \
- { "ps_strings", CTLTYPE_INT }, \
- { "usrstack", CTLTYPE_INT }, \
- { "logsigexit", CTLTYPE_INT }, \
- { "iov_max", CTLTYPE_INT }, \
- { "hostuuid", CTLTYPE_STRING }, \
- { "arc4rand", CTLTYPE_OPAQUE }, \
-}
-
-/*
- * CTL_VFS identifiers
- */
-#define CTL_VFS_NAMES { \
- { "vfsconf", CTLTYPE_STRUCT }, \
-}
-
/*
* KERN_PROC subtypes
*/
-#define KERN_PROC_ALL 0 /* everything */
+#define KERN_PROC_ALL 0 /* everything */
#define KERN_PROC_PID 1 /* by process id */
#define KERN_PROC_PGRP 2 /* by process group id */
#define KERN_PROC_SESSION 3 /* by session of pid */
@@ -666,11 +910,13 @@ TAILQ_HEAD(sysctl_ctx_list, sysctl_ctx_entry);
#define KERN_PROC_UMASK 39 /* process umask */
#define KERN_PROC_OSREL 40 /* osreldate for process binary */
#define KERN_PROC_SIGTRAMP 41 /* signal trampoline location */
+#define KERN_PROC_CWD 42 /* process current working directory */
+#define KERN_PROC_NFDS 43 /* number of open file descriptors */
/*
* KERN_IPC identifiers
*/
-#define KIPC_MAXSOCKBUF 1 /* int: max size of a socket buffer */
+#define KIPC_MAXSOCKBUF 1 /* int: max size of a socket buffer */
#define KIPC_SOCKBUF_WASTE 2 /* int: wastage factor in sockbuf */
#define KIPC_SOMAXCONN 3 /* int: max length of connection q */
#define KIPC_MAX_LINKHDR 4 /* int: max length of link header */
@@ -690,26 +936,9 @@ TAILQ_HEAD(sysctl_ctx_list, sysctl_ctx_entry);
#define HW_PAGESIZE 7 /* int: software page size */
#define HW_DISKNAMES 8 /* strings: disk drive names */
#define HW_DISKSTATS 9 /* struct: diskstats[] */
-#define HW_FLOATINGPT 10 /* int: has HW floating point? */
-#define HW_MACHINE_ARCH 11 /* string: machine architecture */
+#define HW_FLOATINGPT 10 /* int: has HW floating point? */
+#define HW_MACHINE_ARCH 11 /* string: machine architecture */
#define HW_REALMEM 12 /* int: 'real' memory */
-#define HW_MAXID 13 /* number of valid hw ids */
-
-#define CTL_HW_NAMES { \
- { 0, 0 }, \
- { "machine", CTLTYPE_STRING }, \
- { "model", CTLTYPE_STRING }, \
- { "ncpu", CTLTYPE_INT }, \
- { "byteorder", CTLTYPE_INT }, \
- { "physmem", CTLTYPE_ULONG }, \
- { "usermem", CTLTYPE_ULONG }, \
- { "pagesize", CTLTYPE_INT }, \
- { "disknames", CTLTYPE_STRUCT }, \
- { "diskstats", CTLTYPE_STRUCT }, \
- { "floatingpoint", CTLTYPE_INT }, \
- { "machine_arch", CTLTYPE_STRING }, \
- { "realmem", CTLTYPE_ULONG }, \
-}
/*
* CTL_USER definitions
@@ -734,88 +963,34 @@ TAILQ_HEAD(sysctl_ctx_list, sysctl_ctx_entry);
#define USER_POSIX2_UPE 18 /* int: POSIX2_UPE */
#define USER_STREAM_MAX 19 /* int: POSIX2_STREAM_MAX */
#define USER_TZNAME_MAX 20 /* int: POSIX2_TZNAME_MAX */
-#define USER_MAXID 21 /* number of valid user ids */
-
-#define CTL_USER_NAMES { \
- { 0, 0 }, \
- { "cs_path", CTLTYPE_STRING }, \
- { "bc_base_max", CTLTYPE_INT }, \
- { "bc_dim_max", CTLTYPE_INT }, \
- { "bc_scale_max", CTLTYPE_INT }, \
- { "bc_string_max", CTLTYPE_INT }, \
- { "coll_weights_max", CTLTYPE_INT }, \
- { "expr_nest_max", CTLTYPE_INT }, \
- { "line_max", CTLTYPE_INT }, \
- { "re_dup_max", CTLTYPE_INT }, \
- { "posix2_version", CTLTYPE_INT }, \
- { "posix2_c_bind", CTLTYPE_INT }, \
- { "posix2_c_dev", CTLTYPE_INT }, \
- { "posix2_char_term", CTLTYPE_INT }, \
- { "posix2_fort_dev", CTLTYPE_INT }, \
- { "posix2_fort_run", CTLTYPE_INT }, \
- { "posix2_localedef", CTLTYPE_INT }, \
- { "posix2_sw_dev", CTLTYPE_INT }, \
- { "posix2_upe", CTLTYPE_INT }, \
- { "stream_max", CTLTYPE_INT }, \
- { "tzname_max", CTLTYPE_INT }, \
-}
-
-#define CTL_P1003_1B_ASYNCHRONOUS_IO 1 /* boolean */
-#define CTL_P1003_1B_MAPPED_FILES 2 /* boolean */
-#define CTL_P1003_1B_MEMLOCK 3 /* boolean */
-#define CTL_P1003_1B_MEMLOCK_RANGE 4 /* boolean */
-#define CTL_P1003_1B_MEMORY_PROTECTION 5 /* boolean */
-#define CTL_P1003_1B_MESSAGE_PASSING 6 /* boolean */
-#define CTL_P1003_1B_PRIORITIZED_IO 7 /* boolean */
-#define CTL_P1003_1B_PRIORITY_SCHEDULING 8 /* boolean */
-#define CTL_P1003_1B_REALTIME_SIGNALS 9 /* boolean */
-#define CTL_P1003_1B_SEMAPHORES 10 /* boolean */
-#define CTL_P1003_1B_FSYNC 11 /* boolean */
-#define CTL_P1003_1B_SHARED_MEMORY_OBJECTS 12 /* boolean */
-#define CTL_P1003_1B_SYNCHRONIZED_IO 13 /* boolean */
-#define CTL_P1003_1B_TIMERS 14 /* boolean */
-#define CTL_P1003_1B_AIO_LISTIO_MAX 15 /* int */
-#define CTL_P1003_1B_AIO_MAX 16 /* int */
-#define CTL_P1003_1B_AIO_PRIO_DELTA_MAX 17 /* int */
-#define CTL_P1003_1B_DELAYTIMER_MAX 18 /* int */
-#define CTL_P1003_1B_MQ_OPEN_MAX 19 /* int */
-#define CTL_P1003_1B_PAGESIZE 20 /* int */
-#define CTL_P1003_1B_RTSIG_MAX 21 /* int */
-#define CTL_P1003_1B_SEM_NSEMS_MAX 22 /* int */
-#define CTL_P1003_1B_SEM_VALUE_MAX 23 /* int */
-#define CTL_P1003_1B_SIGQUEUE_MAX 24 /* int */
-#define CTL_P1003_1B_TIMER_MAX 25 /* int */
-
-#define CTL_P1003_1B_MAXID 26
-
-#define CTL_P1003_1B_NAMES { \
- { 0, 0 }, \
- { "asynchronous_io", CTLTYPE_INT }, \
- { "mapped_files", CTLTYPE_INT }, \
- { "memlock", CTLTYPE_INT }, \
- { "memlock_range", CTLTYPE_INT }, \
- { "memory_protection", CTLTYPE_INT }, \
- { "message_passing", CTLTYPE_INT }, \
- { "prioritized_io", CTLTYPE_INT }, \
- { "priority_scheduling", CTLTYPE_INT }, \
- { "realtime_signals", CTLTYPE_INT }, \
- { "semaphores", CTLTYPE_INT }, \
- { "fsync", CTLTYPE_INT }, \
- { "shared_memory_objects", CTLTYPE_INT }, \
- { "synchronized_io", CTLTYPE_INT }, \
- { "timers", CTLTYPE_INT }, \
- { "aio_listio_max", CTLTYPE_INT }, \
- { "aio_max", CTLTYPE_INT }, \
- { "aio_prio_delta_max", CTLTYPE_INT }, \
- { "delaytimer_max", CTLTYPE_INT }, \
- { "mq_open_max", CTLTYPE_INT }, \
- { "pagesize", CTLTYPE_INT }, \
- { "rtsig_max", CTLTYPE_INT }, \
- { "nsems_max", CTLTYPE_INT }, \
- { "sem_value_max", CTLTYPE_INT }, \
- { "sigqueue_max", CTLTYPE_INT }, \
- { "timer_max", CTLTYPE_INT }, \
-}
+
+#define CTL_P1003_1B_ASYNCHRONOUS_IO 1 /* boolean */
+#define CTL_P1003_1B_MAPPED_FILES 2 /* boolean */
+#define CTL_P1003_1B_MEMLOCK 3 /* boolean */
+#define CTL_P1003_1B_MEMLOCK_RANGE 4 /* boolean */
+#define CTL_P1003_1B_MEMORY_PROTECTION 5 /* boolean */
+#define CTL_P1003_1B_MESSAGE_PASSING 6 /* boolean */
+#define CTL_P1003_1B_PRIORITIZED_IO 7 /* boolean */
+#define CTL_P1003_1B_PRIORITY_SCHEDULING 8 /* boolean */
+#define CTL_P1003_1B_REALTIME_SIGNALS 9 /* boolean */
+#define CTL_P1003_1B_SEMAPHORES 10 /* boolean */
+#define CTL_P1003_1B_FSYNC 11 /* boolean */
+#define CTL_P1003_1B_SHARED_MEMORY_OBJECTS 12 /* boolean */
+#define CTL_P1003_1B_SYNCHRONIZED_IO 13 /* boolean */
+#define CTL_P1003_1B_TIMERS 14 /* boolean */
+#define CTL_P1003_1B_AIO_LISTIO_MAX 15 /* int */
+#define CTL_P1003_1B_AIO_MAX 16 /* int */
+#define CTL_P1003_1B_AIO_PRIO_DELTA_MAX 17 /* int */
+#define CTL_P1003_1B_DELAYTIMER_MAX 18 /* int */
+#define CTL_P1003_1B_MQ_OPEN_MAX 19 /* int */
+#define CTL_P1003_1B_PAGESIZE 20 /* int */
+#define CTL_P1003_1B_RTSIG_MAX 21 /* int */
+#define CTL_P1003_1B_SEM_NSEMS_MAX 22 /* int */
+#define CTL_P1003_1B_SEM_VALUE_MAX 23 /* int */
+#define CTL_P1003_1B_SIGQUEUE_MAX 24 /* int */
+#define CTL_P1003_1B_TIMER_MAX 25 /* int */
+
+#define CTL_P1003_1B_MAXID 26
#ifdef _KERNEL
@@ -859,49 +1034,54 @@ extern char kern_ident[];
/* Dynamic oid handling */
struct sysctl_oid *sysctl_add_oid(struct sysctl_ctx_list *clist,
- struct sysctl_oid_list *parent, int nbr, const char *name,
- int kind, void *arg1, intptr_t arg2,
- int (*handler) (SYSCTL_HANDLER_ARGS),
- const char *fmt, const char *descr);
+ struct sysctl_oid_list *parent, int nbr, const char *name, int kind,
+ void *arg1, intmax_t arg2, int (*handler)(SYSCTL_HANDLER_ARGS),
+ const char *fmt, const char *descr);
int sysctl_remove_name(struct sysctl_oid *parent, const char *name, int del,
- int recurse);
+ int recurse);
void sysctl_rename_oid(struct sysctl_oid *oidp, const char *name);
int sysctl_move_oid(struct sysctl_oid *oidp,
- struct sysctl_oid_list *parent);
+ struct sysctl_oid_list *parent);
int sysctl_remove_oid(struct sysctl_oid *oidp, int del, int recurse);
int sysctl_ctx_init(struct sysctl_ctx_list *clist);
int sysctl_ctx_free(struct sysctl_ctx_list *clist);
struct sysctl_ctx_entry *sysctl_ctx_entry_add(struct sysctl_ctx_list *clist,
- struct sysctl_oid *oidp);
+ struct sysctl_oid *oidp);
struct sysctl_ctx_entry *sysctl_ctx_entry_find(struct sysctl_ctx_list *clist,
- struct sysctl_oid *oidp);
+ struct sysctl_oid *oidp);
int sysctl_ctx_entry_del(struct sysctl_ctx_list *clist,
- struct sysctl_oid *oidp);
+ struct sysctl_oid *oidp);
int kernel_sysctl(struct thread *td, int *name, u_int namelen, void *old,
#ifndef __rtems__
- size_t *oldlenp, void *new, size_t newlen,
+ size_t *oldlenp, void *new, size_t newlen, size_t *retval,
#else /* __rtems__ */
- size_t *oldlenp, const void *newp, size_t newlen,
+ size_t *oldlenp, const void *newp, size_t newlen, size_t *retval,
#endif /* __rtems__ */
- size_t *retval, int flags);
+ int flags);
+int kernel_sysctlbyname(struct thread *td, char *name, void *old,
#ifndef __rtems__
-int kernel_sysctlbyname(struct thread *td, char *name,
- void *old, size_t *oldlenp, void *new, size_t newlen,
- size_t *retval, int flags);
+ size_t *oldlenp, void *new, size_t newlen, size_t *retval,
+#else /* __rtems__ */
+ size_t *oldlenp, const void *newp, size_t newlen, size_t *retval,
+#endif /* __rtems__ */
+ int flags);
int userland_sysctl(struct thread *td, int *name, u_int namelen, void *old,
- size_t *oldlenp, int inkernel, void *new, size_t newlen,
- size_t *retval, int flags);
+#ifndef __rtems__
+ size_t *oldlenp, int inkernel, void *new, size_t newlen,
+#else /* __rtems__ */
+ size_t *oldlenp, int inkernel, const void *newp, size_t newlen,
#endif /* __rtems__ */
+ size_t *retval, int flags);
int sysctl_find_oid(int *name, u_int namelen, struct sysctl_oid **noid,
- int *nindx, struct sysctl_req *req);
-void sysctl_lock(void);
-void sysctl_unlock(void);
+ int *nindx, struct sysctl_req *req);
+void sysctl_wlock(void);
+void sysctl_wunlock(void);
int sysctl_wire_old_buffer(struct sysctl_req *req, size_t len);
struct sbuf;
-struct sbuf *sbuf_new_for_sysctl(struct sbuf *, char *, int,
- struct sysctl_req *);
+struct sbuf *sbuf_new_for_sysctl(struct sbuf *, char *, int,
+ struct sysctl_req *);
#else /* !_KERNEL */
#include <sys/cdefs.h>
diff --git a/freebsd/sys/sys/syslog.h b/freebsd/sys/sys/syslog.h
index 6f128314..61bad21c 100644
--- a/freebsd/sys/sys/syslog.h
+++ b/freebsd/sys/sys/syslog.h
@@ -69,7 +69,7 @@ typedef struct _code {
int c_val;
} CODE;
-CODE prioritynames[] = {
+static const CODE prioritynames[] = {
{ "alert", LOG_ALERT, },
{ "crit", LOG_CRIT, },
{ "debug", LOG_DEBUG, },
@@ -122,7 +122,7 @@ CODE prioritynames[] = {
#define LOG_FAC(p) (((p) & LOG_FACMASK) >> 3)
#ifdef SYSLOG_NAMES
-CODE facilitynames[] = {
+static const CODE facilitynames[] = {
{ "auth", LOG_AUTH, },
{ "authpriv", LOG_AUTHPRIV, },
{ "console", LOG_CONSOLE, },
diff --git a/freebsd/sys/sys/sysproto.h b/freebsd/sys/sys/sysproto.h
index 479eeb4c..1ee7bb4e 100644
--- a/freebsd/sys/sys/sysproto.h
+++ b/freebsd/sys/sys/sysproto.h
@@ -3,7 +3,7 @@
*
* DO NOT EDIT-- this file is automatically generated.
* $FreeBSD$
- * created from FreeBSD: stable/9/sys/kern/syscalls.master 276957 2015-01-11 07:10:43Z dchagin
+ * created from FreeBSD: head/sys/kern/syscalls.master 304395 2016-08-18 10:50:40Z gnn
*/
#ifndef _SYS_SYSPROTO_H_
@@ -12,6 +12,7 @@
#include <sys/signal.h>
#include <sys/acl.h>
#include <rtems/bsd/sys/cpuset.h>
+#include <sys/_ffcounter.h>
#include <sys/_semaphore.h>
#include <sys/ucontext.h>
#include <sys/wait.h>
@@ -166,15 +167,15 @@ struct getsockname_args {
#ifndef __rtems__
struct access_args {
char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)];
- char flags_l_[PADL_(int)]; int flags; char flags_r_[PADR_(int)];
+ char amode_l_[PADL_(int)]; int amode; char amode_r_[PADR_(int)];
};
struct chflags_args {
- char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)];
- char flags_l_[PADL_(int)]; int flags; char flags_r_[PADR_(int)];
+ char path_l_[PADL_(const char *)]; const char * path; char path_r_[PADR_(const char *)];
+ char flags_l_[PADL_(u_long)]; u_long flags; char flags_r_[PADR_(u_long)];
};
struct fchflags_args {
char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
- char flags_l_[PADL_(int)]; int flags; char flags_r_[PADR_(int)];
+ char flags_l_[PADL_(u_long)]; u_long flags; char flags_r_[PADR_(u_long)];
};
struct sync_args {
register_t dummy;
@@ -189,7 +190,7 @@ struct getppid_args {
struct dup_args {
char fd_l_[PADL_(u_int)]; u_int fd; char fd_r_[PADR_(u_int)];
};
-struct pipe_args {
+struct freebsd10_pipe_args {
register_t dummy;
};
struct getegid_args {
@@ -283,7 +284,7 @@ struct munmap_args {
char len_l_[PADL_(size_t)]; size_t len; char len_r_[PADR_(size_t)];
};
struct mprotect_args {
- char addr_l_[PADL_(const void *)]; const void * addr; char addr_r_[PADR_(const void *)];
+ char addr_l_[PADL_(void *)]; void * addr; char addr_r_[PADR_(void *)];
char len_l_[PADL_(size_t)]; size_t len; char len_r_[PADR_(size_t)];
char prot_l_[PADL_(int)]; int prot; char prot_r_[PADR_(int)];
};
@@ -566,20 +567,6 @@ struct shmsys_args {
char a3_l_[PADL_(int)]; int a3; char a3_r_[PADR_(int)];
char a4_l_[PADL_(int)]; int a4; char a4_r_[PADR_(int)];
};
-struct freebsd6_pread_args {
- char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
- char buf_l_[PADL_(void *)]; void * buf; char buf_r_[PADR_(void *)];
- char nbyte_l_[PADL_(size_t)]; size_t nbyte; char nbyte_r_[PADR_(size_t)];
- char pad_l_[PADL_(int)]; int pad; char pad_r_[PADR_(int)];
- char offset_l_[PADL_(off_t)]; off_t offset; char offset_r_[PADR_(off_t)];
-};
-struct freebsd6_pwrite_args {
- char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
- char buf_l_[PADL_(const void *)]; const void * buf; char buf_r_[PADR_(const void *)];
- char nbyte_l_[PADL_(size_t)]; size_t nbyte; char nbyte_r_[PADR_(size_t)];
- char pad_l_[PADL_(int)]; int pad; char pad_r_[PADR_(int)];
- char offset_l_[PADL_(off_t)]; off_t offset; char offset_r_[PADR_(off_t)];
-};
#endif /* __rtems__ */
struct setfib_args {
char fibnum_l_[PADL_(int)]; int fibnum; char fibnum_r_[PADR_(int)];
@@ -631,31 +618,6 @@ struct getdirentries_args {
char count_l_[PADL_(u_int)]; u_int count; char count_r_[PADR_(u_int)];
char basep_l_[PADL_(long *)]; long * basep; char basep_r_[PADR_(long *)];
};
-struct freebsd6_mmap_args {
- char addr_l_[PADL_(caddr_t)]; caddr_t addr; char addr_r_[PADR_(caddr_t)];
- char len_l_[PADL_(size_t)]; size_t len; char len_r_[PADR_(size_t)];
- char prot_l_[PADL_(int)]; int prot; char prot_r_[PADR_(int)];
- char flags_l_[PADL_(int)]; int flags; char flags_r_[PADR_(int)];
- char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
- char pad_l_[PADL_(int)]; int pad; char pad_r_[PADR_(int)];
- char pos_l_[PADL_(off_t)]; off_t pos; char pos_r_[PADR_(off_t)];
-};
-struct freebsd6_lseek_args {
- char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
- char pad_l_[PADL_(int)]; int pad; char pad_r_[PADR_(int)];
- char offset_l_[PADL_(off_t)]; off_t offset; char offset_r_[PADR_(off_t)];
- char whence_l_[PADL_(int)]; int whence; char whence_r_[PADR_(int)];
-};
-struct freebsd6_truncate_args {
- char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)];
- char pad_l_[PADL_(int)]; int pad; char pad_r_[PADR_(int)];
- char length_l_[PADL_(off_t)]; off_t length; char length_r_[PADR_(off_t)];
-};
-struct freebsd6_ftruncate_args {
- char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
- char pad_l_[PADL_(int)]; int pad; char pad_r_[PADR_(int)];
- char length_l_[PADL_(off_t)]; off_t length; char length_r_[PADR_(off_t)];
-};
struct sysctl_args {
char name_l_[PADL_(int *)]; int * name; char name_r_[PADR_(int *)];
char namelen_l_[PADL_(u_int)]; u_int namelen; char namelen_r_[PADR_(u_int)];
@@ -766,6 +728,15 @@ struct nanosleep_args {
char rqtp_l_[PADL_(const struct timespec *)]; const struct timespec * rqtp; char rqtp_r_[PADR_(const struct timespec *)];
char rmtp_l_[PADL_(struct timespec *)]; struct timespec * rmtp; char rmtp_r_[PADR_(struct timespec *)];
};
+struct ffclock_getcounter_args {
+ char ffcount_l_[PADL_(ffcounter *)]; ffcounter * ffcount; char ffcount_r_[PADR_(ffcounter *)];
+};
+struct ffclock_setestimate_args {
+ char cest_l_[PADL_(struct ffclock_estimate *)]; struct ffclock_estimate * cest; char cest_r_[PADR_(struct ffclock_estimate *)];
+};
+struct ffclock_getestimate_args {
+ char cest_l_[PADL_(struct ffclock_estimate *)]; struct ffclock_estimate * cest; char cest_r_[PADR_(struct ffclock_estimate *)];
+};
struct clock_getcpuclockid2_args {
char id_l_[PADL_(id_t)]; id_t id; char id_r_[PADR_(id_t)];
char which_l_[PADL_(int)]; int which; char which_r_[PADR_(int)];
@@ -782,11 +753,6 @@ struct minherit_args {
struct rfork_args {
char flags_l_[PADL_(int)]; int flags; char flags_r_[PADR_(int)];
};
-struct openbsd_poll_args {
- char fds_l_[PADL_(struct pollfd *)]; struct pollfd * fds; char fds_r_[PADR_(struct pollfd *)];
- char nfds_l_[PADL_(u_int)]; u_int nfds; char nfds_r_[PADR_(u_int)];
- char timeout_l_[PADL_(int)]; int timeout; char timeout_r_[PADR_(int)];
-};
struct issetugid_args {
register_t dummy;
};
@@ -912,18 +878,6 @@ struct aio_cancel_args {
struct aio_error_args {
char aiocbp_l_[PADL_(struct aiocb *)]; struct aiocb * aiocbp; char aiocbp_r_[PADR_(struct aiocb *)];
};
-struct oaio_read_args {
- char aiocbp_l_[PADL_(struct oaiocb *)]; struct oaiocb * aiocbp; char aiocbp_r_[PADR_(struct oaiocb *)];
-};
-struct oaio_write_args {
- char aiocbp_l_[PADL_(struct oaiocb *)]; struct oaiocb * aiocbp; char aiocbp_r_[PADR_(struct oaiocb *)];
-};
-struct olio_listio_args {
- char mode_l_[PADL_(int)]; int mode; char mode_r_[PADR_(int)];
- char acb_list_l_[PADL_(struct oaiocb *const *)]; struct oaiocb *const * acb_list; char acb_list_r_[PADR_(struct oaiocb *const *)];
- char nent_l_[PADL_(int)]; int nent; char nent_r_[PADR_(int)];
- char sig_l_[PADL_(struct osigevent *)]; struct osigevent * sig; char sig_r_[PADR_(struct osigevent *)];
-};
struct yield_args {
register_t dummy;
};
@@ -1124,7 +1078,7 @@ struct __setugid_args {
};
struct eaccess_args {
char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)];
- char flags_l_[PADL_(int)]; int flags; char flags_r_[PADR_(int)];
+ char amode_l_[PADL_(int)]; int amode; char amode_r_[PADR_(int)];
};
struct afs3_syscall_args {
char syscall_l_[PADL_(long)]; long syscall; char syscall_r_[PADR_(long)];
@@ -1170,7 +1124,7 @@ struct kenv_args {
};
struct lchflags_args {
char path_l_[PADL_(const char *)]; const char * path; char path_r_[PADR_(const char *)];
- char flags_l_[PADL_(int)]; int flags; char flags_r_[PADR_(int)];
+ char flags_l_[PADL_(u_long)]; u_long flags; char flags_r_[PADR_(u_long)];
};
struct uuidgen_args {
char store_l_[PADL_(struct uuid *)]; struct uuid * store; char store_r_[PADR_(struct uuid *)];
@@ -1336,12 +1290,6 @@ struct thr_kill_args {
char id_l_[PADL_(long)]; long id; char id_r_[PADR_(long)];
char sig_l_[PADL_(int)]; int sig; char sig_r_[PADR_(int)];
};
-struct _umtx_lock_args {
- char umtx_l_[PADL_(struct umtx *)]; struct umtx * umtx; char umtx_r_[PADR_(struct umtx *)];
-};
-struct _umtx_unlock_args {
- char umtx_l_[PADL_(struct umtx *)]; struct umtx * umtx; char umtx_r_[PADR_(struct umtx *)];
-};
struct jail_attach_args {
char jid_l_[PADL_(int)]; int jid; char jid_r_[PADR_(int)];
};
@@ -1583,7 +1531,7 @@ struct cpuset_setaffinity_args {
struct faccessat_args {
char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)];
- char mode_l_[PADL_(int)]; int mode; char mode_r_[PADR_(int)];
+ char amode_l_[PADL_(int)]; int amode; char amode_r_[PADR_(int)];
char flag_l_[PADL_(int)]; int flag; char flag_r_[PADR_(int)];
};
struct fchmodat_args {
@@ -1708,13 +1656,10 @@ struct lpathconf_args {
char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)];
char name_l_[PADL_(int)]; int name; char name_r_[PADR_(int)];
};
-struct cap_new_args {
- char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
- char rights_l_[PADL_(u_int64_t)]; u_int64_t rights; char rights_r_[PADR_(u_int64_t)];
-};
-struct cap_getrights_args {
+struct __cap_rights_get_args {
+ char version_l_[PADL_(int)]; int version; char version_r_[PADR_(int)];
char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
- char rightsp_l_[PADL_(u_int64_t *)]; u_int64_t * rightsp; char rightsp_r_[PADR_(u_int64_t *)];
+ char rightsp_l_[PADL_(cap_rights_t *)]; cap_rights_t * rightsp; char rightsp_r_[PADR_(cap_rights_t *)];
};
struct cap_enter_args {
register_t dummy;
@@ -1798,12 +1743,94 @@ struct wait6_args {
char wrusage_l_[PADL_(struct __wrusage *)]; struct __wrusage * wrusage; char wrusage_r_[PADR_(struct __wrusage *)];
char info_l_[PADL_(siginfo_t *)]; siginfo_t * info; char info_r_[PADR_(siginfo_t *)];
};
+struct cap_rights_limit_args {
+ char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
+ char rightsp_l_[PADL_(cap_rights_t *)]; cap_rights_t * rightsp; char rightsp_r_[PADR_(cap_rights_t *)];
+};
+struct cap_ioctls_limit_args {
+ char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
+ char cmds_l_[PADL_(const u_long *)]; const u_long * cmds; char cmds_r_[PADR_(const u_long *)];
+ char ncmds_l_[PADL_(size_t)]; size_t ncmds; char ncmds_r_[PADR_(size_t)];
+};
+struct cap_ioctls_get_args {
+ char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
+ char cmds_l_[PADL_(u_long *)]; u_long * cmds; char cmds_r_[PADR_(u_long *)];
+ char maxcmds_l_[PADL_(size_t)]; size_t maxcmds; char maxcmds_r_[PADR_(size_t)];
+};
+struct cap_fcntls_limit_args {
+ char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
+ char fcntlrights_l_[PADL_(uint32_t)]; uint32_t fcntlrights; char fcntlrights_r_[PADR_(uint32_t)];
+};
+struct cap_fcntls_get_args {
+ char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
+ char fcntlrightsp_l_[PADL_(uint32_t *)]; uint32_t * fcntlrightsp; char fcntlrightsp_r_[PADR_(uint32_t *)];
+};
+struct bindat_args {
+ char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
+ char s_l_[PADL_(int)]; int s; char s_r_[PADR_(int)];
+ char name_l_[PADL_(caddr_t)]; caddr_t name; char name_r_[PADR_(caddr_t)];
+ char namelen_l_[PADL_(int)]; int namelen; char namelen_r_[PADR_(int)];
+};
+struct connectat_args {
+ char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
+ char s_l_[PADL_(int)]; int s; char s_r_[PADR_(int)];
+ char name_l_[PADL_(caddr_t)]; caddr_t name; char name_r_[PADR_(caddr_t)];
+ char namelen_l_[PADL_(int)]; int namelen; char namelen_r_[PADR_(int)];
+};
+struct chflagsat_args {
+ char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
+ char path_l_[PADL_(const char *)]; const char * path; char path_r_[PADR_(const char *)];
+ char flags_l_[PADL_(u_long)]; u_long flags; char flags_r_[PADR_(u_long)];
+ char atflag_l_[PADL_(int)]; int atflag; char atflag_r_[PADR_(int)];
+};
+struct accept4_args {
+ char s_l_[PADL_(int)]; int s; char s_r_[PADR_(int)];
+ char name_l_[PADL_(struct sockaddr *__restrict)]; struct sockaddr *__restrict name; char name_r_[PADR_(struct sockaddr *__restrict)];
+ char anamelen_l_[PADL_(__socklen_t *__restrict)]; __socklen_t *__restrict anamelen; char anamelen_r_[PADR_(__socklen_t *__restrict)];
+ char flags_l_[PADL_(int)]; int flags; char flags_r_[PADR_(int)];
+};
+struct pipe2_args {
+ char fildes_l_[PADL_(int *)]; int * fildes; char fildes_r_[PADR_(int *)];
+ char flags_l_[PADL_(int)]; int flags; char flags_r_[PADR_(int)];
+};
+struct aio_mlock_args {
+ char aiocbp_l_[PADL_(struct aiocb *)]; struct aiocb * aiocbp; char aiocbp_r_[PADR_(struct aiocb *)];
+};
struct procctl_args {
char idtype_l_[PADL_(idtype_t)]; idtype_t idtype; char idtype_r_[PADR_(idtype_t)];
char id_l_[PADL_(id_t)]; id_t id; char id_r_[PADR_(id_t)];
char com_l_[PADL_(int)]; int com; char com_r_[PADR_(int)];
char data_l_[PADL_(void *)]; void * data; char data_r_[PADR_(void *)];
};
+struct ppoll_args {
+ char fds_l_[PADL_(struct pollfd *)]; struct pollfd * fds; char fds_r_[PADR_(struct pollfd *)];
+ char nfds_l_[PADL_(u_int)]; u_int nfds; char nfds_r_[PADR_(u_int)];
+ char ts_l_[PADL_(const struct timespec *)]; const struct timespec * ts; char ts_r_[PADR_(const struct timespec *)];
+ char set_l_[PADL_(const sigset_t *)]; const sigset_t * set; char set_r_[PADR_(const sigset_t *)];
+};
+struct futimens_args {
+ char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
+ char times_l_[PADL_(struct timespec *)]; struct timespec * times; char times_r_[PADR_(struct timespec *)];
+};
+struct utimensat_args {
+ char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
+ char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)];
+ char times_l_[PADL_(struct timespec *)]; struct timespec * times; char times_r_[PADR_(struct timespec *)];
+ char flag_l_[PADL_(int)]; int flag; char flag_r_[PADR_(int)];
+};
+struct numa_getaffinity_args {
+ char which_l_[PADL_(cpuwhich_t)]; cpuwhich_t which; char which_r_[PADR_(cpuwhich_t)];
+ char id_l_[PADL_(id_t)]; id_t id; char id_r_[PADR_(id_t)];
+ char policy_l_[PADL_(struct vm_domain_policy_entry *)]; struct vm_domain_policy_entry * policy; char policy_r_[PADR_(struct vm_domain_policy_entry *)];
+};
+struct numa_setaffinity_args {
+ char which_l_[PADL_(cpuwhich_t)]; cpuwhich_t which; char which_r_[PADR_(cpuwhich_t)];
+ char id_l_[PADL_(id_t)]; id_t id; char id_r_[PADR_(id_t)];
+ char policy_l_[PADL_(const struct vm_domain_policy_entry *)]; const struct vm_domain_policy_entry * policy; char policy_r_[PADR_(const struct vm_domain_policy_entry *)];
+};
+struct fdatasync_args {
+ char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
+};
int nosys(struct thread *, struct nosys_args *);
void sys_sys_exit(struct thread *, struct sys_exit_args *);
int sys_fork(struct thread *, struct fork_args *);
@@ -1840,7 +1867,6 @@ int sys_sync(struct thread *, struct sync_args *);
int sys_kill(struct thread *, struct kill_args *);
int sys_getppid(struct thread *, struct getppid_args *);
int sys_dup(struct thread *, struct dup_args *);
-int sys_pipe(struct thread *, struct pipe_args *);
int sys_getegid(struct thread *, struct getegid_args *);
int sys_profil(struct thread *, struct profil_args *);
int sys_ktrace(struct thread *, struct ktrace_args *);
@@ -1916,8 +1942,6 @@ int sys_rtprio(struct thread *, struct rtprio_args *);
int sys_semsys(struct thread *, struct semsys_args *);
int sys_msgsys(struct thread *, struct msgsys_args *);
int sys_shmsys(struct thread *, struct shmsys_args *);
-int freebsd6_pread(struct thread *, struct freebsd6_pread_args *);
-int freebsd6_pwrite(struct thread *, struct freebsd6_pwrite_args *);
int sys_setfib(struct thread *, struct setfib_args *);
int sys_ntp_adjtime(struct thread *, struct ntp_adjtime_args *);
int sys_setgid(struct thread *, struct setgid_args *);
@@ -1931,10 +1955,6 @@ int sys_fpathconf(struct thread *, struct fpathconf_args *);
int sys_getrlimit(struct thread *, struct __getrlimit_args *);
int sys_setrlimit(struct thread *, struct __setrlimit_args *);
int sys_getdirentries(struct thread *, struct getdirentries_args *);
-int freebsd6_mmap(struct thread *, struct freebsd6_mmap_args *);
-int freebsd6_lseek(struct thread *, struct freebsd6_lseek_args *);
-int freebsd6_truncate(struct thread *, struct freebsd6_truncate_args *);
-int freebsd6_ftruncate(struct thread *, struct freebsd6_ftruncate_args *);
int sys___sysctl(struct thread *, struct sysctl_args *);
int sys_mlock(struct thread *, struct mlock_args *);
int sys_munlock(struct thread *, struct munlock_args *);
@@ -1959,11 +1979,13 @@ int sys_ktimer_settime(struct thread *, struct ktimer_settime_args *);
int sys_ktimer_gettime(struct thread *, struct ktimer_gettime_args *);
int sys_ktimer_getoverrun(struct thread *, struct ktimer_getoverrun_args *);
int sys_nanosleep(struct thread *, struct nanosleep_args *);
+int sys_ffclock_getcounter(struct thread *, struct ffclock_getcounter_args *);
+int sys_ffclock_setestimate(struct thread *, struct ffclock_setestimate_args *);
+int sys_ffclock_getestimate(struct thread *, struct ffclock_getestimate_args *);
int sys_clock_getcpuclockid2(struct thread *, struct clock_getcpuclockid2_args *);
int sys_ntp_gettime(struct thread *, struct ntp_gettime_args *);
int sys_minherit(struct thread *, struct minherit_args *);
int sys_rfork(struct thread *, struct rfork_args *);
-int sys_openbsd_poll(struct thread *, struct openbsd_poll_args *);
int sys_issetugid(struct thread *, struct issetugid_args *);
int sys_lchown(struct thread *, struct lchown_args *);
int sys_aio_read(struct thread *, struct aio_read_args *);
@@ -1996,9 +2018,6 @@ int sys_aio_return(struct thread *, struct aio_return_args *);
int sys_aio_suspend(struct thread *, struct aio_suspend_args *);
int sys_aio_cancel(struct thread *, struct aio_cancel_args *);
int sys_aio_error(struct thread *, struct aio_error_args *);
-int sys_oaio_read(struct thread *, struct oaio_read_args *);
-int sys_oaio_write(struct thread *, struct oaio_write_args *);
-int sys_olio_listio(struct thread *, struct olio_listio_args *);
int sys_yield(struct thread *, struct yield_args *);
int sys_mlockall(struct thread *, struct mlockall_args *);
int sys_munlockall(struct thread *, struct munlockall_args *);
@@ -2090,8 +2109,6 @@ int sys_thr_create(struct thread *, struct thr_create_args *);
int sys_thr_exit(struct thread *, struct thr_exit_args *);
int sys_thr_self(struct thread *, struct thr_self_args *);
int sys_thr_kill(struct thread *, struct thr_kill_args *);
-int sys__umtx_lock(struct thread *, struct _umtx_lock_args *);
-int sys__umtx_unlock(struct thread *, struct _umtx_unlock_args *);
int sys_jail_attach(struct thread *, struct jail_attach_args *);
int sys_extattr_list_fd(struct thread *, struct extattr_list_fd_args *);
int sys_extattr_list_file(struct thread *, struct extattr_list_file_args *);
@@ -2165,8 +2182,7 @@ int sys___semctl(struct thread *, struct __semctl_args *);
int sys_msgctl(struct thread *, struct msgctl_args *);
int sys_shmctl(struct thread *, struct shmctl_args *);
int sys_lpathconf(struct thread *, struct lpathconf_args *);
-int sys_cap_new(struct thread *, struct cap_new_args *);
-int sys_cap_getrights(struct thread *, struct cap_getrights_args *);
+int sys___cap_rights_get(struct thread *, struct __cap_rights_get_args *);
int sys_cap_enter(struct thread *, struct cap_enter_args *);
int sys_cap_getmode(struct thread *, struct cap_getmode_args *);
int sys_pdfork(struct thread *, struct pdfork_args *);
@@ -2183,7 +2199,24 @@ int sys_rctl_remove_rule(struct thread *, struct rctl_remove_rule_args *);
int sys_posix_fallocate(struct thread *, struct posix_fallocate_args *);
int sys_posix_fadvise(struct thread *, struct posix_fadvise_args *);
int sys_wait6(struct thread *, struct wait6_args *);
+int sys_cap_rights_limit(struct thread *, struct cap_rights_limit_args *);
+int sys_cap_ioctls_limit(struct thread *, struct cap_ioctls_limit_args *);
+int sys_cap_ioctls_get(struct thread *, struct cap_ioctls_get_args *);
+int sys_cap_fcntls_limit(struct thread *, struct cap_fcntls_limit_args *);
+int sys_cap_fcntls_get(struct thread *, struct cap_fcntls_get_args *);
+int sys_bindat(struct thread *, struct bindat_args *);
+int sys_connectat(struct thread *, struct connectat_args *);
+int sys_chflagsat(struct thread *, struct chflagsat_args *);
+int sys_accept4(struct thread *, struct accept4_args *);
+int sys_pipe2(struct thread *, struct pipe2_args *);
+int sys_aio_mlock(struct thread *, struct aio_mlock_args *);
int sys_procctl(struct thread *, struct procctl_args *);
+int sys_ppoll(struct thread *, struct ppoll_args *);
+int sys_futimens(struct thread *, struct futimens_args *);
+int sys_utimensat(struct thread *, struct utimensat_args *);
+int sys_numa_getaffinity(struct thread *, struct numa_getaffinity_args *);
+int sys_numa_setaffinity(struct thread *, struct numa_setaffinity_args *);
+int sys_fdatasync(struct thread *, struct fdatasync_args *);
#ifdef COMPAT_43
@@ -2420,6 +2453,66 @@ int freebsd4_sigreturn(struct thread *, struct freebsd4_sigreturn_args *);
#ifdef COMPAT_FREEBSD6
+struct freebsd6_pread_args {
+ char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
+ char buf_l_[PADL_(void *)]; void * buf; char buf_r_[PADR_(void *)];
+ char nbyte_l_[PADL_(size_t)]; size_t nbyte; char nbyte_r_[PADR_(size_t)];
+ char pad_l_[PADL_(int)]; int pad; char pad_r_[PADR_(int)];
+ char offset_l_[PADL_(off_t)]; off_t offset; char offset_r_[PADR_(off_t)];
+};
+struct freebsd6_pwrite_args {
+ char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
+ char buf_l_[PADL_(const void *)]; const void * buf; char buf_r_[PADR_(const void *)];
+ char nbyte_l_[PADL_(size_t)]; size_t nbyte; char nbyte_r_[PADR_(size_t)];
+ char pad_l_[PADL_(int)]; int pad; char pad_r_[PADR_(int)];
+ char offset_l_[PADL_(off_t)]; off_t offset; char offset_r_[PADR_(off_t)];
+};
+struct freebsd6_mmap_args {
+ char addr_l_[PADL_(caddr_t)]; caddr_t addr; char addr_r_[PADR_(caddr_t)];
+ char len_l_[PADL_(size_t)]; size_t len; char len_r_[PADR_(size_t)];
+ char prot_l_[PADL_(int)]; int prot; char prot_r_[PADR_(int)];
+ char flags_l_[PADL_(int)]; int flags; char flags_r_[PADR_(int)];
+ char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
+ char pad_l_[PADL_(int)]; int pad; char pad_r_[PADR_(int)];
+ char pos_l_[PADL_(off_t)]; off_t pos; char pos_r_[PADR_(off_t)];
+};
+struct freebsd6_lseek_args {
+ char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
+ char pad_l_[PADL_(int)]; int pad; char pad_r_[PADR_(int)];
+ char offset_l_[PADL_(off_t)]; off_t offset; char offset_r_[PADR_(off_t)];
+ char whence_l_[PADL_(int)]; int whence; char whence_r_[PADR_(int)];
+};
+struct freebsd6_truncate_args {
+ char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)];
+ char pad_l_[PADL_(int)]; int pad; char pad_r_[PADR_(int)];
+ char length_l_[PADL_(off_t)]; off_t length; char length_r_[PADR_(off_t)];
+};
+struct freebsd6_ftruncate_args {
+ char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
+ char pad_l_[PADL_(int)]; int pad; char pad_r_[PADR_(int)];
+ char length_l_[PADL_(off_t)]; off_t length; char length_r_[PADR_(off_t)];
+};
+struct freebsd6_aio_read_args {
+ char aiocbp_l_[PADL_(struct oaiocb *)]; struct oaiocb * aiocbp; char aiocbp_r_[PADR_(struct oaiocb *)];
+};
+struct freebsd6_aio_write_args {
+ char aiocbp_l_[PADL_(struct oaiocb *)]; struct oaiocb * aiocbp; char aiocbp_r_[PADR_(struct oaiocb *)];
+};
+struct freebsd6_lio_listio_args {
+ char mode_l_[PADL_(int)]; int mode; char mode_r_[PADR_(int)];
+ char acb_list_l_[PADL_(struct oaiocb *const *)]; struct oaiocb *const * acb_list; char acb_list_r_[PADR_(struct oaiocb *const *)];
+ char nent_l_[PADL_(int)]; int nent; char nent_r_[PADR_(int)];
+ char sig_l_[PADL_(struct osigevent *)]; struct osigevent * sig; char sig_r_[PADR_(struct osigevent *)];
+};
+int freebsd6_pread(struct thread *, struct freebsd6_pread_args *);
+int freebsd6_pwrite(struct thread *, struct freebsd6_pwrite_args *);
+int freebsd6_mmap(struct thread *, struct freebsd6_mmap_args *);
+int freebsd6_lseek(struct thread *, struct freebsd6_lseek_args *);
+int freebsd6_truncate(struct thread *, struct freebsd6_truncate_args *);
+int freebsd6_ftruncate(struct thread *, struct freebsd6_ftruncate_args *);
+int freebsd6_aio_read(struct thread *, struct freebsd6_aio_read_args *);
+int freebsd6_aio_write(struct thread *, struct freebsd6_aio_write_args *);
+int freebsd6_lio_listio(struct thread *, struct freebsd6_lio_listio_args *);
#endif /* COMPAT_FREEBSD6 */
@@ -2448,11 +2541,18 @@ int freebsd7_shmctl(struct thread *, struct freebsd7_shmctl_args *);
#endif /* COMPAT_FREEBSD7 */
+
+#ifdef COMPAT_FREEBSD10
+
+int freebsd10_pipe(struct thread *, struct freebsd10_pipe_args *);
+
+#endif /* COMPAT_FREEBSD10 */
+
#define SYS_AUE_syscall AUE_NULL
#define SYS_AUE_exit AUE_EXIT
#define SYS_AUE_fork AUE_FORK
-#define SYS_AUE_read AUE_NULL
-#define SYS_AUE_write AUE_NULL
+#define SYS_AUE_read AUE_READ
+#define SYS_AUE_write AUE_WRITE
#define SYS_AUE_open AUE_OPEN_RWTC
#define SYS_AUE_close AUE_CLOSE
#define SYS_AUE_wait4 AUE_WAIT4
@@ -2489,7 +2589,7 @@ int freebsd7_shmctl(struct thread *, struct freebsd7_shmctl_args *);
#define SYS_AUE_getppid AUE_GETPPID
#define SYS_AUE_olstat AUE_LSTAT
#define SYS_AUE_dup AUE_DUP
-#define SYS_AUE_pipe AUE_PIPE
+#define SYS_AUE_freebsd10_pipe AUE_PIPE
#define SYS_AUE_getegid AUE_GETEGID
#define SYS_AUE_profil AUE_PROFILE
#define SYS_AUE_ktrace AUE_KTRACE
@@ -2649,11 +2749,13 @@ int freebsd7_shmctl(struct thread *, struct freebsd7_shmctl_args *);
#define SYS_AUE_ktimer_gettime AUE_NULL
#define SYS_AUE_ktimer_getoverrun AUE_NULL
#define SYS_AUE_nanosleep AUE_NULL
+#define SYS_AUE_ffclock_getcounter AUE_NULL
+#define SYS_AUE_ffclock_setestimate AUE_NULL
+#define SYS_AUE_ffclock_getestimate AUE_NULL
#define SYS_AUE_clock_getcpuclockid2 AUE_NULL
#define SYS_AUE_ntp_gettime AUE_NULL
#define SYS_AUE_minherit AUE_MINHERIT
#define SYS_AUE_rfork AUE_RFORK
-#define SYS_AUE_openbsd_poll AUE_POLL
#define SYS_AUE_issetugid AUE_ISSETUGID
#define SYS_AUE_lchown AUE_LCHOWN
#define SYS_AUE_aio_read AUE_NULL
@@ -2687,9 +2789,9 @@ int freebsd7_shmctl(struct thread *, struct freebsd7_shmctl_args *);
#define SYS_AUE_aio_suspend AUE_NULL
#define SYS_AUE_aio_cancel AUE_NULL
#define SYS_AUE_aio_error AUE_NULL
-#define SYS_AUE_oaio_read AUE_NULL
-#define SYS_AUE_oaio_write AUE_NULL
-#define SYS_AUE_olio_listio AUE_NULL
+#define SYS_AUE_freebsd6_aio_read AUE_NULL
+#define SYS_AUE_freebsd6_aio_write AUE_NULL
+#define SYS_AUE_freebsd6_lio_listio AUE_NULL
#define SYS_AUE_yield AUE_NULL
#define SYS_AUE_mlockall AUE_MLOCKALL
#define SYS_AUE_munlockall AUE_MUNLOCKALL
@@ -2784,8 +2886,6 @@ int freebsd7_shmctl(struct thread *, struct freebsd7_shmctl_args *);
#define SYS_AUE_thr_exit AUE_NULL
#define SYS_AUE_thr_self AUE_NULL
#define SYS_AUE_thr_kill AUE_NULL
-#define SYS_AUE__umtx_lock AUE_NULL
-#define SYS_AUE__umtx_unlock AUE_NULL
#define SYS_AUE_jail_attach AUE_NULL
#define SYS_AUE_extattr_list_fd AUE_EXTATTR_LIST_FD
#define SYS_AUE_extattr_list_file AUE_EXTATTR_LIST_FILE
@@ -2859,8 +2959,7 @@ int freebsd7_shmctl(struct thread *, struct freebsd7_shmctl_args *);
#define SYS_AUE_msgctl AUE_MSGCTL
#define SYS_AUE_shmctl AUE_SHMCTL
#define SYS_AUE_lpathconf AUE_LPATHCONF
-#define SYS_AUE_cap_new AUE_CAP_NEW
-#define SYS_AUE_cap_getrights AUE_CAP_GETRIGHTS
+#define SYS_AUE___cap_rights_get AUE_CAP_RIGHTS_GET
#define SYS_AUE_cap_enter AUE_CAP_ENTER
#define SYS_AUE_cap_getmode AUE_CAP_GETMODE
#define SYS_AUE_pdfork AUE_PDFORK
@@ -2877,7 +2976,24 @@ int freebsd7_shmctl(struct thread *, struct freebsd7_shmctl_args *);
#define SYS_AUE_posix_fallocate AUE_NULL
#define SYS_AUE_posix_fadvise AUE_NULL
#define SYS_AUE_wait6 AUE_WAIT6
+#define SYS_AUE_cap_rights_limit AUE_CAP_RIGHTS_LIMIT
+#define SYS_AUE_cap_ioctls_limit AUE_CAP_IOCTLS_LIMIT
+#define SYS_AUE_cap_ioctls_get AUE_CAP_IOCTLS_GET
+#define SYS_AUE_cap_fcntls_limit AUE_CAP_FCNTLS_LIMIT
+#define SYS_AUE_cap_fcntls_get AUE_CAP_FCNTLS_GET
+#define SYS_AUE_bindat AUE_BINDAT
+#define SYS_AUE_connectat AUE_CONNECTAT
+#define SYS_AUE_chflagsat AUE_CHFLAGSAT
+#define SYS_AUE_accept4 AUE_ACCEPT
+#define SYS_AUE_pipe2 AUE_PIPE
+#define SYS_AUE_aio_mlock AUE_NULL
#define SYS_AUE_procctl AUE_NULL
+#define SYS_AUE_ppoll AUE_POLL
+#define SYS_AUE_futimens AUE_FUTIMES
+#define SYS_AUE_utimensat AUE_FUTIMESAT
+#define SYS_AUE_numa_getaffinity AUE_NULL
+#define SYS_AUE_numa_setaffinity AUE_NULL
+#define SYS_AUE_fdatasync AUE_FSYNC
#endif /* __rtems__ */
#undef PAD_
diff --git a/freebsd/sys/sys/systm.h b/freebsd/sys/sys/systm.h
index 36b3f59f..d2205a7a 100644
--- a/freebsd/sys/sys/systm.h
+++ b/freebsd/sys/sys/systm.h
@@ -47,6 +47,7 @@
#ifndef __rtems__
extern int cold; /* nonzero if we are doing a cold boot */
+extern int suspend_blocked; /* block suspend due to pending shutdown */
extern int rebooting; /* kern_reboot() has been called. */
#else /* __rtems__ */
/* In RTEMS there is no cold boot and reboot */
@@ -93,18 +94,24 @@ extern int vm_guest; /* Running as virtual machine guest? */
* Detected virtual machine guest types. The intention is to expand
* and/or add to the VM_GUEST_VM type if specific VM functionality is
* ever implemented (e.g. vendor-specific paravirtualization features).
+ * Keep in sync with vm_guest_sysctl_names[].
*/
-enum VM_GUEST { VM_GUEST_NO = 0, VM_GUEST_VM, VM_GUEST_XEN };
+enum VM_GUEST { VM_GUEST_NO = 0, VM_GUEST_VM, VM_GUEST_XEN, VM_GUEST_HV,
+ VM_GUEST_VMWARE, VM_GUEST_KVM, VM_LAST };
+
+#if defined(WITNESS) || defined(INVARIANT_SUPPORT)
+void kassert_panic(const char *fmt, ...) __printflike(1, 2);
+#endif
#ifdef INVARIANTS /* The option is always available */
#define KASSERT(exp,msg) do { \
if (__predict_false(!(exp))) \
- panic msg; \
+ kassert_panic msg; \
} while (0)
#define VNASSERT(exp, vp, msg) do { \
if (__predict_false(!(exp))) { \
vn_printf(vp, "VNASSERT failed\n"); \
- panic msg; \
+ kassert_panic msg; \
} \
} while (0)
#else
@@ -131,6 +138,12 @@ enum VM_GUEST { VM_GUEST_NO = 0, VM_GUEST_VM, VM_GUEST_XEN };
((uintptr_t)&(var) & (sizeof(void *) - 1)) == 0, msg)
/*
+ * Assert that a thread is in critical(9) section.
+ */
+#define CRITICAL_ASSERT(td) \
+ KASSERT((td)->td_critnest >= 1, ("Not in critical section"));
+
+/*
* If we have already panic'd and this is the thread that called
* panic(), then don't block on any mutexes but silently succeed.
* Otherwise, the kernel will deadlock since the scheduler isn't
@@ -162,10 +175,14 @@ extern char **kenvp;
extern const void *zero_region; /* address space maps to a zeroed page */
extern int unmapped_buf_allowed;
-extern int iosize_max_clamp;
-extern int devfs_iosize_max_clamp;
-#define IOSIZE_MAX (iosize_max_clamp ? INT_MAX : SSIZE_MAX)
-#define DEVFS_IOSIZE_MAX (devfs_iosize_max_clamp ? INT_MAX : SSIZE_MAX)
+
+#ifdef __LP64__
+#define IOSIZE_MAX iosize_max()
+#define DEVFS_IOSIZE_MAX devfs_iosize_max()
+#else
+#define IOSIZE_MAX SSIZE_MAX
+#define DEVFS_IOSIZE_MAX SSIZE_MAX
+#endif
/*
* General function declarations.
@@ -183,6 +200,7 @@ struct ucred;
struct uio;
struct _jmp_buf;
struct trapframe;
+struct eventtimer;
#ifndef __rtems__
int setjmp(struct _jmp_buf *) __returns_twice;
@@ -200,9 +218,12 @@ void *hashinit_flags(int count, struct malloc_type *type,
#define HASH_WAITOK 0x00000002
void *phashinit(int count, struct malloc_type *type, u_long *nentries);
+void *phashinit_flags(int count, struct malloc_type *type, u_long *nentries,
+ int flags);
void g_waitidle(void);
void panic(const char *, ...) __dead2 __printflike(1, 2);
+void vpanic(const char *, __va_list) __dead2 __printflike(1, 0);
void cpu_boot(int);
void cpu_flush_dcache(void *, size_t);
@@ -229,15 +250,24 @@ void init_param1(void);
void init_param2(long physpages);
void init_static_kenv(char *, size_t);
void tablefull(const char *);
+#ifdef EARLY_PRINTF
+typedef void early_putc_t(int ch);
+extern early_putc_t *early_putc;
+#endif
int kvprintf(char const *, void (*)(int, void*), void *, int,
__va_list) __printflike(1, 0);
void log(int, const char *, ...) __printflike(2, 3);
void log_console(struct uio *);
+void vlog(int, const char *, __va_list) __printflike(2, 0);
+int asprintf(char **ret, struct malloc_type *mtp, const char *format,
+ ...) __printflike(3, 4);
int printf(const char *, ...) __printflike(1, 2);
int snprintf(char *, size_t, const char *, ...) __printflike(3, 4);
int sprintf(char *buf, const char *, ...) __printflike(2, 3);
int uprintf(const char *, ...) __printflike(1, 2);
int vprintf(const char *, __va_list) __printflike(1, 0);
+int vasprintf(char **ret, struct malloc_type *mtp, const char *format,
+ __va_list ap) __printflike(3, 0);
int vsnprintf(char *, size_t, const char *, __va_list) __printflike(3, 0);
int vsnrprintf(char *, size_t, int, const char *, __va_list) __printflike(4, 0);
int vsprintf(char *buf, const char *, __va_list) __printflike(2, 0);
@@ -249,6 +279,7 @@ u_long strtoul(const char *, char **, int) __nonnull(1);
quad_t strtoq(const char *, char **, int) __nonnull(1);
u_quad_t strtouq(const char *, char **, int) __nonnull(1);
void tprintf(struct proc *p, int pri, const char *, ...) __printflike(3, 4);
+void vtprintf(struct proc *, int, const char *, __va_list) __printflike(3, 0);
void hexdump(const void *ptr, int length, const char *hdr, int flags);
#define HD_COLUMN_MASK 0xff
#define HD_DELIM_MASK 0xff00
@@ -264,6 +295,7 @@ void bzero(void *buf, size_t len) __nonnull(1);
#define bcopy(src, dst, len) memmove((dst), (src), (len))
#define bzero(buf, size) memset((buf), 0, (size))
#endif /* __rtems__ */
+void explicit_bzero(void *, size_t) __nonnull(1);
void *memcpy(void *to, const void *from, size_t len) __nonnull(1) __nonnull(2);
void *memmove(void *dest, const void *src, size_t n) __nonnull(1) __nonnull(2);
@@ -331,7 +363,7 @@ copyout_nofault(const void * __restrict kaddr, void * __restrict udaddr,
#endif /* __rtems__ */
#ifndef __rtems__
-int fubyte(const void *base);
+int fubyte(volatile const void *base);
#else /* __rtems__ */
static inline int
fubyte(const void *base)
@@ -341,17 +373,24 @@ fubyte(const void *base)
return byte_base[0];
}
#endif /* __rtems__ */
-long fuword(const void *base);
-int fuword16(void *base);
-int32_t fuword32(const void *base);
-int64_t fuword64(const void *base);
-int subyte(void *base, int byte);
-int suword(void *base, long word);
-int suword16(void *base, int word);
-int suword32(void *base, int32_t word);
-int suword64(void *base, int64_t word);
+long fuword(volatile const void *base);
+int fuword16(volatile const void *base);
+int32_t fuword32(volatile const void *base);
+int64_t fuword64(volatile const void *base);
+int fueword(volatile const void *base, long *val);
+int fueword32(volatile const void *base, int32_t *val);
+int fueword64(volatile const void *base, int64_t *val);
+int subyte(volatile void *base, int byte);
+int suword(volatile void *base, long word);
+int suword16(volatile void *base, int word);
+int suword32(volatile void *base, int32_t word);
+int suword64(volatile void *base, int64_t word);
uint32_t casuword32(volatile uint32_t *base, uint32_t oldval, uint32_t newval);
-u_long casuword(volatile u_long *p, u_long oldval, u_long newval);
+u_long casuword(volatile u_long *p, u_long oldval, u_long newval);
+int casueword32(volatile uint32_t *base, uint32_t oldval, uint32_t *oldvalp,
+ uint32_t newval);
+int casueword(volatile u_long *p, u_long oldval, u_long *oldvalp,
+ u_long newval);
void realitexpire(void *);
@@ -361,7 +400,9 @@ void hardclock(int usermode, uintfptr_t pc);
void hardclock_cnt(int cnt, int usermode);
void hardclock_cpu(int usermode);
void hardclock_sync(int cpu);
+#ifndef __rtems__
void softclock(void *);
+#endif /* __rtems__ */
void statclock(int usermode);
void statclock_cnt(int cnt, int usermode);
void profclock(int usermode, uintfptr_t pc);
@@ -373,34 +414,26 @@ void startprofclock(struct proc *);
void stopprofclock(struct proc *);
void cpu_startprofclock(void);
void cpu_stopprofclock(void);
-void cpu_idleclock(void);
+sbintime_t cpu_idleclock(void);
void cpu_activeclock(void);
+void cpu_new_callout(int cpu, sbintime_t bt, sbintime_t bt_opt);
+void cpu_et_frequency(struct eventtimer *et, uint64_t newfreq);
extern int cpu_deepest_sleep;
extern int cpu_disable_c2_sleep;
extern int cpu_disable_c3_sleep;
-#ifndef __rtems__
-int cr_cansee(struct ucred *u1, struct ucred *u2);
-int cr_canseesocket(struct ucred *cred, struct socket *so);
-int cr_canseeinpcb(struct ucred *cred, struct inpcb *inp);
-#else /* __rtems__ */
-#define cr_cansee(u1, u2) 0
-#define cr_canseesocket(cred, so) 0
-#define cr_canseeinpcb(cred, inp) 0
-#endif /* __rtems__ */
-
-char *getenv(const char *name);
+char *kern_getenv(const char *name);
void freeenv(char *env);
int getenv_int(const char *name, int *data);
int getenv_uint(const char *name, unsigned int *data);
int getenv_long(const char *name, long *data);
int getenv_ulong(const char *name, unsigned long *data);
int getenv_string(const char *name, char *data, int size);
+int getenv_int64(const char *name, int64_t *data);
+int getenv_uint64(const char *name, uint64_t *data);
int getenv_quad(const char *name, quad_t *data);
-#ifndef __rtems__
-int setenv(const char *name, const char *value);
-#endif /* __rtems__ */
-int unsetenv(const char *name);
+int kern_setenv(const char *name, const char *value);
+int kern_unsetenv(const char *name);
int testenv(const char *name);
typedef uint64_t (cpu_tick_f)(void);
@@ -435,28 +468,18 @@ typedef void timeout_t(void *); /* timeout function type */
void callout_handle_init(struct callout_handle *);
struct callout_handle timeout(timeout_t *, void *, int);
void untimeout(timeout_t *, void *, struct callout_handle);
-caddr_t kern_timeout_callwheel_alloc(caddr_t v);
-void kern_timeout_callwheel_init(void);
/* Stubs for obsolete functions that used to be for interrupt management */
#ifdef __rtems__
typedef int intrmask_t;
#endif /* __rtems__ */
-static __inline void spl0(void) { return; }
static __inline intrmask_t splbio(void) { return 0; }
static __inline intrmask_t splcam(void) { return 0; }
static __inline intrmask_t splclock(void) { return 0; }
static __inline intrmask_t splhigh(void) { return 0; }
static __inline intrmask_t splimp(void) { return 0; }
static __inline intrmask_t splnet(void) { return 0; }
-static __inline intrmask_t splsoftcam(void) { return 0; }
-static __inline intrmask_t splsoftclock(void) { return 0; }
-static __inline intrmask_t splsofttty(void) { return 0; }
-static __inline intrmask_t splsoftvm(void) { return 0; }
-static __inline intrmask_t splsofttq(void) { return 0; }
-static __inline intrmask_t splstatclock(void) { return 0; }
static __inline intrmask_t spltty(void) { return 0; }
-static __inline intrmask_t splvm(void) { return 0; }
static __inline void splx(intrmask_t ipl __unused) { return; }
/*
@@ -464,23 +487,35 @@ static __inline void splx(intrmask_t ipl __unused) { return; }
* less often.
*/
int _sleep(void *chan, struct lock_object *lock, int pri, const char *wmesg,
- int timo) __nonnull(1);
+ sbintime_t sbt, sbintime_t pr, int flags) __nonnull(1);
#define msleep(chan, mtx, pri, wmesg, timo) \
- _sleep((chan), &(mtx)->lock_object, (pri), (wmesg), (timo))
+ _sleep((chan), &(mtx)->lock_object, (pri), (wmesg), \
+ tick_sbt * (timo), 0, C_HARDCLOCK)
+#define msleep_sbt(chan, mtx, pri, wmesg, bt, pr, flags) \
+ _sleep((chan), &(mtx)->lock_object, (pri), (wmesg), (bt), (pr), \
+ (flags))
#ifndef __rtems__
-int msleep_spin(void *chan, struct mtx *mtx, const char *wmesg, int timo)
- __nonnull(1);
+int msleep_spin_sbt(void *chan, struct mtx *mtx, const char *wmesg,
+ sbintime_t sbt, sbintime_t pr, int flags) __nonnull(1);
#else /* __rtems__ */
-#define msleep_spin(chan, mtx, wmesg, timo) \
- msleep((chan), (mtx), 0, (wmesg), (timo))
+#define msleep_spin_sbt(chan, mtx, wmesg, sbt, pr, flags) \
+ msleep_sbt(chan, mtx, 0, wmesg, sbt, pr, flags)
#endif /* __rtems__ */
+#define msleep_spin(chan, mtx, wmesg, timo) \
+ msleep_spin_sbt((chan), (mtx), (wmesg), tick_sbt * (timo), \
+ 0, C_HARDCLOCK)
+int pause_sbt(const char *wmesg, sbintime_t sbt, sbintime_t pr,
+ int flags);
#ifdef __rtems__
#include <unistd.h>
-#define pause _bsd_pause
#endif /* __rtems__ */
-int pause(const char *wmesg, int timo);
+#define pause(wmesg, timo) \
+ pause_sbt((wmesg), tick_sbt * (timo), 0, C_HARDCLOCK)
#define tsleep(chan, pri, wmesg, timo) \
- _sleep((chan), NULL, (pri), (wmesg), (timo))
+ _sleep((chan), NULL, (pri), (wmesg), tick_sbt * (timo), \
+ 0, C_HARDCLOCK)
+#define tsleep_sbt(chan, pri, wmesg, bt, pr, flags) \
+ _sleep((chan), NULL, (pri), (wmesg), (bt), (pr), (flags))
void wakeup(void *chan) __nonnull(1);
void wakeup_one(void *chan) __nonnull(1);
@@ -492,6 +527,11 @@ struct cdev;
dev_t dev2udev(struct cdev *x);
const char *devtoname(struct cdev *cdev);
+#ifdef __LP64__
+size_t devfs_iosize_max(void);
+size_t iosize_max(void);
+#endif
+
int poll_no_poll(int events);
/* XXX: Should be void nanodelay(u_int nsec); */
@@ -502,7 +542,6 @@ struct root_hold_token;
struct root_hold_token *root_mount_hold(const char *identifier);
void root_mount_rel(struct root_hold_token *h);
-void root_mount_wait(void);
int root_mounted(void);
@@ -511,6 +550,7 @@ int root_mounted(void);
*/
struct unrhdr;
struct unrhdr *new_unrhdr(int low, int high, struct mtx *mutex);
+void init_unrhdr(struct unrhdr *uh, int low, int high, struct mtx *mutex);
void delete_unrhdr(struct unrhdr *uh);
void clean_unrhdr(struct unrhdr *uh);
void clean_unrhdrl(struct unrhdr *uh);
@@ -519,31 +559,10 @@ int alloc_unr_specific(struct unrhdr *uh, u_int item);
int alloc_unrl(struct unrhdr *uh);
void free_unr(struct unrhdr *uh, u_int item);
-/*
- * Population count algorithm using SWAR approach
- * - "SIMD Within A Register".
- */
-static __inline uint32_t
-bitcount32(uint32_t x)
-{
-
- x = (x & 0x55555555) + ((x & 0xaaaaaaaa) >> 1);
- x = (x & 0x33333333) + ((x & 0xcccccccc) >> 2);
- x = (x + (x >> 4)) & 0x0f0f0f0f;
- x = (x + (x >> 8));
- x = (x + (x >> 16)) & 0x000000ff;
- return (x);
-}
+void intr_prof_stack_use(struct thread *td, struct trapframe *frame);
-static __inline uint16_t
-bitcount16(uint32_t x)
-{
+extern void (*softdep_ast_cleanup)(void);
- x = (x & 0x5555) + ((x & 0xaaaa) >> 1);
- x = (x & 0x3333) + ((x & 0xcccc) >> 2);
- x = (x + (x >> 4)) & 0x0f0f;
- x = (x + (x >> 8)) & 0x00ff;
- return (x);
-}
+void counted_warning(unsigned *counter, const char *msg);
#endif /* !_SYS_SYSTM_H_ */
diff --git a/freebsd/sys/sys/taskqueue.h b/freebsd/sys/sys/taskqueue.h
index 68000026..a6c66558 100644
--- a/freebsd/sys/sys/taskqueue.h
+++ b/freebsd/sys/sys/taskqueue.h
@@ -36,8 +36,10 @@
#include <sys/queue.h>
#include <sys/_task.h>
#include <sys/_callout.h>
+#include <sys/_cpuset.h>
struct taskqueue;
+struct taskqgroup;
struct thread;
struct timeout_task {
@@ -47,6 +49,17 @@ struct timeout_task {
int f;
};
+enum taskqueue_callback_type {
+ TASKQUEUE_CALLBACK_TYPE_INIT,
+ TASKQUEUE_CALLBACK_TYPE_SHUTDOWN,
+};
+#define TASKQUEUE_CALLBACK_TYPE_MIN TASKQUEUE_CALLBACK_TYPE_INIT
+#define TASKQUEUE_CALLBACK_TYPE_MAX TASKQUEUE_CALLBACK_TYPE_SHUTDOWN
+#define TASKQUEUE_NUM_CALLBACKS TASKQUEUE_CALLBACK_TYPE_MAX + 1
+#define TASKQUEUE_NAMELEN 32
+
+typedef void (*taskqueue_callback_fn)(void *context);
+
/*
* A notification callback function which is called from
* taskqueue_enqueue(). The context argument is given in the call to
@@ -61,6 +74,8 @@ struct taskqueue *taskqueue_create(const char *name, int mflags,
void *context);
int taskqueue_start_threads(struct taskqueue **tqp, int count, int pri,
const char *name, ...) __printflike(4, 5);
+int taskqueue_start_threads_cpuset(struct taskqueue **tqp, int count,
+ int pri, cpuset_t *mask, const char *name, ...) __printflike(5, 6);
int taskqueue_enqueue(struct taskqueue *queue, struct task *task);
int taskqueue_enqueue_timeout(struct taskqueue *queue,
struct timeout_task *timeout_task, int ticks);
@@ -77,6 +92,9 @@ void taskqueue_run(struct taskqueue *queue);
void taskqueue_block(struct taskqueue *queue);
void taskqueue_unblock(struct taskqueue *queue);
int taskqueue_member(struct taskqueue *queue, struct thread *td);
+void taskqueue_set_callback(struct taskqueue *queue,
+ enum taskqueue_callback_type cb_type,
+ taskqueue_callback_fn callback, void *context);
#define TASK_INITIALIZER(priority, func, context) \
{ .ta_pending = 0, \
@@ -127,7 +145,7 @@ taskqueue_define_##name(void *arg) \
init; \
} \
\
-SYSINIT(taskqueue_##name, SI_SUB_CONFIGURE, SI_ORDER_SECOND, \
+SYSINIT(taskqueue_##name, SI_SUB_INIT_IF, SI_ORDER_SECOND, \
taskqueue_define_##name, NULL); \
\
struct __hack
@@ -152,7 +170,7 @@ taskqueue_define_##name(void *arg) \
init; \
} \
\
-SYSINIT(taskqueue_##name, SI_SUB_CONFIGURE, SI_ORDER_SECOND, \
+SYSINIT(taskqueue_##name, SI_SUB_INIT_IF, SI_ORDER_SECOND, \
taskqueue_define_##name, NULL); \
\
struct __hack
@@ -182,7 +200,6 @@ TASKQUEUE_DECLARE(thread);
* from a fast interrupt handler context.
*/
TASKQUEUE_DECLARE(fast);
-int taskqueue_enqueue_fast(struct taskqueue *queue, struct task *task);
struct taskqueue *taskqueue_create_fast(const char *name, int mflags,
taskqueue_enqueue_fn enqueue,
void *context);
diff --git a/freebsd/sys/sys/tree.h b/freebsd/sys/sys/tree.h
index 1cce7278..c9df686f 100644
--- a/freebsd/sys/sys/tree.h
+++ b/freebsd/sys/sys/tree.h
@@ -383,16 +383,33 @@ struct { \
#define RB_PROTOTYPE_STATIC(name, type, field, cmp) \
RB_PROTOTYPE_INTERNAL(name, type, field, cmp, __unused static)
#define RB_PROTOTYPE_INTERNAL(name, type, field, cmp, attr) \
-attr void name##_RB_INSERT_COLOR(struct name *, struct type *); \
-attr void name##_RB_REMOVE_COLOR(struct name *, struct type *, struct type *);\
-attr struct type *name##_RB_REMOVE(struct name *, struct type *); \
-attr struct type *name##_RB_INSERT(struct name *, struct type *); \
-attr struct type *name##_RB_FIND(struct name *, struct type *); \
-attr struct type *name##_RB_NFIND(struct name *, struct type *); \
-attr struct type *name##_RB_NEXT(struct type *); \
-attr struct type *name##_RB_PREV(struct type *); \
-attr struct type *name##_RB_MINMAX(struct name *, int); \
- \
+ RB_PROTOTYPE_INSERT_COLOR(name, type, attr); \
+ RB_PROTOTYPE_REMOVE_COLOR(name, type, attr); \
+ RB_PROTOTYPE_INSERT(name, type, attr); \
+ RB_PROTOTYPE_REMOVE(name, type, attr); \
+ RB_PROTOTYPE_FIND(name, type, attr); \
+ RB_PROTOTYPE_NFIND(name, type, attr); \
+ RB_PROTOTYPE_NEXT(name, type, attr); \
+ RB_PROTOTYPE_PREV(name, type, attr); \
+ RB_PROTOTYPE_MINMAX(name, type, attr);
+#define RB_PROTOTYPE_INSERT_COLOR(name, type, attr) \
+ attr void name##_RB_INSERT_COLOR(struct name *, struct type *)
+#define RB_PROTOTYPE_REMOVE_COLOR(name, type, attr) \
+ attr void name##_RB_REMOVE_COLOR(struct name *, struct type *, struct type *)
+#define RB_PROTOTYPE_REMOVE(name, type, attr) \
+ attr struct type *name##_RB_REMOVE(struct name *, struct type *)
+#define RB_PROTOTYPE_INSERT(name, type, attr) \
+ attr struct type *name##_RB_INSERT(struct name *, struct type *)
+#define RB_PROTOTYPE_FIND(name, type, attr) \
+ attr struct type *name##_RB_FIND(struct name *, struct type *)
+#define RB_PROTOTYPE_NFIND(name, type, attr) \
+ attr struct type *name##_RB_NFIND(struct name *, struct type *)
+#define RB_PROTOTYPE_NEXT(name, type, attr) \
+ attr struct type *name##_RB_NEXT(struct type *)
+#define RB_PROTOTYPE_PREV(name, type, attr) \
+ attr struct type *name##_RB_PREV(struct type *)
+#define RB_PROTOTYPE_MINMAX(name, type, attr) \
+ attr struct type *name##_RB_MINMAX(struct name *, int)
/* Main rb operation.
* Moves node close to the key of elm to top
@@ -402,6 +419,17 @@ attr struct type *name##_RB_MINMAX(struct name *, int); \
#define RB_GENERATE_STATIC(name, type, field, cmp) \
RB_GENERATE_INTERNAL(name, type, field, cmp, __unused static)
#define RB_GENERATE_INTERNAL(name, type, field, cmp, attr) \
+ RB_GENERATE_INSERT_COLOR(name, type, field, attr) \
+ RB_GENERATE_REMOVE_COLOR(name, type, field, attr) \
+ RB_GENERATE_INSERT(name, type, field, cmp, attr) \
+ RB_GENERATE_REMOVE(name, type, field, attr) \
+ RB_GENERATE_FIND(name, type, field, cmp, attr) \
+ RB_GENERATE_NFIND(name, type, field, cmp, attr) \
+ RB_GENERATE_NEXT(name, type, field, attr) \
+ RB_GENERATE_PREV(name, type, field, attr) \
+ RB_GENERATE_MINMAX(name, type, field, attr)
+
+#define RB_GENERATE_INSERT_COLOR(name, type, field, attr) \
attr void \
name##_RB_INSERT_COLOR(struct name *head, struct type *elm) \
{ \
@@ -444,8 +472,9 @@ name##_RB_INSERT_COLOR(struct name *head, struct type *elm) \
} \
} \
RB_COLOR(head->rbh_root, field) = RB_BLACK; \
-} \
- \
+}
+
+#define RB_GENERATE_REMOVE_COLOR(name, type, field, attr) \
attr void \
name##_RB_REMOVE_COLOR(struct name *head, struct type *parent, struct type *elm) \
{ \
@@ -522,8 +551,9 @@ name##_RB_REMOVE_COLOR(struct name *head, struct type *parent, struct type *elm)
} \
if (elm) \
RB_COLOR(elm, field) = RB_BLACK; \
-} \
- \
+}
+
+#define RB_GENERATE_REMOVE(name, type, field, attr) \
attr struct type * \
name##_RB_REMOVE(struct name *head, struct type *elm) \
{ \
@@ -590,7 +620,8 @@ color: \
name##_RB_REMOVE_COLOR(head, parent, child); \
return (old); \
} \
- \
+
+#define RB_GENERATE_INSERT(name, type, field, cmp, attr) \
/* Inserts a node into the RB tree */ \
attr struct type * \
name##_RB_INSERT(struct name *head, struct type *elm) \
@@ -620,8 +651,9 @@ name##_RB_INSERT(struct name *head, struct type *elm) \
RB_ROOT(head) = elm; \
name##_RB_INSERT_COLOR(head, elm); \
return (NULL); \
-} \
- \
+}
+
+#define RB_GENERATE_FIND(name, type, field, cmp, attr) \
/* Finds the node with the same key as elm */ \
attr struct type * \
name##_RB_FIND(struct name *head, struct type *elm) \
@@ -638,8 +670,9 @@ name##_RB_FIND(struct name *head, struct type *elm) \
return (tmp); \
} \
return (NULL); \
-} \
- \
+}
+
+#define RB_GENERATE_NFIND(name, type, field, cmp, attr) \
/* Finds the first node greater than or equal to the search key */ \
attr struct type * \
name##_RB_NFIND(struct name *head, struct type *elm) \
@@ -659,8 +692,9 @@ name##_RB_NFIND(struct name *head, struct type *elm) \
return (tmp); \
} \
return (res); \
-} \
- \
+}
+
+#define RB_GENERATE_NEXT(name, type, field, attr) \
/* ARGSUSED */ \
attr struct type * \
name##_RB_NEXT(struct type *elm) \
@@ -681,8 +715,9 @@ name##_RB_NEXT(struct type *elm) \
} \
} \
return (elm); \
-} \
- \
+}
+
+#define RB_GENERATE_PREV(name, type, field, attr) \
/* ARGSUSED */ \
attr struct type * \
name##_RB_PREV(struct type *elm) \
@@ -703,8 +738,9 @@ name##_RB_PREV(struct type *elm) \
} \
} \
return (elm); \
-} \
- \
+}
+
+#define RB_GENERATE_MINMAX(name, type, field, attr) \
attr struct type * \
name##_RB_MINMAX(struct name *head, int val) \
{ \
diff --git a/freebsd/sys/sys/tty.h b/freebsd/sys/sys/tty.h
index 00cf4e6c..4d082667 100644
--- a/freebsd/sys/sys/tty.h
+++ b/freebsd/sys/sys/tty.h
@@ -171,8 +171,11 @@ void tty_rel_gone(struct tty *tp);
#define tty_getlock(tp) ((tp)->t_mtx)
/* Device node creation. */
-void tty_makedev(struct tty *tp, struct ucred *cred, const char *fmt, ...)
- __printflike(3, 4);
+int tty_makedevf(struct tty *tp, struct ucred *cred, int flags,
+ const char *fmt, ...) __printflike(4, 5);
+#define TTYMK_CLONING 0x1
+#define tty_makedev(tp, cred, fmt, ...) \
+ (void )tty_makedevf((tp), (cred), 0, (fmt), ## __VA_ARGS__)
#define tty_makealias(tp,fmt,...) \
make_dev_alias((tp)->t_dev, fmt, ## __VA_ARGS__)
diff --git a/freebsd/sys/sys/ttydevsw.h b/freebsd/sys/sys/ttydevsw.h
index 748ae0be..98bebca7 100644
--- a/freebsd/sys/sys/ttydevsw.h
+++ b/freebsd/sys/sys/ttydevsw.h
@@ -54,6 +54,7 @@ typedef int tsw_mmap_t(struct tty *tp, vm_ooffset_t offset,
vm_paddr_t * paddr, int nprot, vm_memattr_t *memattr);
typedef void tsw_pktnotify_t(struct tty *tp, char event);
typedef void tsw_free_t(void *softc);
+typedef bool tsw_busy_t(struct tty *tp);
struct ttydevsw {
unsigned int tsw_flags; /* Default TTY flags. */
@@ -74,21 +75,25 @@ struct ttydevsw {
tsw_free_t *tsw_free; /* Destructor. */
- void *tsw_spare[4]; /* For future use. */
+ tsw_busy_t *tsw_busy; /* Draining output. */
+
+ void *tsw_spare[3]; /* For future use. */
};
static __inline int
ttydevsw_open(struct tty *tp)
{
+
tty_lock_assert(tp, MA_OWNED);
MPASS(!tty_gone(tp));
- return tp->t_devsw->tsw_open(tp);
+ return (tp->t_devsw->tsw_open(tp));
}
static __inline void
ttydevsw_close(struct tty *tp)
{
+
tty_lock_assert(tp, MA_OWNED);
MPASS(!tty_gone(tp));
@@ -98,6 +103,7 @@ ttydevsw_close(struct tty *tp)
static __inline void
ttydevsw_outwakeup(struct tty *tp)
{
+
tty_lock_assert(tp, MA_OWNED);
MPASS(!tty_gone(tp));
@@ -111,6 +117,7 @@ ttydevsw_outwakeup(struct tty *tp)
static __inline void
ttydevsw_inwakeup(struct tty *tp)
{
+
tty_lock_assert(tp, MA_OWNED);
MPASS(!tty_gone(tp));
@@ -124,49 +131,56 @@ ttydevsw_inwakeup(struct tty *tp)
static __inline int
ttydevsw_ioctl(struct tty *tp, u_long cmd, caddr_t data, struct thread *td)
{
+
tty_lock_assert(tp, MA_OWNED);
MPASS(!tty_gone(tp));
- return tp->t_devsw->tsw_ioctl(tp, cmd, data, td);
+ return (tp->t_devsw->tsw_ioctl(tp, cmd, data, td));
}
static __inline int
-ttydevsw_cioctl(struct tty *tp, int unit, u_long cmd, caddr_t data, struct thread *td)
+ttydevsw_cioctl(struct tty *tp, int unit, u_long cmd, caddr_t data,
+ struct thread *td)
{
+
tty_lock_assert(tp, MA_OWNED);
MPASS(!tty_gone(tp));
- return tp->t_devsw->tsw_cioctl(tp, unit, cmd, data, td);
+ return (tp->t_devsw->tsw_cioctl(tp, unit, cmd, data, td));
}
static __inline int
ttydevsw_param(struct tty *tp, struct termios *t)
{
+
MPASS(!tty_gone(tp));
- return tp->t_devsw->tsw_param(tp, t);
+ return (tp->t_devsw->tsw_param(tp, t));
}
static __inline int
ttydevsw_modem(struct tty *tp, int sigon, int sigoff)
{
+
MPASS(!tty_gone(tp));
- return tp->t_devsw->tsw_modem(tp, sigon, sigoff);
+ return (tp->t_devsw->tsw_modem(tp, sigon, sigoff));
}
static __inline int
ttydevsw_mmap(struct tty *tp, vm_ooffset_t offset, vm_paddr_t *paddr,
int nprot, vm_memattr_t *memattr)
{
+
MPASS(!tty_gone(tp));
- return tp->t_devsw->tsw_mmap(tp, offset, paddr, nprot, memattr);
+ return (tp->t_devsw->tsw_mmap(tp, offset, paddr, nprot, memattr));
}
static __inline void
ttydevsw_pktnotify(struct tty *tp, char event)
{
+
tty_lock_assert(tp, MA_OWNED);
MPASS(!tty_gone(tp));
@@ -176,9 +190,20 @@ ttydevsw_pktnotify(struct tty *tp, char event)
static __inline void
ttydevsw_free(struct tty *tp)
{
+
MPASS(tty_gone(tp));
tp->t_devsw->tsw_free(tty_softc(tp));
}
+static __inline bool
+ttydevsw_busy(struct tty *tp)
+{
+
+ tty_lock_assert(tp, MA_OWNED);
+ MPASS(!tty_gone(tp));
+
+ return (tp->t_devsw->tsw_busy(tp));
+}
+
#endif /* !_SYS_TTYDEVSW_H_ */
diff --git a/freebsd/sys/sys/ucred.h b/freebsd/sys/sys/ucred.h
index 82e4d9a4..ae3fcdeb 100644
--- a/freebsd/sys/sys/ucred.h
+++ b/freebsd/sys/sys/ucred.h
@@ -37,6 +37,8 @@
struct loginclass;
+#define XU_NGROUPS 16
+
/*
* Credentials.
*
@@ -65,6 +67,7 @@ struct ucred {
struct auditinfo_addr cr_audit; /* Audit properties. */
gid_t *cr_groups; /* groups */
int cr_agroups; /* Available groups */
+ gid_t cr_smallgroups[XU_NGROUPS]; /* storage for small groups */
};
#else /* __rtems__ */
struct ucred;
@@ -73,8 +76,6 @@ struct ucred;
#define FSCRED ((struct ucred *)-1) /* filesystem credential */
#endif /* _KERNEL || _WANT_UCRED */
-#define XU_NGROUPS 16
-
/*
* Flags for cr_flags.
*/
@@ -111,11 +112,12 @@ void change_svuid(struct ucred *newcred, uid_t svuid);
void crcopy(struct ucred *dest, struct ucred *src);
struct ucred *crcopysafe(struct proc *p, struct ucred *cr);
struct ucred *crdup(struct ucred *cr);
-void cred_update_thread(struct thread *td);
+void crextend(struct ucred *cr, int n);
+void proc_set_cred_init(struct proc *p, struct ucred *cr);
+struct ucred *proc_set_cred(struct proc *p, struct ucred *cr);
void crfree(struct ucred *cr);
struct ucred *crget(void);
struct ucred *crhold(struct ucred *cr);
-int crshared(struct ucred *cr);
void cru2x(struct ucred *cr, struct xucred *xcr);
void crsetgroups(struct ucred *cr, int n, gid_t *groups);
int groupmember(gid_t gid, struct ucred *cred);
diff --git a/freebsd/sys/sys/unpcb.h b/freebsd/sys/sys/unpcb.h
index 38a2d1fe..cdb5c4d0 100644
--- a/freebsd/sys/sys/unpcb.h
+++ b/freebsd/sys/sys/unpcb.h
@@ -78,8 +78,8 @@ struct unpcb {
struct unp_head unp_refs; /* referencing socket linked list */
LIST_ENTRY(unpcb) unp_reflink; /* link in unp_refs list */
struct sockaddr_un *unp_addr; /* bound address of socket */
- int unp_cc; /* copy of rcv.sb_cc */
- int unp_mbcnt; /* copy of rcv.sb_mbcnt */
+ int reserved1;
+ int reserved2;
unp_gen_t unp_gencnt; /* generation count of this instance */
short unp_flags; /* flags */
short unp_gcflag; /* Garbage collector flags. */
@@ -107,10 +107,6 @@ struct unpcb {
#define UNP_WANTCRED 0x004 /* credentials wanted */
#define UNP_CONNWAIT 0x008 /* connect blocks until accepted */
-#define UNPGC_REF 0x1 /* unpcb has external ref. */
-#define UNPGC_DEAD 0x2 /* unpcb might be dead. */
-#define UNPGC_SCANNED 0x4 /* Has been scanned. */
-
/*
* These flags are used to handle non-atomicity in connect() and bind()
* operations on a socket: in particular, to avoid races between multiple
@@ -118,6 +114,15 @@ struct unpcb {
*/
#define UNP_CONNECTING 0x010 /* Currently connecting. */
#define UNP_BINDING 0x020 /* Currently binding. */
+#define UNP_NASCENT 0x040 /* Newborn child socket. */
+
+/*
+ * Flags in unp_gcflag.
+ */
+#define UNPGC_REF 0x1 /* unpcb has external ref. */
+#define UNPGC_DEAD 0x2 /* unpcb might be dead. */
+#define UNPGC_SCANNED 0x4 /* Has been scanned. */
+#define UNPGC_IGNORE_RIGHTS 0x8 /* Attached rights are freed */
#define sotounpcb(so) ((struct unpcb *)((so)->so_pcb))
diff --git a/freebsd/sys/sys/user.h b/freebsd/sys/sys/user.h
index 698cad9e..d0da0455 100644
--- a/freebsd/sys/sys/user.h
+++ b/freebsd/sys/sys/user.h
@@ -61,6 +61,7 @@
#ifndef _SYS_SOCKET_VAR_H_
#include <sys/socket.h>
#endif
+#include <sys/caprights.h>
/*
* KERN_PROC subtype ops return arrays of selected proc structure entries:
@@ -83,7 +84,7 @@
* it in two places: function fill_kinfo_proc in sys/kern/kern_proc.c and
* function kvm_proclist in lib/libkvm/kvm_proc.c .
*/
-#define KI_NSPARE_INT 7
+#define KI_NSPARE_INT 4
#define KI_NSPARE_LONG 12
#define KI_NSPARE_PTR 6
@@ -98,7 +99,7 @@
#define TDNAMLEN 16 /* size of returned thread name */
#define COMMLEN 19 /* size of returned ki_comm name */
#define KI_EMULNAMELEN 16 /* size of returned ki_emul */
-#define KI_NGROUPS 16 /* number of groups in ki_groups */
+#define KI_NGROUPS 16 /* number of groups in ki_groups */
#define LOGNAMELEN 17 /* size of returned ki_login */
#define LOGINCLASSLEN 17 /* size of returned ki_loginclass */
@@ -146,7 +147,7 @@ struct kinfo_proc {
gid_t ki_svgid; /* Saved effective group id */
short ki_ngroups; /* number of groups */
short ki_spare_short2; /* unused (just here for alignment) */
- gid_t ki_groups[KI_NGROUPS]; /* groups */
+ gid_t ki_groups[KI_NGROUPS]; /* groups */
vm_size_t ki_size; /* virtual size */
segsz_t ki_rssize; /* current resident set size in pages */
segsz_t ki_swrss; /* resident set size before last swap */
@@ -170,8 +171,8 @@ struct kinfo_proc {
signed char ki_nice; /* Process "nice" value */
char ki_lock; /* Process lock (prevent swap) count */
char ki_rqindex; /* Run queue index */
- u_char ki_oncpu; /* Which cpu we are on */
- u_char ki_lastcpu; /* Last cpu we were on */
+ u_char ki_oncpu_old; /* Which cpu we are on (legacy) */
+ u_char ki_lastcpu_old; /* Last cpu we were on (legacy) */
char ki_tdname[TDNAMLEN+1]; /* thread name */
char ki_wmesg[WMESGLEN+1]; /* wchan message */
char ki_login[LOGNAMELEN+1]; /* setlogin name */
@@ -186,6 +187,9 @@ struct kinfo_proc {
*/
char ki_sparestrings[50]; /* spare string space */
int ki_spareints[KI_NSPARE_INT]; /* spare room for growth */
+ int ki_oncpu; /* Which cpu we are on */
+ int ki_lastcpu; /* Last cpu we were on */
+ int ki_tracer; /* Pid of tracing process */
int ki_flag2; /* P2_* flags */
int ki_fibnum; /* Default FIB number */
u_int ki_cr_flags; /* Credential flags */
@@ -255,8 +259,7 @@ struct user {
#define KF_TYPE_SHM 8
#define KF_TYPE_SEM 9
#define KF_TYPE_PTS 10
-/* no KF_TYPE_CAPABILITY (11), since capabilities wrap other file objects */
-#define KF_TYPE_PROCDESC 12
+#define KF_TYPE_PROCDESC 11
#define KF_TYPE_UNKNOWN 255
#define KF_VTYPE_VNON 0
@@ -273,7 +276,7 @@ struct user {
#define KF_FD_TYPE_CWD -1 /* Current working directory */
#define KF_FD_TYPE_ROOT -2 /* Root directory */
#define KF_FD_TYPE_JAIL -3 /* Jail directory */
-#define KF_FD_TYPE_TRACE -4 /* ptrace vnode */
+#define KF_FD_TYPE_TRACE -4 /* Ktrace vnode */
#define KF_FD_TYPE_TEXT -5 /* Text vnode */
#define KF_FD_TYPE_CTTY -6 /* Controlling terminal */
@@ -292,11 +295,10 @@ struct user {
#define KF_FLAG_TRUNC 0x00001000
#define KF_FLAG_EXCL 0x00002000
#define KF_FLAG_EXEC 0x00004000
-#define KF_FLAG_CAPABILITY 0x00008000
/*
* Old format. Has variable hidden padding due to alignment.
- * This is a compatability hack for pre-build 7.1 packages.
+ * This is a compatibility hack for pre-build 7.1 packages.
*/
#if defined(__amd64__)
#define KINFO_OFILE_SIZE 1328
@@ -323,6 +325,12 @@ struct kinfo_ofile {
};
#if defined(__amd64__) || defined(__i386__)
+/*
+ * This size should never be changed. If you really need to, you must provide
+ * backward ABI compatibility by allocating a new sysctl MIB that will return
+ * the new structure. The current structure has to be returned by the current
+ * sysctl MIB. See how it is done for the kinfo_ofile structure.
+ */
#define KINFO_FILE_SIZE 1392
#endif
@@ -395,7 +403,7 @@ struct kinfo_file {
uint16_t kf_pad1; /* Round to 32 bit alignment. */
int _kf_ispare0; /* Space for more stuff. */
cap_rights_t kf_cap_rights; /* Capability rights. */
- int _kf_ispare[4]; /* Space for more stuff. */
+ uint64_t _kf_cap_spare; /* Space for future cap_rights_t. */
/* Truncated before copyout in sysctl */
char kf_path[PATH_MAX]; /* Path to file, if any. */
#else /* __rtems__ */
@@ -484,6 +492,27 @@ struct kinfo_vmentry {
};
/*
+ * The "vm.objects" sysctl provides a list of all VM objects in the system
+ * via an array of these entries.
+ */
+struct kinfo_vmobject {
+ int kvo_structsize; /* Variable size of record. */
+ int kvo_type; /* Object type: KVME_TYPE_*. */
+ uint64_t kvo_size; /* Object size in pages. */
+ uint64_t kvo_vn_fileid; /* inode number if vnode. */
+ uint32_t kvo_vn_fsid; /* dev_t of vnode location. */
+ int kvo_ref_count; /* Reference count. */
+ int kvo_shadow_count; /* Shadow count. */
+ int kvo_memattr; /* Memory attribute. */
+ uint64_t kvo_resident; /* Number of resident pages. */
+ uint64_t kvo_active; /* Number of active pages. */
+ uint64_t kvo_inactive; /* Number of inactive pages. */
+ uint64_t _kvo_qspare[8];
+ uint32_t _kvo_ispare[8];
+ char kvo_path[PATH_MAX]; /* Pathname, if any. */
+};
+
+/*
* The KERN_PROC_KSTACK sysctl allows a process to dump the kernel stacks of
* another process as a series of entries. Each stack is represented by a
* series of symbol names and offsets as generated by stack_sbuf_print(9).
@@ -516,6 +545,11 @@ struct kinfo_sigtramp {
#define KERN_PROC_NOTHREADS 0x1
#define KERN_PROC_MASK32 0x2
+/* Flags for kern_proc_filedesc_out. */
+#define KERN_FILEDESC_PACK_KINFO 0x00000001U
+
+/* Flags for kern_proc_vmmap_out. */
+#define KERN_VMMAP_PACK_KINFO 0x00000001U
struct sbuf;
/*
@@ -527,9 +561,12 @@ struct sbuf;
* to be locked on enter. On return the process is unlocked.
*/
-int kern_proc_filedesc_out(struct proc *p, struct sbuf *sb, ssize_t maxlen);
+int kern_proc_filedesc_out(struct proc *p, struct sbuf *sb, ssize_t maxlen,
+ int flags);
+int kern_proc_cwd_out(struct proc *p, struct sbuf *sb, ssize_t maxlen);
int kern_proc_out(struct proc *p, struct sbuf *sb, int flags);
-int kern_proc_vmmap_out(struct proc *p, struct sbuf *sb);
+int kern_proc_vmmap_out(struct proc *p, struct sbuf *sb, ssize_t maxlen,
+ int flags);
int vntype_to_kinfo(int vtype);
#endif /* !_KERNEL */
diff --git a/freebsd/sys/sys/uuid.h b/freebsd/sys/sys/uuid.h
new file mode 100644
index 00000000..0748f611
--- /dev/null
+++ b/freebsd/sys/sys/uuid.h
@@ -0,0 +1,85 @@
+/*-
+ * Copyright (c) 2002 Marcel Moolenaar
+ * All rights reserved.
+ *
+ * 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 ``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 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_UUID_H_
+#define _SYS_UUID_H_
+
+#include <sys/cdefs.h>
+
+/* Length of a node address (an IEEE 802 address). */
+#define _UUID_NODE_LEN 6
+
+/*
+ * See also:
+ * http://www.opengroup.org/dce/info/draft-leach-uuids-guids-01.txt
+ * http://www.opengroup.org/onlinepubs/009629399/apdxa.htm
+ *
+ * A DCE 1.1 compatible source representation of UUIDs.
+ */
+struct uuid {
+ uint32_t time_low;
+ uint16_t time_mid;
+ uint16_t time_hi_and_version;
+ uint8_t clock_seq_hi_and_reserved;
+ uint8_t clock_seq_low;
+ uint8_t node[_UUID_NODE_LEN];
+};
+
+#ifdef _KERNEL
+
+#define UUID_NODE_LEN _UUID_NODE_LEN
+
+struct sbuf;
+
+struct uuid *kern_uuidgen(struct uuid *, size_t);
+
+int uuid_ether_add(const uint8_t *);
+int uuid_ether_del(const uint8_t *);
+
+int snprintf_uuid(char *, size_t, struct uuid *);
+int printf_uuid(struct uuid *);
+int sbuf_printf_uuid(struct sbuf *, struct uuid *);
+int parse_uuid(const char *, struct uuid *);
+
+void be_uuid_dec(void const *buf, struct uuid *uuid);
+void be_uuid_enc(void *buf, struct uuid const *uuid);
+void le_uuid_dec(void const *buf, struct uuid *uuid);
+void le_uuid_enc(void *buf, struct uuid const *uuid);
+
+#else /* _KERNEL */
+
+/* XXX namespace pollution? */
+typedef struct uuid uuid_t;
+
+__BEGIN_DECLS
+int uuidgen(struct uuid *, int);
+__END_DECLS
+
+#endif /* _KERNEL */
+
+#endif /* _SYS_UUID_H_ */
diff --git a/freebsd/sys/sys/vmmeter.h b/freebsd/sys/sys/vmmeter.h
index c66016c6..39f03d0d 100644
--- a/freebsd/sys/sys/vmmeter.h
+++ b/freebsd/sys/sys/vmmeter.h
@@ -46,7 +46,7 @@
* c - constant after initialization
* f - locked by vm_page_queue_free_mtx
* p - locked by being in the PCPU and atomicity respect to interrupts
- * q - locked by vm_page_queue_mtx
+ * q - changes are synchronized by the corresponding vm_pagequeue lock
*/
struct vmmeter {
/*
@@ -61,6 +61,7 @@ struct vmmeter {
* Virtual memory activity.
*/
u_int v_vm_faults; /* (p) address memory faults */
+ u_int v_io_faults; /* (p) page faults requiring I/O */
u_int v_cow_faults; /* (p) copy-on-writes faults */
u_int v_cow_optim; /* (p) optimized copy-on-writes faults */
u_int v_zfod; /* (p) pages zero filled on demand */
@@ -75,8 +76,8 @@ struct vmmeter {
u_int v_vnodepgsout; /* (p) vnode pager pages paged out */
u_int v_intrans; /* (p) intransit blocking page faults */
u_int v_reactivated; /* (f) pages reactivated from free list */
- u_int v_pdwakeups; /* (f) times daemon has awaken from sleep */
- u_int v_pdpages; /* (q) pages analyzed by daemon */
+ u_int v_pdwakeups; /* (p) times daemon has awaken from sleep */
+ u_int v_pdpages; /* (p) pages analyzed by daemon */
u_int v_tcached; /* (p) total pages cached */
u_int v_dfree; /* (p) pages freed by daemon */
@@ -96,8 +97,6 @@ struct vmmeter {
u_int v_inactive_target; /* (c) pages desired inactive */
u_int v_inactive_count; /* (q) pages inactive */
u_int v_cache_count; /* (f) pages on cache queue */
- u_int v_cache_min; /* (c) min pages desired on cache queue */
- u_int v_cache_max; /* (c) max pages in cached obj */
u_int v_pageout_free_min; /* (c) min pages reserved for kernel */
u_int v_interrupt_free_min; /* (c) reserved pages for int code */
u_int v_free_severe; /* (c) severe page depletion point */
@@ -112,10 +111,13 @@ struct vmmeter {
u_int v_vforkpages; /* (p) VM pages affected by vfork() */
u_int v_rforkpages; /* (p) VM pages affected by rfork() */
u_int v_kthreadpages; /* (p) VM pages affected by fork() by kernel */
+ u_int v_spare[2];
};
#ifdef _KERNEL
-extern struct vmmeter cnt;
+extern struct vmmeter vm_cnt;
+
+extern u_int vm_pageout_wakeup_thresh;
/*
* Return TRUE if we are under our severe low-free-pages threshold
@@ -123,12 +125,12 @@ extern struct vmmeter cnt;
* This routine is typically used at the user<->system interface to determine
* whether we need to block in order to avoid a low memory deadlock.
*/
-
-static __inline
-int
+static inline int
vm_page_count_severe(void)
{
- return (cnt.v_free_severe > (cnt.v_free_count + cnt.v_cache_count));
+
+ return (vm_cnt.v_free_severe > vm_cnt.v_free_count +
+ vm_cnt.v_cache_count);
}
/*
@@ -138,55 +140,48 @@ vm_page_count_severe(void)
* we can execute potentially very expensive code in terms of memory. It
* is also used by the pageout daemon to calculate when to sleep, when
* to wake waiters up, and when (after making a pass) to become more
- * desparate.
+ * desperate.
*/
-
-static __inline
-int
+static inline int
vm_page_count_min(void)
{
- return (cnt.v_free_min > (cnt.v_free_count + cnt.v_cache_count));
+
+ return (vm_cnt.v_free_min > vm_cnt.v_free_count + vm_cnt.v_cache_count);
}
/*
* Return TRUE if we have not reached our free page target during
* free page recovery operations.
*/
-
-static __inline
-int
+static inline int
vm_page_count_target(void)
{
- return (cnt.v_free_target > (cnt.v_free_count + cnt.v_cache_count));
+
+ return (vm_cnt.v_free_target > vm_cnt.v_free_count +
+ vm_cnt.v_cache_count);
}
/*
* Return the number of pages we need to free-up or cache
* A positive number indicates that we do not have enough free pages.
*/
-
-static __inline
-int
+static inline int
vm_paging_target(void)
{
- return (
- (cnt.v_free_target + cnt.v_cache_min) -
- (cnt.v_free_count + cnt.v_cache_count)
- );
+
+ return (vm_cnt.v_free_target - (vm_cnt.v_free_count +
+ vm_cnt.v_cache_count));
}
/*
* Returns TRUE if the pagedaemon needs to be woken up.
*/
-
-static __inline
-int
+static inline int
vm_paging_needed(void)
{
- return (
- (cnt.v_free_reserved + cnt.v_cache_min) >
- (cnt.v_free_count + cnt.v_cache_count)
- );
+
+ return (vm_cnt.v_free_count + vm_cnt.v_cache_count <
+ vm_pageout_wakeup_thresh);
}
#endif
diff --git a/freebsd/sys/sys/vnode.h b/freebsd/sys/sys/vnode.h
index 5b709f81..a047bc67 100644
--- a/freebsd/sys/sys/vnode.h
+++ b/freebsd/sys/sys/vnode.h
@@ -78,6 +78,7 @@ struct vpollinfo {
* c - namecache mutex
* f - freelist mutex
* i - interlock
+ * I - updated with atomics, 0->1 and 1->0 transitions with interlock held
* m - mount point interlock
* p - pollinfo lock
* u - Only a reference to the vnode is needed to read.
@@ -100,7 +101,6 @@ struct vnode {
* Fields which define the identity of the vnode. These fields are
* owned by the filesystem (XXX: and vgone() ?)
*/
- enum vtype v_type; /* u vnode type */
const char *v_tag; /* u type of underlying data */
struct vop_vector *v_op; /* u vnode operations vector */
void *v_data; /* u private data for fs */
@@ -123,10 +123,10 @@ struct vnode {
} v_un;
/*
- * vfs_hash: (mount + inode) -> vnode hash.
+ * vfs_hash: (mount + inode) -> vnode hash. The hash value
+ * itself is grouped with other int fields, to avoid padding.
*/
LIST_ENTRY(vnode) v_hashlist;
- u_int v_hash;
/*
* VFS_namecache stuff
@@ -136,24 +136,11 @@ struct vnode {
struct namecache *v_cache_dd; /* c Cache entry for .. vnode */
/*
- * clustering stuff
- */
- daddr_t v_cstart; /* v start block of cluster */
- daddr_t v_lasta; /* v last allocation */
- daddr_t v_lastw; /* v last write */
- int v_clen; /* v length of cur. cluster */
-
- /*
* Locking
*/
struct lock v_lock; /* u (if fs don't have one) */
struct mtx v_interlock; /* lock for "i" things */
struct lock *v_vnlock; /* u pointer to vnode lock */
- int v_holdcnt; /* i prevents recycling. */
- int v_usecount; /* i ref count of users */
- u_long v_iflag; /* i vnode flags (see below) */
- u_long v_vflag; /* v vnode flags */
- int v_writecount; /* v ref count of writers */
/*
* The machinery of being a vnode
@@ -168,6 +155,22 @@ struct vnode {
struct label *v_label; /* MAC label for vnode */
struct lockf *v_lockf; /* Byte-level advisory lock list */
struct rangelock v_rl; /* Byte-range lock */
+
+ /*
+ * clustering stuff
+ */
+ daddr_t v_cstart; /* v start block of cluster */
+ daddr_t v_lasta; /* v last allocation */
+ daddr_t v_lastw; /* v last write */
+ int v_clen; /* v length of cur. cluster */
+
+ u_int v_holdcnt; /* I prevents recycling. */
+ u_int v_usecount; /* I ref count of users */
+ u_int v_iflag; /* i vnode flags (see below) */
+ u_int v_vflag; /* v vnode flags */
+ int v_writecount; /* v ref count of writers */
+ u_int v_hash;
+ enum vtype v_type; /* u vnode type */
};
#endif /* defined(_KERNEL) || defined(_KVM_VNODE) */
@@ -232,7 +235,6 @@ struct xvnode {
* are required for writing but the status may be checked with either.
*/
#define VI_MOUNT 0x0020 /* Mount in progress */
-#define VI_AGE 0x0040 /* Insert vnode at head of free list */
#define VI_DOOMED 0x0080 /* This vnode is being recycled */
#define VI_FREE 0x0100 /* This vnode is on the freelist */
#define VI_ACTIVE 0x0200 /* This vnode is on the active list */
@@ -285,6 +287,7 @@ struct vattr {
*/
#define VA_UTIMES_NULL 0x01 /* utimes argument was NULL */
#define VA_EXCLUSIVE 0x02 /* exclusive create request */
+#define VA_SYNC 0x04 /* O_SYNC truncation */
/*
* Flags for ioflag. (high 16 bits used to ask for read-ahead and
@@ -304,6 +307,7 @@ struct vattr {
#define IO_NORMAL 0x0800 /* operate on regular data */
#define IO_NOMACCHECK 0x1000 /* MAC checks unnecessary */
#define IO_BUFLOCKED 0x2000 /* ffs flag; indir buf is locked */
+#define IO_RANGELOCKED 0x4000 /* range locked */
#define IO_SEQMAX 0x7F /* seq heuristic max value */
#define IO_SEQSHIFT 16 /* seq heuristic in upper 16 bits */
@@ -334,6 +338,8 @@ struct vattr {
#define VWRITE_ACL 000040000000 /* change ACL and/or file mode */
#define VWRITE_OWNER 000100000000 /* change file owner */
#define VSYNCHRONIZE 000200000000 /* not used */
+#define VCREAT 000400000000 /* creating new file */
+#define VVERIFY 001000000000 /* verification required */
/*
* Permissions that were traditionally granted only to the file owner.
@@ -368,6 +374,8 @@ struct vattr {
MALLOC_DECLARE(M_VNODE);
#endif
+extern u_int ncsizefactor;
+
/*
* Convert between vnode types and inode formats (since POSIX.1
* defines mode word of stat structure in terms of inode formats).
@@ -393,10 +401,14 @@ extern int vttoif_tab[];
#define V_WAIT 0x0001 /* vn_start_write: sleep for suspend */
#define V_NOWAIT 0x0002 /* vn_start_write: don't sleep for suspend */
#define V_XSLEEP 0x0004 /* vn_start_write: just return after sleep */
+#define V_MNTREF 0x0010 /* vn_start_write: mp is already ref-ed */
#define VR_START_WRITE 0x0001 /* vfs_write_resume: start write atomically */
#define VR_NO_SUSPCLR 0x0002 /* vfs_write_resume: do not clear suspension */
+#define VS_SKIP_UNMOUNT 0x0001 /* vfs_write_suspend: fail if the
+ filesystem is being unmounted */
+
#define VREF(vp) vref(vp)
#ifdef DIAGNOSTIC
@@ -411,7 +423,7 @@ extern int vttoif_tab[];
* Global vnode data.
*/
extern struct vnode *rootvnode; /* root (i.e. "/") vnode */
-extern int async_io_version; /* 0 or POSIX version of AIO i'face */
+extern struct mount *rootdevmp; /* "/dev" mount */
extern int desiredvnodes; /* number of vnodes desired */
extern struct uma_zone *namei_zone;
extern struct vattr va_null; /* predefined null vattr structure */
@@ -424,6 +436,7 @@ extern struct vattr va_null; /* predefined null vattr structure */
#define VN_LOCK_AREC(vp) lockallowrecurse((vp)->v_vnlock)
#define VN_LOCK_ASHARE(vp) lockallowshare((vp)->v_vnlock)
+#define VN_LOCK_DSHARE(vp) lockdisableshare((vp)->v_vnlock)
#endif /* _KERNEL */
@@ -498,30 +511,20 @@ extern struct vnodeop_desc *vnodeop_descs[];
* reliable since if the thread sleeps between changing the lock
* state and checking it with the assert, some other thread could
* change the state. They are good enough for debugging a single
- * filesystem using a single-threaded test.
+ * filesystem using a single-threaded test. Note that the unreliability is
+ * limited to false negatives; efforts were made to ensure that false
+ * positives cannot occur.
*/
void assert_vi_locked(struct vnode *vp, const char *str);
void assert_vi_unlocked(struct vnode *vp, const char *str);
void assert_vop_elocked(struct vnode *vp, const char *str);
-#if 0
-void assert_vop_elocked_other(struct vnode *vp, const char *str);
-#endif
void assert_vop_locked(struct vnode *vp, const char *str);
-#if 0
-voi0 assert_vop_slocked(struct vnode *vp, const char *str);
-#endif
void assert_vop_unlocked(struct vnode *vp, const char *str);
#define ASSERT_VI_LOCKED(vp, str) assert_vi_locked((vp), (str))
#define ASSERT_VI_UNLOCKED(vp, str) assert_vi_unlocked((vp), (str))
#define ASSERT_VOP_ELOCKED(vp, str) assert_vop_elocked((vp), (str))
-#if 0
-#define ASSERT_VOP_ELOCKED_OTHER(vp, str) assert_vop_locked_other((vp), (str))
-#endif
#define ASSERT_VOP_LOCKED(vp, str) assert_vop_locked((vp), (str))
-#if 0
-#define ASSERT_VOP_SLOCKED(vp, str) assert_vop_slocked((vp), (str))
-#endif
#define ASSERT_VOP_UNLOCKED(vp, str) assert_vop_unlocked((vp), (str))
#else /* !DEBUG_VFS_LOCKS */
@@ -529,13 +532,7 @@ void assert_vop_unlocked(struct vnode *vp, const char *str);
#define ASSERT_VI_LOCKED(vp, str) ((void)0)
#define ASSERT_VI_UNLOCKED(vp, str) ((void)0)
#define ASSERT_VOP_ELOCKED(vp, str) ((void)0)
-#if 0
-#define ASSERT_VOP_ELOCKED_OTHER(vp, str)
-#endif
#define ASSERT_VOP_LOCKED(vp, str) ((void)0)
-#if 0
-#define ASSERT_VOP_SLOCKED(vp, str)
-#endif
#define ASSERT_VOP_UNLOCKED(vp, str) ((void)0)
#endif /* DEBUG_VFS_LOCKS */
@@ -566,10 +563,13 @@ vn_canvmio(struct vnode *vp)
/*
* Finally, include the default set of vnode operations.
*/
+typedef void vop_getpages_iodone_t(void *, vm_page_t *, int, int);
#include <rtems/bsd/local/vnode_if.h>
/* vn_open_flags */
#define VN_OPEN_NOAUDIT 0x00000001
+#define VN_OPEN_NOCAPCHECK 0x00000002
+#define VN_OPEN_NAMECACHE 0x00000004
/*
* Public vnode manipulation functions.
@@ -586,23 +586,26 @@ struct nstat;
struct ucred;
struct uio;
struct vattr;
+struct vfsops;
struct vnode;
+typedef int (*vn_get_ino_t)(struct mount *, void *, int, struct vnode **);
+
+int bnoreuselist(struct bufv *bufv, struct bufobj *bo, daddr_t startn,
+ daddr_t endn);
/* cache_* may belong in namei.h. */
+void cache_changesize(int newhashsize);
#define cache_enter(dvp, vp, cnp) \
cache_enter_time(dvp, vp, cnp, NULL, NULL)
void cache_enter_time(struct vnode *dvp, struct vnode *vp,
struct componentname *cnp, struct timespec *tsp,
struct timespec *dtsp);
-#define cache_lookup(dvp, vpp, cnp) \
- cache_lookup_times(dvp, vpp, cnp, NULL, NULL)
-int cache_lookup_times(struct vnode *dvp, struct vnode **vpp,
+int cache_lookup(struct vnode *dvp, struct vnode **vpp,
struct componentname *cnp, struct timespec *tsp, int *ticksp);
void cache_purge(struct vnode *vp);
void cache_purge_negative(struct vnode *vp);
void cache_purgevfs(struct mount *mp);
int change_dir(struct vnode *vp, struct thread *td);
-int change_root(struct vnode *vp, struct thread *td);
void cvtstat(struct stat *st, struct ostat *ost);
void cvtnstat(struct stat *sb, struct nstat *nsb);
int getnewvnode(const char *tag, struct mount *mp, struct vop_vector *vops,
@@ -616,8 +619,6 @@ u_quad_t init_va_filerev(void);
int speedup_syncer(void);
int vn_vptocnp(struct vnode **vp, struct ucred *cred, char *buf,
u_int *buflen);
-#define textvp_fullpath(p, rb, rfb) \
- vn_fullpath(FIRST_THREAD_IN_PROC(p), (p)->p_textvp, rb, rfb)
int vn_fullpath(struct thread *td, struct vnode *vn,
char **retbuf, char **freebuf);
int vn_fullpath_global(struct thread *td, struct vnode *vn,
@@ -638,21 +639,22 @@ int vaccess_acl_posix1e(enum vtype type, uid_t file_uid,
struct ucred *cred, int *privused);
void vattr_null(struct vattr *vap);
int vcount(struct vnode *vp);
-void vdrop(struct vnode *);
-void vdropl(struct vnode *);
+#define vdrop(vp) _vdrop((vp), 0)
+#define vdropl(vp) _vdrop((vp), 1)
+void _vdrop(struct vnode *, bool);
int vflush(struct mount *mp, int rootrefs, int flags, struct thread *td);
int vget(struct vnode *vp, int lockflag, struct thread *td);
void vgone(struct vnode *vp);
-void vhold(struct vnode *);
-void vholdl(struct vnode *);
+#define vhold(vp) _vhold((vp), 0)
+#define vholdl(vp) _vhold((vp), 1)
+void _vhold(struct vnode *, bool);
void vinactive(struct vnode *, struct thread *);
int vinvalbuf(struct vnode *vp, int save, int slpflag, int slptimeo);
-int vtruncbuf(struct vnode *vp, struct ucred *cred, struct thread *td,
- off_t length, int blksize);
+int vtruncbuf(struct vnode *vp, struct ucred *cred, off_t length,
+ int blksize);
void vunref(struct vnode *);
void vn_printf(struct vnode *vp, const char *fmt, ...) __printflike(2,3);
-#define vprint(label, vp) vn_printf((vp), "%s\n", (label))
-int vrecycle(struct vnode *vp, struct thread *td);
+int vrecycle(struct vnode *vp);
int vn_bmap_seekhole(struct vnode *vp, u_long cmd, off_t *off,
struct ucred *cred);
int vn_close(struct vnode *vp,
@@ -665,6 +667,8 @@ int _vn_lock(struct vnode *vp, int flags, char *file, int line);
int vn_open(struct nameidata *ndp, int *flagp, int cmode, struct file *fp);
int vn_open_cred(struct nameidata *ndp, int *flagp, int cmode,
u_int vn_open_flags, struct ucred *cred, struct file *fp);
+int vn_open_vnode(struct vnode *vp, int fmode, struct ucred *cred,
+ struct thread *td, struct file *fp);
void vn_pages_remove(struct vnode *vp, vm_pindex_t start, vm_pindex_t end);
int vn_pollrecord(struct vnode *vp, struct thread *p, int events);
int vn_rdwr(enum uio_rw rw, struct vnode *vp, void *base,
@@ -676,7 +680,7 @@ int vn_rdwr_inchunks(enum uio_rw rw, struct vnode *vp, void *base,
struct ucred *active_cred, struct ucred *file_cred, size_t *aresid,
struct thread *td);
int vn_rlimit_fsize(const struct vnode *vn, const struct uio *uio,
- const struct thread *td);
+ struct thread *td);
int vn_stat(struct vnode *vp, struct stat *sb, struct ucred *active_cred,
struct ucred *file_cred, struct thread *td);
int vn_start_write(struct vnode *vp, struct mount **mpp, int flags);
@@ -691,6 +695,10 @@ int vn_extattr_rm(struct vnode *vp, int ioflg, int attrnamespace,
const char *attrname, struct thread *td);
int vn_vget_ino(struct vnode *vp, ino_t ino, int lkflags,
struct vnode **rvp);
+int vn_vget_ino_gen(struct vnode *vp, vn_get_ino_t alloc,
+ void *alloc_arg, int lkflags, struct vnode **rvp);
+int vn_utimes_perm(struct vnode *vp, struct vattr *vap,
+ struct ucred *cred, struct thread *td);
int vn_io_fault_uiomove(char *data, int xfersize, struct uio *uio);
int vn_io_fault_pgmove(vm_page_t ma[], vm_offset_t offset, int xfersize,
@@ -708,10 +716,12 @@ int vn_io_fault_pgmove(vm_page_t ma[], vm_offset_t offset, int xfersize,
int vfs_cache_lookup(struct vop_lookup_args *ap);
void vfs_timestamp(struct timespec *);
-void vfs_write_resume(struct mount *mp);
-void vfs_write_resume_flags(struct mount *mp, int flags);
-int vfs_write_suspend(struct mount *mp);
+void vfs_write_resume(struct mount *mp, int flags);
+int vfs_write_suspend(struct mount *mp, int flags);
+int vfs_write_suspend_umnt(struct mount *mp);
+void vnlru_free(int, struct vfsops *);
int vop_stdbmap(struct vop_bmap_args *);
+int vop_stdfdatasync_buf(struct vop_fdatasync_args *);
int vop_stdfsync(struct vop_fsync_args *);
int vop_stdgetwritemount(struct vop_getwritemount_args *);
int vop_stdgetpages(struct vop_getpages_args *);
@@ -743,33 +753,51 @@ int vop_enoent(struct vop_generic_args *ap);
int vop_enotty(struct vop_generic_args *ap);
int vop_null(struct vop_generic_args *ap);
int vop_panic(struct vop_generic_args *ap);
+int dead_poll(struct vop_poll_args *ap);
+int dead_read(struct vop_read_args *ap);
+int dead_write(struct vop_write_args *ap);
/* These are called from within the actual VOPS. */
+void vop_close_post(void *a, int rc);
void vop_create_post(void *a, int rc);
void vop_deleteextattr_post(void *a, int rc);
void vop_link_post(void *a, int rc);
-void vop_lock_pre(void *a);
-void vop_lock_post(void *a, int rc);
void vop_lookup_post(void *a, int rc);
void vop_lookup_pre(void *a);
void vop_mkdir_post(void *a, int rc);
void vop_mknod_post(void *a, int rc);
+void vop_open_post(void *a, int rc);
+void vop_read_post(void *a, int rc);
+void vop_readdir_post(void *a, int rc);
+void vop_reclaim_post(void *a, int rc);
void vop_remove_post(void *a, int rc);
void vop_rename_post(void *a, int rc);
void vop_rename_pre(void *a);
void vop_rmdir_post(void *a, int rc);
void vop_setattr_post(void *a, int rc);
void vop_setextattr_post(void *a, int rc);
-void vop_strategy_pre(void *a);
void vop_symlink_post(void *a, int rc);
+
+#ifdef DEBUG_VFS_LOCKS
+void vop_strategy_pre(void *a);
+void vop_lock_pre(void *a);
+void vop_lock_post(void *a, int rc);
void vop_unlock_post(void *a, int rc);
void vop_unlock_pre(void *a);
+#else
+#define vop_strategy_pre(x) do { } while (0)
+#define vop_lock_pre(x) do { } while (0)
+#define vop_lock_post(x, y) do { } while (0)
+#define vop_unlock_post(x, y) do { } while (0)
+#define vop_unlock_pre(x) do { } while (0)
+#endif
void vop_rename_fail(struct vop_rename_args *ap);
#define VOP_WRITE_PRE(ap) \
struct vattr va; \
- int error, osize, ooffset, noffset; \
+ int error; \
+ off_t osize, ooffset, noffset; \
\
osize = ooffset = noffset = 0; \
if (!VN_KNLIST_EMPTY((ap)->a_vp)) { \
@@ -777,7 +805,7 @@ void vop_rename_fail(struct vop_rename_args *ap);
if (error) \
return (error); \
ooffset = (ap)->a_uio->uio_offset; \
- osize = va.va_size; \
+ osize = (off_t)va.va_size; \
}
#define VOP_WRITE_POST(ap, ret) \
@@ -793,6 +821,7 @@ void vop_rename_fail(struct vop_rename_args *ap);
void vput(struct vnode *vp);
void vrele(struct vnode *vp);
void vref(struct vnode *vp);
+void vrefl(struct vnode *vp);
int vrefcnt(struct vnode *vp);
void v_addpollinfo(struct vnode *vp);
@@ -811,12 +840,20 @@ extern struct vop_vector default_vnodeops;
#define VOP_ENOENT ((void*)(uintptr_t)vop_enoent)
#define VOP_EOPNOTSUPP ((void*)(uintptr_t)vop_eopnotsupp)
+/* fifo_vnops.c */
+int fifo_printinfo(struct vnode *);
+
/* vfs_hash.c */
typedef int vfs_hash_cmp_t(struct vnode *vp, void *arg);
-int vfs_hash_get(const struct mount *mp, u_int hash, int flags, struct thread *td, struct vnode **vpp, vfs_hash_cmp_t *fn, void *arg);
+void vfs_hash_changesize(int newhashsize);
+int vfs_hash_get(const struct mount *mp, u_int hash, int flags,
+ struct thread *td, struct vnode **vpp, vfs_hash_cmp_t *fn, void *arg);
u_int vfs_hash_index(struct vnode *vp);
-int vfs_hash_insert(struct vnode *vp, u_int hash, int flags, struct thread *td, struct vnode **vpp, vfs_hash_cmp_t *fn, void *arg);
+int vfs_hash_insert(struct vnode *vp, u_int hash, int flags, struct thread *td,
+ struct vnode **vpp, vfs_hash_cmp_t *fn, void *arg);
+void vfs_hash_ref(const struct mount *mp, u_int hash, struct thread *td,
+ struct vnode **vpp, vfs_hash_cmp_t *fn, void *arg);
void vfs_hash_rehash(struct vnode *vp, u_int hash);
void vfs_hash_remove(struct vnode *vp);