From fef0fdf2d582edbc2f3daba606a9a1f1bffb3388 Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Wed, 23 Jul 2003 07:14:19 +0000 Subject: [PATCH] 2003-07-22 Hiten Pandya * MFC FreeBSD rev. 1.189 of kern_exit.c (DONE) (shmexit to take vmspace instead of proc) (sort the sys/lock.h include in vm_map.c too) * MFC FreeBSD rev. 1.143 of kern_sysctl.c (DONE) (don't panic if sysctl is unregistrable) * Don't panic when enumerating SYSCTL_NODE() without children nodes. (DONE) * MFC FreeBSD rev. 1.113 of kern_sysctl.c (DONE) (Fix ogetkerninfo() handling for KINFO_BSD_SYSINFO) * MFC FreeBSD rev. 1.103 of kern_sysctl.c (DONE) (Never reuse AUTO_OID values) * MFC FreeBSD rev 1.21 of i386/include/bus_dma.h (BUS_DMAMEM_NOSYNC -> BUS_DMA_COHERENT) * MFC FreeBSD rev. 1.19 of i386/include/bus_dma.h (DONE) (Implement real read/write barriers for i386) Submitted by: Hiten Pandya --- sys/cpu/i386/include/bus_at386.h | 19 +++++--- sys/cpu/i386/include/bus_dma.h | 4 +- sys/i386/include/bus_at386.h | 19 +++++--- sys/i386/include/bus_dma.h | 4 +- sys/kern/kern_exec.c | 5 +-- sys/kern/kern_exit.c | 5 +-- sys/kern/kern_sysctl.c | 61 +++++++++++++++++--------- sys/kern/sysv_ipc.c | 5 +-- sys/kern/sysv_shm.c | 31 +++++++------ sys/net/i4b/layer1/itjc/i4b_itjc_pci.c | 6 +-- sys/sys/shm.h | 5 ++- sys/vm/vm_map.c | 11 ++++- 12 files changed, 109 insertions(+), 66 deletions(-) diff --git a/sys/cpu/i386/include/bus_at386.h b/sys/cpu/i386/include/bus_at386.h index 8354799d16..25bea3b4f7 100644 --- a/sys/cpu/i386/include/bus_at386.h +++ b/sys/cpu/i386/include/bus_at386.h @@ -68,7 +68,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* $FreeBSD: src/sys/i386/include/bus_at386.h,v 1.8.2.3 2002/03/03 05:42:50 nyan Exp $ */ -/* $DragonFly: src/sys/cpu/i386/include/bus_at386.h,v 1.2 2003/06/17 04:28:35 dillon Exp $ */ +/* $DragonFly: src/sys/cpu/i386/include/bus_at386.h,v 1.3 2003/07/23 07:14:15 dillon Exp $ */ #ifndef _I386_BUS_AT386_H_ #define _I386_BUS_AT386_H_ @@ -1156,12 +1156,21 @@ bus_space_copy_region_4(bus_space_tag_t tag, bus_space_handle_t bsh1, * void bus_space_barrier(bus_space_tag_t tag, bus_space_handle_t bsh, * bus_size_t offset, bus_size_t len, int flags); * - * Note: the i386 does not currently require barriers, but we must - * provide the flags to MI code. + * Note that BUS_SPACE_BARRIER_WRITE doesn't do anything other than + * prevent reordering by the compiler; all Intel x86 processors currently + * retire operations outside the CPU in program order. */ -#define bus_space_barrier(t, h, o, l, f) \ - ((void)((void)(t), (void)(h), (void)(o), (void)(l), (void)(f))) #define BUS_SPACE_BARRIER_READ 0x01 /* force read barrier */ #define BUS_SPACE_BARRIER_WRITE 0x02 /* force write barrier */ +static __inline void +bus_space_barrier(bus_space_tag_t tag, bus_space_handle_t bsh, + bus_size_t offset, bus_size_t len, int flags) +{ + if (flags & BUS_SPACE_BARRIER_READ) + __asm __volatile("lock; addl $0,0(%esp)" : : : "memory"); + else + __asm __volatile("" : : : "memory"); +} + #endif /* _I386_BUS_AT386_H_ */ diff --git a/sys/cpu/i386/include/bus_dma.h b/sys/cpu/i386/include/bus_dma.h index 3a4bc05ee2..085756cc91 100644 --- a/sys/cpu/i386/include/bus_dma.h +++ b/sys/cpu/i386/include/bus_dma.h @@ -68,7 +68,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* $FreeBSD: src/sys/i386/include/bus_dma.h,v 1.15.2.2 2002/11/21 23:36:01 sam Exp $ */ -/* $DragonFly: src/sys/cpu/i386/include/bus_dma.h,v 1.2 2003/06/17 04:28:35 dillon Exp $ */ +/* $DragonFly: src/sys/cpu/i386/include/bus_dma.h,v 1.3 2003/07/23 07:14:15 dillon Exp $ */ #ifndef _I386_BUS_DMA_H_ #define _I386_BUS_DMA_H_ @@ -79,7 +79,7 @@ #define BUS_DMA_WAITOK 0x00 /* safe to sleep (pseudo-flag) */ #define BUS_DMA_NOWAIT 0x01 /* not safe to sleep */ #define BUS_DMA_ALLOCNOW 0x02 /* perform resource allocation now */ -#define BUS_DMAMEM_NOSYNC 0x04 /* map memory to not require sync */ +#define BUS_DMA_COHERENT 0x04 /* map memory to not require sync */ #define BUS_DMA_BUS1 0x10 /* placeholders for bus functions... */ #define BUS_DMA_BUS2 0x20 #define BUS_DMA_BUS3 0x40 diff --git a/sys/i386/include/bus_at386.h b/sys/i386/include/bus_at386.h index 7a61972318..14c272e681 100644 --- a/sys/i386/include/bus_at386.h +++ b/sys/i386/include/bus_at386.h @@ -68,7 +68,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* $FreeBSD: src/sys/i386/include/bus_at386.h,v 1.8.2.3 2002/03/03 05:42:50 nyan Exp $ */ -/* $DragonFly: src/sys/i386/include/Attic/bus_at386.h,v 1.2 2003/06/17 04:28:35 dillon Exp $ */ +/* $DragonFly: src/sys/i386/include/Attic/bus_at386.h,v 1.3 2003/07/23 07:14:15 dillon Exp $ */ #ifndef _I386_BUS_AT386_H_ #define _I386_BUS_AT386_H_ @@ -1156,12 +1156,21 @@ bus_space_copy_region_4(bus_space_tag_t tag, bus_space_handle_t bsh1, * void bus_space_barrier(bus_space_tag_t tag, bus_space_handle_t bsh, * bus_size_t offset, bus_size_t len, int flags); * - * Note: the i386 does not currently require barriers, but we must - * provide the flags to MI code. + * Note that BUS_SPACE_BARRIER_WRITE doesn't do anything other than + * prevent reordering by the compiler; all Intel x86 processors currently + * retire operations outside the CPU in program order. */ -#define bus_space_barrier(t, h, o, l, f) \ - ((void)((void)(t), (void)(h), (void)(o), (void)(l), (void)(f))) #define BUS_SPACE_BARRIER_READ 0x01 /* force read barrier */ #define BUS_SPACE_BARRIER_WRITE 0x02 /* force write barrier */ +static __inline void +bus_space_barrier(bus_space_tag_t tag, bus_space_handle_t bsh, + bus_size_t offset, bus_size_t len, int flags) +{ + if (flags & BUS_SPACE_BARRIER_READ) + __asm __volatile("lock; addl $0,0(%esp)" : : : "memory"); + else + __asm __volatile("" : : : "memory"); +} + #endif /* _I386_BUS_AT386_H_ */ diff --git a/sys/i386/include/bus_dma.h b/sys/i386/include/bus_dma.h index a2a7adf746..6ce3be9360 100644 --- a/sys/i386/include/bus_dma.h +++ b/sys/i386/include/bus_dma.h @@ -68,7 +68,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* $FreeBSD: src/sys/i386/include/bus_dma.h,v 1.15.2.2 2002/11/21 23:36:01 sam Exp $ */ -/* $DragonFly: src/sys/i386/include/Attic/bus_dma.h,v 1.2 2003/06/17 04:28:35 dillon Exp $ */ +/* $DragonFly: src/sys/i386/include/Attic/bus_dma.h,v 1.3 2003/07/23 07:14:15 dillon Exp $ */ #ifndef _I386_BUS_DMA_H_ #define _I386_BUS_DMA_H_ @@ -79,7 +79,7 @@ #define BUS_DMA_WAITOK 0x00 /* safe to sleep (pseudo-flag) */ #define BUS_DMA_NOWAIT 0x01 /* not safe to sleep */ #define BUS_DMA_ALLOCNOW 0x02 /* perform resource allocation now */ -#define BUS_DMAMEM_NOSYNC 0x04 /* map memory to not require sync */ +#define BUS_DMA_COHERENT 0x04 /* map memory to not require sync */ #define BUS_DMA_BUS1 0x10 /* placeholders for bus functions... */ #define BUS_DMA_BUS2 0x20 #define BUS_DMA_BUS3 0x40 diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c index dcb3d42f30..510e5fc47e 100644 --- a/sys/kern/kern_exec.c +++ b/sys/kern/kern_exec.c @@ -24,7 +24,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/kern/kern_exec.c,v 1.107.2.15 2002/07/30 15:40:46 nectar Exp $ - * $DragonFly: src/sys/kern/kern_exec.c,v 1.6 2003/06/26 05:55:14 dillon Exp $ + * $DragonFly: src/sys/kern/kern_exec.c,v 1.7 2003/07/23 07:14:18 dillon Exp $ */ #include @@ -533,8 +533,7 @@ exec_new_vmspace(imgp) * not disrupted */ if (vmspace->vm_refcnt == 1) { - if (vmspace->vm_shm) - shmexit(imgp->proc); + shmexit(vmspace); pmap_remove_pages(vmspace_pmap(vmspace), 0, VM_MAXUSER_ADDRESS); vm_map_remove(map, 0, VM_MAXUSER_ADDRESS); } else { diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c index 406fd478cb..768d4f48e7 100644 --- a/sys/kern/kern_exit.c +++ b/sys/kern/kern_exit.c @@ -37,7 +37,7 @@ * * @(#)kern_exit.c 8.7 (Berkeley) 2/12/94 * $FreeBSD: src/sys/kern/kern_exit.c,v 1.92.2.11 2003/01/13 22:51:16 dillon Exp $ - * $DragonFly: src/sys/kern/kern_exit.c,v 1.18 2003/07/19 21:14:38 dillon Exp $ + * $DragonFly: src/sys/kern/kern_exit.c,v 1.19 2003/07/23 07:14:18 dillon Exp $ */ #include "opt_compat.h" @@ -216,8 +216,7 @@ exit1(int rv) */ ++vm->vm_exitingcnt; if (--vm->vm_refcnt == 0) { - if (vm->vm_shm) - shmexit(p); + shmexit(vm); pmap_remove_pages(vmspace_pmap(vm), VM_MIN_ADDRESS, VM_MAXUSER_ADDRESS); (void) vm_map_remove(&vm->vm_map, VM_MIN_ADDRESS, diff --git a/sys/kern/kern_sysctl.c b/sys/kern/kern_sysctl.c index c812cb1360..1c6e30e685 100644 --- a/sys/kern/kern_sysctl.c +++ b/sys/kern/kern_sysctl.c @@ -38,7 +38,7 @@ * * @(#)kern_sysctl.c 8.4 (Berkeley) 4/14/94 * $FreeBSD: src/sys/kern/kern_sysctl.c,v 1.92.2.9 2003/05/01 22:48:09 trhodes Exp $ - * $DragonFly: src/sys/kern/kern_sysctl.c,v 1.7 2003/07/19 21:14:38 dillon Exp $ + * $DragonFly: src/sys/kern/kern_sysctl.c,v 1.8 2003/07/23 07:14:18 dillon Exp $ */ #include "opt_compat.h" @@ -94,7 +94,6 @@ void sysctl_register_oid(struct sysctl_oid *oidp) struct sysctl_oid_list *parent = oidp->oid_parent; struct sysctl_oid *p; struct sysctl_oid *q; - int n; /* * First check if another oid with the same name already @@ -116,13 +115,10 @@ void sysctl_register_oid(struct sysctl_oid *oidp) * 100 to leave space for pre-assigned oid numbers. */ if (oidp->oid_number == OID_AUTO) { - /* First, find the highest oid in the parent list >99 */ - n = 99; - SLIST_FOREACH(p, parent, oid_link) { - if (p->oid_number > n) - n = p->oid_number; - } - oidp->oid_number = n + 1; + static int newoid = 100; + oidp->oid_number = newoid++; + if (newoid == 0x7fffffff) + panic("out of oids"); } /* @@ -142,8 +138,30 @@ void sysctl_register_oid(struct sysctl_oid *oidp) void sysctl_unregister_oid(struct sysctl_oid *oidp) { + struct sysctl_oid *p; + int error; - SLIST_REMOVE(oidp->oid_parent, oidp, sysctl_oid, oid_link); + error = ENOENT; + if (oidp->oid_number == OID_AUTO) { + error = EINVAL; + } else { + SLIST_FOREACH(p, oidp->oid_parent, oid_link) { + if (p == oidp) { + SLIST_REMOVE(oidp->oid_parent, oidp, + sysctl_oid, oid_link); + error = 0; + break; + } + } + } + + /* + * This can happen when a module fails to register and is + * being unloaded afterwards. It should not be a panic() + * for normal use. + */ + if (error) + printf("%s: failed to unregister sysctl\n", __func__); } /* Initialize a new context to keep track of dynamically added sysctls. */ @@ -560,7 +578,7 @@ sysctl_sysctl_next_ls(struct sysctl_oid_list *lsp, int *name, u_int namelen, if (!sysctl_sysctl_next_ls(lsp, 0, 0, next+1, len, level+1, oidpp)) return 0; - goto next; + goto emptynode; } if (oidp->oid_number < *name) @@ -590,6 +608,8 @@ sysctl_sysctl_next_ls(struct sysctl_oid_list *lsp, int *name, u_int namelen, next: namelen = 1; *len = level; + emptynode: + *len = level; } return 1; } @@ -1299,6 +1319,7 @@ ogetkerninfo(struct getkerninfo_args *uap) { int error, name[6]; size_t size; + u_int needed = 0; switch (uap->op & 0xff00) { @@ -1361,17 +1382,15 @@ ogetkerninfo(struct getkerninfo_args *uap) /* * this is pretty crude, but it's just enough for uname() * from BSDI's 1.x libc to work. + * *size gives the size of the buffer before the call, and + * the amount of data copied after a successful call. + * If successful, the return value is the amount of data + * available, which can be larger than *size. * - * In particular, it doesn't return the same results when - * the supplied buffer is too small. BSDI's version apparently - * will return the amount copied, and set the *size to how - * much was needed. The emulation framework here isn't capable - * of that, so we just set both to the amount copied. - * BSDI's 2.x product apparently fails with ENOMEM in this - * scenario. + * BSDI's 2.x product apparently fails with ENOMEM if + * *size is too small. */ - u_int needed; u_int left; char *s; @@ -1394,13 +1413,15 @@ ogetkerninfo(struct getkerninfo_args *uap) needed = sizeof(bsdi_si) + (s - bsdi_strings); - if (uap->where == NULL) { + if (uap->where == NULL || (uap->size == NULL)) { /* process is asking how much buffer to supply.. */ size = needed; error = 0; break; } + if ((error = copyin(uap->size, &size, sizeof(size))) != 0) + break; /* if too much buffer supplied, trim it down */ if (size > needed) diff --git a/sys/kern/sysv_ipc.c b/sys/kern/sysv_ipc.c index 95703dbc56..b84cf4950b 100644 --- a/sys/kern/sysv_ipc.c +++ b/sys/kern/sysv_ipc.c @@ -1,5 +1,5 @@ /* $FreeBSD: src/sys/kern/sysv_ipc.c,v 1.13.2.2 2000/07/01 14:33:49 bsd Exp $ */ -/* $DragonFly: src/sys/kern/sysv_ipc.c,v 1.4 2003/06/25 03:55:57 dillon Exp $ */ +/* $DragonFly: src/sys/kern/sysv_ipc.c,v 1.5 2003/07/23 07:14:18 dillon Exp $ */ /* $NetBSD: sysv_ipc.c,v 1.7 1994/06/29 06:33:11 cgd Exp $ */ /* @@ -261,8 +261,7 @@ shmfork(p1, p2) /* called from kern_exit.c */ void -shmexit(p) - struct proc *p; +shmexit(struct vmspace *vm) { return; } diff --git a/sys/kern/sysv_shm.c b/sys/kern/sysv_shm.c index ba9f6f8c7b..1e0fb79b05 100644 --- a/sys/kern/sysv_shm.c +++ b/sys/kern/sysv_shm.c @@ -1,5 +1,5 @@ /* $FreeBSD: src/sys/kern/sysv_shm.c,v 1.45.2.6 2002/10/22 20:45:03 fjoe Exp $ */ -/* $DragonFly: src/sys/kern/sysv_shm.c,v 1.4 2003/07/19 21:14:39 dillon Exp $ */ +/* $DragonFly: src/sys/kern/sysv_shm.c,v 1.5 2003/07/23 07:14:18 dillon Exp $ */ /* $NetBSD: sysv_shm.c,v 1.23 1994/07/04 23:25:12 glass Exp $ */ /* @@ -93,7 +93,7 @@ struct shmmap_state { static void shm_deallocate_segment __P((struct shmid_ds *)); static int shm_find_segment_by_key __P((key_t)); static struct shmid_ds *shm_find_segment_by_shmid __P((int)); -static int shm_delete_mapping __P((struct proc *, struct shmmap_state *)); +static int shm_delete_mapping __P((struct vmspace *vm, struct shmmap_state *)); static void shmrealloc __P((void)); static void shminit __P((void *)); @@ -192,9 +192,7 @@ shm_deallocate_segment(shmseg) } static int -shm_delete_mapping(p, shmmap_s) - struct proc *p; - struct shmmap_state *shmmap_s; +shm_delete_mapping(struct vmspace *vm, struct shmmap_state *shmmap_s) { struct shmid_ds *shmseg; int segnum, result; @@ -203,7 +201,7 @@ shm_delete_mapping(p, shmmap_s) segnum = IPCID_TO_IX(shmmap_s->shmid); shmseg = &shmsegs[segnum]; size = round_page(shmseg->shm_segsz); - result = vm_map_remove(&p->p_vmspace->vm_map, shmmap_s->va, shmmap_s->va + size); + result = vm_map_remove(&vm->vm_map, shmmap_s->va, shmmap_s->va + size); if (result != KERN_SUCCESS) return EINVAL; shmmap_s->shmid = -1; @@ -241,7 +239,7 @@ shmdt(struct shmdt_args *uap) break; if (i == shminfo.shmseg) return EINVAL; - return shm_delete_mapping(p, shmmap_s); + return shm_delete_mapping(p->p_vmspace, shmmap_s); } #ifndef _SYS_SYSPROTO_H_ @@ -640,18 +638,19 @@ shmfork(p1, p2) } void -shmexit(p) - struct proc *p; +shmexit(struct vmspace *vm) { - struct shmmap_state *shmmap_s; + struct shmmap_state *base, *shm; int i; - shmmap_s = (struct shmmap_state *)p->p_vmspace->vm_shm; - for (i = 0; i < shminfo.shmseg; i++, shmmap_s++) - if (shmmap_s->shmid != -1) - shm_delete_mapping(p, shmmap_s); - free((caddr_t)p->p_vmspace->vm_shm, M_SHM); - p->p_vmspace->vm_shm = NULL; + if ((base = (struct shmmap_state *)vm->vm_shm) != NULL) { + vm->vm_shm = NULL; + for (i = 0, shm = base; i < shminfo.shmseg; i++, shm++) { + if (shm->shmid != -1) + shm_delete_mapping(vm, shm); + } + free(base, M_SHM); + } } static void diff --git a/sys/net/i4b/layer1/itjc/i4b_itjc_pci.c b/sys/net/i4b/layer1/itjc/i4b_itjc_pci.c index e3654613cb..fcae6ce020 100644 --- a/sys/net/i4b/layer1/itjc/i4b_itjc_pci.c +++ b/sys/net/i4b/layer1/itjc/i4b_itjc_pci.c @@ -34,7 +34,7 @@ * ---------------------------------------- * * $FreeBSD: src/sys/i4b/layer1/itjc/i4b_itjc_pci.c,v 1.1.2.1 2001/08/10 14:08:39 obrien Exp $ - * $DragonFly: src/sys/net/i4b/layer1/itjc/i4b_itjc_pci.c,v 1.2 2003/06/17 04:28:40 dillon Exp $ + * $DragonFly: src/sys/net/i4b/layer1/itjc/i4b_itjc_pci.c,v 1.3 2003/07/23 07:14:18 dillon Exp $ * * last edit-date: [Thu Jan 11 11:29:38 2001] * @@ -1610,7 +1610,7 @@ itjc_attach(device_t dev) ITJC_DMA_POOL_BYTES, /* maxsize*/ 1, /* nsegments*/ ITJC_DMA_POOL_BYTES, /* maxsegsz*/ - BUS_DMA_ALLOCNOW | BUS_DMAMEM_NOSYNC, /* flags*/ + BUS_DMA_ALLOCNOW | BUS_DMA_COHERENT, /* flags*/ &ctx->tag); if (error) @@ -1624,7 +1624,7 @@ itjc_attach(device_t dev) error = bus_dmamem_alloc( ctx->tag, /* DMA tag */ (void **)&ctx->pool, /* KV addr of the allocated memory */ - BUS_DMA_NOWAIT | BUS_DMAMEM_NOSYNC, /* flags */ + BUS_DMA_NOWAIT | BUS_DMA_COHERENT, /* flags */ &ctx->map); /* KV <-> PCI map */ if (error) diff --git a/sys/sys/shm.h b/sys/sys/shm.h index 26a5a39d63..139008b0db 100644 --- a/sys/sys/shm.h +++ b/sys/sys/shm.h @@ -1,5 +1,5 @@ /* $FreeBSD: src/sys/sys/shm.h,v 1.14 1999/12/29 04:24:46 peter Exp $ */ -/* $DragonFly: src/sys/sys/shm.h,v 1.2 2003/06/17 04:28:58 dillon Exp $ */ +/* $DragonFly: src/sys/sys/shm.h,v 1.3 2003/07/23 07:14:19 dillon Exp $ */ /* $NetBSD: shm.h,v 1.15 1994/06/29 06:45:17 cgd Exp $ */ /* @@ -81,8 +81,9 @@ extern struct shminfo shminfo; extern struct shmid_ds *shmsegs; struct proc; +struct vmspace; -void shmexit __P((struct proc *)); +void shmexit __P((struct vmspace *)); void shmfork __P((struct proc *, struct proc *)); #else /* !_KERNEL */ diff --git a/sys/vm/vm_map.c b/sys/vm/vm_map.c index 68080cc448..92479d1ca8 100644 --- a/sys/vm/vm_map.c +++ b/sys/vm/vm_map.c @@ -62,7 +62,7 @@ * rights to redistribute these changes. * * $FreeBSD: src/sys/vm/vm_map.c,v 1.187.2.19 2003/05/27 00:47:02 alc Exp $ - * $DragonFly: src/sys/vm/vm_map.c,v 1.6 2003/07/19 21:14:53 dillon Exp $ + * $DragonFly: src/sys/vm/vm_map.c,v 1.7 2003/07/23 07:14:19 dillon Exp $ */ /* @@ -72,14 +72,15 @@ #include #include #include +#include #include #include #include #include +#include #include #include -#include #include #include #include @@ -201,6 +202,12 @@ vm_init2(void) { static __inline void vmspace_dofree(struct vmspace *vm) { + /* + * Make sure any SysV shm is freed, it might not have in + * exit1() + */ + shmexit(vm); + /* * Lock the map, to wait out all other references to it. * Delete all of the mappings and pages they hold, then call -- 2.41.0