diff options
Diffstat (limited to 'freebsd/sys/sys')
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); |