From owner-svn-src-user@FreeBSD.ORG Thu Jun 21 14:37:06 2012 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id CBFD11065673; Thu, 21 Jun 2012 14:37:06 +0000 (UTC) (envelope-from ae@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id B27C38FC1B; Thu, 21 Jun 2012 14:37:06 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id q5LEb67f018517; Thu, 21 Jun 2012 14:37:06 GMT (envelope-from ae@svn.freebsd.org) Received: (from ae@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id q5LEb64f018491; Thu, 21 Jun 2012 14:37:06 GMT (envelope-from ae@svn.freebsd.org) Message-Id: <201206211437.q5LEb64f018491@svn.freebsd.org> From: "Andrey V. Elsukov" Date: Thu, 21 Jun 2012 14:37:06 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r237399 - in user/ae/bootcode: bin/rm etc/periodic/daily lib/libc/string share/man/man4 sys/amd64/amd64 sys/boot/common sys/cam sys/cam/scsi sys/dev/puc sys/dev/viawd sys/dev/xen/balloo... X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 21 Jun 2012 14:37:06 -0000 Author: ae Date: Thu Jun 21 14:37:05 2012 New Revision: 237399 URL: http://svn.freebsd.org/changeset/base/237399 Log: Sync with head/. Modified: user/ae/bootcode/bin/rm/rm.c user/ae/bootcode/etc/periodic/daily/400.status-disks user/ae/bootcode/lib/libc/string/strcasecmp.3 user/ae/bootcode/lib/libc/string/strcoll.3 user/ae/bootcode/lib/libc/string/strstr.3 user/ae/bootcode/lib/libc/string/strxfrm.3 user/ae/bootcode/share/man/man4/cpufreq.4 user/ae/bootcode/sys/amd64/amd64/pmap.c user/ae/bootcode/sys/boot/common/load_elf.c user/ae/bootcode/sys/boot/common/load_elf_obj.c user/ae/bootcode/sys/cam/cam_periph.c user/ae/bootcode/sys/cam/cam_xpt.c user/ae/bootcode/sys/cam/cam_xpt_periph.h user/ae/bootcode/sys/cam/scsi/scsi_cd.c user/ae/bootcode/sys/cam/scsi/scsi_da.c user/ae/bootcode/sys/cam/scsi/scsi_enc.c user/ae/bootcode/sys/cam/scsi/scsi_pass.c user/ae/bootcode/sys/dev/puc/puc_cfg.h user/ae/bootcode/sys/dev/puc/pucdata.c user/ae/bootcode/sys/dev/viawd/viawd.c user/ae/bootcode/sys/dev/xen/balloon/balloon.c user/ae/bootcode/sys/fs/nfsclient/nfs_clbio.c user/ae/bootcode/sys/fs/nfsclient/nfs_clvfsops.c user/ae/bootcode/sys/kern/vfs_vnops.c user/ae/bootcode/sys/netinet/sctp_usrreq.c user/ae/bootcode/sys/ufs/ffs/ffs_vnops.c user/ae/bootcode/sys/vm/vm_map.c user/ae/bootcode/sys/vm/vm_page.c user/ae/bootcode/sys/vm/vm_page.h user/ae/bootcode/tools/regression/usr.bin/make/common.sh user/ae/bootcode/usr.bin/makewhatis/makewhatis.c user/ae/bootcode/usr.sbin/mfiutil/mfi_drive.c Directory Properties: user/ae/bootcode/ (props changed) user/ae/bootcode/lib/libc/ (props changed) user/ae/bootcode/share/man/man4/ (props changed) user/ae/bootcode/sys/ (props changed) user/ae/bootcode/sys/boot/ (props changed) Modified: user/ae/bootcode/bin/rm/rm.c ============================================================================== --- user/ae/bootcode/bin/rm/rm.c Thu Jun 21 14:35:46 2012 (r237398) +++ user/ae/bootcode/bin/rm/rm.c Thu Jun 21 14:37:05 2012 (r237399) @@ -301,10 +301,16 @@ rm_tree(char **argv) if (fflag) continue; /* FALLTHROUGH */ - default: + + case FTS_F: + case FTS_NSOK: if (Pflag) - if (!rm_overwrite(p->fts_accpath, NULL)) + if (!rm_overwrite(p->fts_accpath, p->fts_info == + FTS_NSOK ? NULL : p->fts_statp)) continue; + /* FALLTHROUGH */ + + default: rval = unlink(p->fts_accpath); if (rval == 0 || (fflag && errno == ENOENT)) { if (rval == 0 && vflag) Modified: user/ae/bootcode/etc/periodic/daily/400.status-disks ============================================================================== --- user/ae/bootcode/etc/periodic/daily/400.status-disks Thu Jun 21 14:35:46 2012 (r237398) +++ user/ae/bootcode/etc/periodic/daily/400.status-disks Thu Jun 21 14:37:05 2012 (r237399) @@ -19,12 +19,15 @@ case "$daily_status_disks_enable" in df $daily_status_disks_df_flags && rc=1 || rc=3 # display which filesystems need backing up - if ! [ -f /etc/fstab ]; then - export PATH_FSTAB=/dev/null - fi + if [ -s /etc/dumpdates ]; then + if ! [ -f /etc/fstab ]; then + export PATH_FSTAB=/dev/null + fi - echo "" - dump W || rc=3;; + echo "" + dump W || rc=3 + fi + ;; *) rc=0;; esac Modified: user/ae/bootcode/lib/libc/string/strcasecmp.3 ============================================================================== --- user/ae/bootcode/lib/libc/string/strcasecmp.3 Thu Jun 21 14:35:46 2012 (r237398) +++ user/ae/bootcode/lib/libc/string/strcasecmp.3 Thu Jun 21 14:37:05 2012 (r237399) @@ -45,6 +45,12 @@ .Fn strcasecmp "const char *s1" "const char *s2" .Ft int .Fn strncasecmp "const char *s1" "const char *s2" "size_t len" +.In string.h +.In xlocale.h +.Ft int +.Fn strcasecmp_l "const char *s1" "const char *s2" "locale_t loc" +.Ft int +.Fn strncasecmp_l "const char *s1" "const char *s2" "site_t len" "locale_t loc" .Sh DESCRIPTION The .Fn strcasecmp @@ -58,16 +64,22 @@ and .Pp The .Fn strncasecmp -compares at most +function compares at most .Fa len characters. -.Sh RETURN VALUES The +.Fn strcasecmp_l +and +.Fn strncasecmp_l +functions do the same as their non-locale versions above, but take an +explicit locale rather than using the current locale. +.Sh RETURN VALUES +The functions .Fn strcasecmp and .Fn strncasecmp return an integer greater than, equal to, or less than 0, -according as +depending on whether .Fa s1 is lexicographically greater than, equal to, or less than .Fa s2 @@ -77,6 +89,11 @@ The comparison is done using unsigned ch .Sq Li \e200 is greater than .Ql \e0 . +The functions +.Fn strcasecmp_l +and +.Fn strncasecmp_l +do the same but take explicit locales. .Sh SEE ALSO .Xr bcmp 3 , .Xr memcmp 3 , Modified: user/ae/bootcode/lib/libc/string/strcoll.3 ============================================================================== --- user/ae/bootcode/lib/libc/string/strcoll.3 Thu Jun 21 14:35:46 2012 (r237398) +++ user/ae/bootcode/lib/libc/string/strcoll.3 Thu Jun 21 14:37:05 2012 (r237399) @@ -44,6 +44,8 @@ .In string.h .Ft int .Fn strcoll "const char *s1" "const char *s2" +.Ft int +.Fn strcoll_l "const char *s1" "const char *s2" "locale_t loc" .Sh DESCRIPTION The .Fn strcoll @@ -54,7 +56,7 @@ and .Fa s2 according to the current locale collation and returns an integer greater than, equal to, or less than 0, -according as +depending on whether .Fa s1 is greater than, equal to, or less than .Fa s2 . @@ -62,6 +64,9 @@ If information about the current locale the value of .Fn strcmp s1 s2 is returned. +The +.Fn strcoll_l +function uses an explicit locale argument rather than the system locale. .Sh SEE ALSO .Xr setlocale 3 , .Xr strcmp 3 , @@ -70,6 +75,9 @@ is returned. .Sh STANDARDS The .Fn strcoll -function -conforms to +function conforms to .St -isoC . +The +.Fn strcoll_l +function conforms to +.St -p1003.1-2008 . Modified: user/ae/bootcode/lib/libc/string/strstr.3 ============================================================================== --- user/ae/bootcode/lib/libc/string/strstr.3 Thu Jun 21 14:35:46 2012 (r237398) +++ user/ae/bootcode/lib/libc/string/strstr.3 Thu Jun 21 14:37:05 2012 (r237399) @@ -49,6 +49,10 @@ .Fn strcasestr "const char *big" "const char *little" .Ft char * .Fn strnstr "const char *big" "const char *little" "size_t len" +.In string.h +.In xlocale.h +.Ft char * +.Fn strcasestr_l "const char *big" "const char *little" "locale_t loc" .Sh DESCRIPTION The .Fn strstr @@ -65,6 +69,12 @@ function is similar to but ignores the case of both strings. .Pp The +.Fn strcasestr_l +function does the same as +.Fn strcasestr +but takes an explicit locale rather than using the current locale. +.Pp +The .Fn strnstr function locates the first occurrence of the null-terminated string Modified: user/ae/bootcode/lib/libc/string/strxfrm.3 ============================================================================== --- user/ae/bootcode/lib/libc/string/strxfrm.3 Thu Jun 21 14:35:46 2012 (r237398) +++ user/ae/bootcode/lib/libc/string/strxfrm.3 Thu Jun 21 14:37:05 2012 (r237399) @@ -44,6 +44,8 @@ .In string.h .Ft size_t .Fn strxfrm "char * restrict dst" "const char * restrict src" "size_t n" +.Ft size_t +.Fn strxfrm_l "char * restrict dst" "const char *restrict src" "size_t n" "locale_t loc" .Sh DESCRIPTION The .Fn strxfrm @@ -73,10 +75,16 @@ after is equal to comparing two original strings with .Fn strcoll . +.Pp +.Fn strxfrm_l +does the same, however takes an explicit locale rather than the global +locale. .Sh RETURN VALUES Upon successful completion, .Fn strxfrm -returns the length of the transformed string not including +and +.Fn strxfrm_l +return the length of the transformed string not including the terminating null character. If this value is .Fa n @@ -94,3 +102,7 @@ The function conforms to .St -isoC . +The +.Fn strxfrm_l +function conforms to +.St -p1003.1-2008 . Modified: user/ae/bootcode/share/man/man4/cpufreq.4 ============================================================================== --- user/ae/bootcode/share/man/man4/cpufreq.4 Thu Jun 21 14:35:46 2012 (r237398) +++ user/ae/bootcode/share/man/man4/cpufreq.4 Thu Jun 21 14:37:05 2012 (r237399) @@ -286,6 +286,7 @@ then it should set all elements to .Dv CPUFREQ_VAL_UNKNOWN . .Sh SEE ALSO .Xr acpi 4 , +.Xr est 4 , .Xr timecounters 4 , .Xr powerd 8 , .Xr sysctl 8 Modified: user/ae/bootcode/sys/amd64/amd64/pmap.c ============================================================================== --- user/ae/bootcode/sys/amd64/amd64/pmap.c Thu Jun 21 14:35:46 2012 (r237398) +++ user/ae/bootcode/sys/amd64/amd64/pmap.c Thu Jun 21 14:37:05 2012 (r237399) @@ -241,7 +241,8 @@ static void free_pv_chunk(struct pv_chun static void free_pv_entry(pmap_t pmap, pv_entry_t pv); static pv_entry_t get_pv_entry(pmap_t pmap, boolean_t try); static void pmap_pv_demote_pde(pmap_t pmap, vm_offset_t va, vm_paddr_t pa); -static boolean_t pmap_pv_insert_pde(pmap_t pmap, vm_offset_t va, vm_paddr_t pa); +static boolean_t pmap_pv_insert_pde(pmap_t pmap, vm_offset_t va, vm_paddr_t pa, + struct rwlock **lockp); static void pmap_pv_promote_pde(pmap_t pmap, vm_offset_t va, vm_paddr_t pa); static void pmap_pvh_free(struct md_page *pvh, pmap_t pmap, vm_offset_t va); static pv_entry_t pmap_pvh_remove(struct md_page *pvh, pmap_t pmap, @@ -253,9 +254,9 @@ static boolean_t pmap_demote_pde(pmap_t static boolean_t pmap_demote_pdpe(pmap_t pmap, pdp_entry_t *pdpe, vm_offset_t va); static boolean_t pmap_enter_pde(pmap_t pmap, vm_offset_t va, vm_page_t m, - vm_prot_t prot); + vm_prot_t prot, struct rwlock **lockp); static vm_page_t pmap_enter_quick_locked(pmap_t pmap, vm_offset_t va, - vm_page_t m, vm_prot_t prot, vm_page_t mpte); + vm_page_t m, vm_prot_t prot, vm_page_t mpte, struct rwlock **lockp); static void pmap_fill_ptp(pt_entry_t *firstpte, pt_entry_t newpte); static void pmap_insert_pt_page(pmap_t pmap, vm_page_t mpte); static boolean_t pmap_is_modified_pvh(struct md_page *pvh); @@ -278,7 +279,7 @@ static void pmap_remove_entry(struct pma vm_offset_t va); static void pmap_insert_entry(pmap_t pmap, vm_offset_t va, vm_page_t m); static boolean_t pmap_try_insert_pv_entry(pmap_t pmap, vm_offset_t va, - vm_page_t m); + vm_page_t m, struct rwlock **lockp); static void pmap_update_pde(pmap_t pmap, vm_offset_t va, pd_entry_t *pde, pd_entry_t newpde); static void pmap_update_pde_invalidate(vm_offset_t va, pd_entry_t newpde); @@ -2463,14 +2464,23 @@ pmap_insert_entry(pmap_t pmap, vm_offset * Conditionally create a pv entry. */ static boolean_t -pmap_try_insert_pv_entry(pmap_t pmap, vm_offset_t va, vm_page_t m) +pmap_try_insert_pv_entry(pmap_t pmap, vm_offset_t va, vm_page_t m, + struct rwlock **lockp) { + struct rwlock *new_lock; pv_entry_t pv; - rw_assert(&pvh_global_lock, RA_WLOCKED); + rw_assert(&pvh_global_lock, RA_LOCKED); PMAP_LOCK_ASSERT(pmap, MA_OWNED); if ((pv = get_pv_entry(pmap, TRUE)) != NULL) { pv->pv_va = va; + new_lock = VM_PAGE_TO_PV_LIST_LOCK(m); + if (new_lock != *lockp) { + if (*lockp != NULL) + rw_wunlock(*lockp); + *lockp = new_lock; + rw_wlock(*lockp); + } TAILQ_INSERT_TAIL(&m->md.pv_list, pv, pv_list); return (TRUE); } else @@ -2481,14 +2491,23 @@ pmap_try_insert_pv_entry(pmap_t pmap, vm * Create the pv entry for a 2MB page mapping. */ static boolean_t -pmap_pv_insert_pde(pmap_t pmap, vm_offset_t va, vm_paddr_t pa) +pmap_pv_insert_pde(pmap_t pmap, vm_offset_t va, vm_paddr_t pa, + struct rwlock **lockp) { struct md_page *pvh; + struct rwlock *new_lock; pv_entry_t pv; - rw_assert(&pvh_global_lock, RA_WLOCKED); + rw_assert(&pvh_global_lock, RA_LOCKED); if ((pv = get_pv_entry(pmap, TRUE)) != NULL) { pv->pv_va = va; + new_lock = PHYS_TO_PV_LIST_LOCK(pa); + if (new_lock != *lockp) { + if (*lockp != NULL) + rw_wunlock(*lockp); + *lockp = new_lock; + rw_wlock(*lockp); + } pvh = pa_to_pvh(pa); TAILQ_INSERT_TAIL(&pvh->pv_list, pv, pv_list); return (TRUE); @@ -3434,12 +3453,13 @@ validate: * (3) a pv entry cannot be allocated without reclaiming another pv entry. */ static boolean_t -pmap_enter_pde(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot) +pmap_enter_pde(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot, + struct rwlock **lockp) { pd_entry_t *pde, newpde; vm_page_t free, mpde; - rw_assert(&pvh_global_lock, RA_WLOCKED); + rw_assert(&pvh_global_lock, RA_LOCKED); PMAP_LOCK_ASSERT(pmap, MA_OWNED); if ((mpde = pmap_allocpde(pmap, va, M_NOWAIT)) == NULL) { CTR2(KTR_PMAP, "pmap_enter_pde: failure for va %#lx" @@ -3464,7 +3484,8 @@ pmap_enter_pde(pmap_t pmap, vm_offset_t /* * Abort this mapping if its PV entry could not be created. */ - if (!pmap_pv_insert_pde(pmap, va, VM_PAGE_TO_PHYS(m))) { + if (!pmap_pv_insert_pde(pmap, va, VM_PAGE_TO_PHYS(m), + lockp)) { free = NULL; if (pmap_unwire_pte_hold(pmap, va, mpde, &free)) { pmap_invalidate_page(pmap, va); @@ -3490,7 +3511,7 @@ pmap_enter_pde(pmap_t pmap, vm_offset_t */ pde_store(pde, newpde); - pmap_pde_mappings++; + atomic_add_long(&pmap_pde_mappings, 1); CTR2(KTR_PMAP, "pmap_enter_pde: success for va %#lx" " in pmap %p", va, pmap); return (TRUE); @@ -3512,6 +3533,7 @@ void pmap_enter_object(pmap_t pmap, vm_offset_t start, vm_offset_t end, vm_page_t m_start, vm_prot_t prot) { + struct rwlock *lock; vm_offset_t va; vm_page_t m, mpte; vm_pindex_t diff, psize; @@ -3520,21 +3542,24 @@ pmap_enter_object(pmap_t pmap, vm_offset psize = atop(end - start); mpte = NULL; m = m_start; - rw_wlock(&pvh_global_lock); + lock = NULL; + rw_rlock(&pvh_global_lock); PMAP_LOCK(pmap); while (m != NULL && (diff = m->pindex - m_start->pindex) < psize) { va = start + ptoa(diff); if ((va & PDRMASK) == 0 && va + NBPDR <= end && (VM_PAGE_TO_PHYS(m) & PDRMASK) == 0 && pg_ps_enabled && vm_reserv_level_iffullpop(m) == 0 && - pmap_enter_pde(pmap, va, m, prot)) + pmap_enter_pde(pmap, va, m, prot, &lock)) m = &m[NBPDR / PAGE_SIZE - 1]; else mpte = pmap_enter_quick_locked(pmap, va, m, prot, - mpte); + mpte, &lock); m = TAILQ_NEXT(m, listq); } - rw_wunlock(&pvh_global_lock); + if (lock != NULL) + rw_wunlock(lock); + rw_runlock(&pvh_global_lock); PMAP_UNLOCK(pmap); } @@ -3550,17 +3575,21 @@ pmap_enter_object(pmap_t pmap, vm_offset void pmap_enter_quick(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot) { + struct rwlock *lock; - rw_wlock(&pvh_global_lock); + lock = NULL; + rw_rlock(&pvh_global_lock); PMAP_LOCK(pmap); - (void)pmap_enter_quick_locked(pmap, va, m, prot, NULL); - rw_wunlock(&pvh_global_lock); + (void)pmap_enter_quick_locked(pmap, va, m, prot, NULL, &lock); + if (lock != NULL) + rw_wunlock(lock); + rw_runlock(&pvh_global_lock); PMAP_UNLOCK(pmap); } static vm_page_t pmap_enter_quick_locked(pmap_t pmap, vm_offset_t va, vm_page_t m, - vm_prot_t prot, vm_page_t mpte) + vm_prot_t prot, vm_page_t mpte, struct rwlock **lockp) { vm_page_t free; pt_entry_t *pte; @@ -3569,7 +3598,7 @@ pmap_enter_quick_locked(pmap_t pmap, vm_ KASSERT(va < kmi.clean_sva || va >= kmi.clean_eva || (m->oflags & VPO_UNMANAGED) != 0, ("pmap_enter_quick_locked: managed mapping within the clean submap")); - rw_assert(&pvh_global_lock, RA_WLOCKED); + rw_assert(&pvh_global_lock, RA_LOCKED); PMAP_LOCK_ASSERT(pmap, MA_OWNED); /* @@ -3626,7 +3655,7 @@ pmap_enter_quick_locked(pmap_t pmap, vm_ * Enter on the PV list if part of our managed memory. */ if ((m->oflags & VPO_UNMANAGED) == 0 && - !pmap_try_insert_pv_entry(pmap, va, m)) { + !pmap_try_insert_pv_entry(pmap, va, m, lockp)) { if (mpte != NULL) { free = NULL; if (pmap_unwire_pte_hold(pmap, va, mpte, &free)) { @@ -3825,6 +3854,7 @@ void pmap_copy(pmap_t dst_pmap, pmap_t src_pmap, vm_offset_t dst_addr, vm_size_t len, vm_offset_t src_addr) { + struct rwlock *lock; vm_page_t free; vm_offset_t addr; vm_offset_t end_addr = src_addr + len; @@ -3833,7 +3863,8 @@ pmap_copy(pmap_t dst_pmap, pmap_t src_pm if (dst_addr != src_addr) return; - rw_wlock(&pvh_global_lock); + lock = NULL; + rw_rlock(&pvh_global_lock); if (dst_pmap < src_pmap) { PMAP_LOCK(dst_pmap); PMAP_LOCK(src_pmap); @@ -3885,7 +3916,7 @@ pmap_copy(pmap_t dst_pmap, pmap_t src_pm pde = &pde[pmap_pde_index(addr)]; if (*pde == 0 && ((srcptepaddr & PG_MANAGED) == 0 || pmap_pv_insert_pde(dst_pmap, addr, srcptepaddr & - PG_PS_FRAME))) { + PG_PS_FRAME, &lock))) { *pde = srcptepaddr & ~PG_W; pmap_resident_count_inc(dst_pmap, NBPDR / PAGE_SIZE); } else @@ -3922,7 +3953,8 @@ pmap_copy(pmap_t dst_pmap, pmap_t src_pm dst_pte = &dst_pte[pmap_pte_index(addr)]; if (*dst_pte == 0 && pmap_try_insert_pv_entry(dst_pmap, addr, - PHYS_TO_VM_PAGE(ptetemp & PG_FRAME))) { + PHYS_TO_VM_PAGE(ptetemp & PG_FRAME), + &lock)) { /* * Clear the wired, modified, and * accessed (referenced) bits @@ -3949,7 +3981,9 @@ pmap_copy(pmap_t dst_pmap, pmap_t src_pm } } out: - rw_wunlock(&pvh_global_lock); + if (lock != NULL) + rw_wunlock(lock); + rw_runlock(&pvh_global_lock); PMAP_UNLOCK(src_pmap); PMAP_UNLOCK(dst_pmap); } @@ -4158,9 +4192,9 @@ pmap_remove_pages(pmap_t pmap) printf("warning: pmap_remove_pages called with non-current pmap\n"); return; } + lock = NULL; rw_rlock(&pvh_global_lock); PMAP_LOCK(pmap); - lock = NULL; TAILQ_FOREACH_SAFE(pc, &pmap->pm_pvchunk, pc_list, npc) { allfree = 1; freed = 0; @@ -4268,10 +4302,6 @@ pmap_remove_pages(pmap_t pmap) PV_STAT(atomic_add_int(&pv_entry_spare, freed)); PV_STAT(atomic_subtract_long(&pv_entry_count, freed)); if (allfree) { - if (lock != NULL) { - rw_wunlock(lock); - lock = NULL; - } TAILQ_REMOVE(&pmap->pm_pvchunk, pc, pc_list); free_pv_chunk(pc); } Modified: user/ae/bootcode/sys/boot/common/load_elf.c ============================================================================== --- user/ae/bootcode/sys/boot/common/load_elf.c Thu Jun 21 14:35:46 2012 (r237398) +++ user/ae/bootcode/sys/boot/common/load_elf.c Thu Jun 21 14:37:05 2012 (r237399) @@ -612,7 +612,7 @@ __elfN(parse_modmetadata)(struct preload Elf_Addr v, p, p_stop; if (__elfN(lookup_symbol)(fp, ef, "__start_set_modmetadata_set", &sym) != 0) - return ENOENT; + return 0; p = sym.st_value + ef->off; if (__elfN(lookup_symbol)(fp, ef, "__stop_set_modmetadata_set", &sym) != 0) return ENOENT; Modified: user/ae/bootcode/sys/boot/common/load_elf_obj.c ============================================================================== --- user/ae/bootcode/sys/boot/common/load_elf_obj.c Thu Jun 21 14:35:46 2012 (r237398) +++ user/ae/bootcode/sys/boot/common/load_elf_obj.c Thu Jun 21 14:37:05 2012 (r237399) @@ -369,7 +369,7 @@ __elfN(obj_parse_modmetadata)(struct pre if (__elfN(obj_lookup_set)(fp, ef, "modmetadata_set", &p, &p_stop, &modcnt) != 0) - return ENOENT; + return 0; modcnt = 0; while (p < p_stop) { Modified: user/ae/bootcode/sys/cam/cam_periph.c ============================================================================== --- user/ae/bootcode/sys/cam/cam_periph.c Thu Jun 21 14:35:46 2012 (r237398) +++ user/ae/bootcode/sys/cam/cam_periph.c Thu Jun 21 14:37:05 2012 (r237399) @@ -258,7 +258,7 @@ failure: break; case 3: CAM_DEBUG(periph->path, CAM_DEBUG_INFO, ("Periph destroyed\n")); - xpt_remove_periph(periph); + xpt_remove_periph(periph, /*topology_lock_held*/ 0); /* FALLTHROUGH */ case 2: xpt_lock_buses(); @@ -610,13 +610,38 @@ camperiphfree(struct cam_periph *periph) return; } - TAILQ_REMOVE(&(*p_drv)->units, periph, unit_links); - (*p_drv)->generation++; + /* + * The peripheral destructor semantics dictate calling with only the + * SIM mutex held. Since it might sleep, it should not be called + * with the topology lock held. + */ xpt_unlock_buses(); + /* + * We need to call the peripheral destructor prior to removing the + * peripheral from the list. Otherwise, we risk running into a + * scenario where the peripheral unit number may get reused + * (because it has been removed from the list), but some resources + * used by the peripheral are still hanging around. In particular, + * the devfs nodes used by some peripherals like the pass(4) driver + * aren't fully cleaned up until the destructor is run. If the + * unit number is reused before the devfs instance is fully gone, + * devfs will panic. + */ if (periph->periph_dtor != NULL) periph->periph_dtor(periph); - xpt_remove_periph(periph); + + /* + * The peripheral list is protected by the topology lock. + */ + xpt_lock_buses(); + + TAILQ_REMOVE(&(*p_drv)->units, periph, unit_links); + (*p_drv)->generation++; + + xpt_remove_periph(periph, /*topology_lock_held*/ 1); + + xpt_unlock_buses(); CAM_DEBUG(periph->path, CAM_DEBUG_INFO, ("Periph destroyed\n")); if (periph->flags & CAM_PERIPH_NEW_DEV_FOUND) { Modified: user/ae/bootcode/sys/cam/cam_xpt.c ============================================================================== --- user/ae/bootcode/sys/cam/cam_xpt.c Thu Jun 21 14:35:46 2012 (r237398) +++ user/ae/bootcode/sys/cam/cam_xpt.c Thu Jun 21 14:37:05 2012 (r237399) @@ -1026,7 +1026,7 @@ xpt_add_periph(struct cam_periph *periph } void -xpt_remove_periph(struct cam_periph *periph) +xpt_remove_periph(struct cam_periph *periph, int topology_lock_held) { struct cam_ed *device; @@ -1047,9 +1047,13 @@ xpt_remove_periph(struct cam_periph *per SLIST_REMOVE(periph_head, periph, cam_periph, periph_links); } - mtx_lock(&xsoftc.xpt_topo_lock); + if (topology_lock_held == 0) + mtx_lock(&xsoftc.xpt_topo_lock); + xsoftc.xpt_generation++; - mtx_unlock(&xsoftc.xpt_topo_lock); + + if (topology_lock_held == 0) + mtx_unlock(&xsoftc.xpt_topo_lock); } Modified: user/ae/bootcode/sys/cam/cam_xpt_periph.h ============================================================================== --- user/ae/bootcode/sys/cam/cam_xpt_periph.h Thu Jun 21 14:35:46 2012 (r237398) +++ user/ae/bootcode/sys/cam/cam_xpt_periph.h Thu Jun 21 14:37:05 2012 (r237399) @@ -42,7 +42,8 @@ void xpt_polled_action(union ccb *ccb); void xpt_release_ccb(union ccb *released_ccb); void xpt_schedule(struct cam_periph *perph, u_int32_t new_priority); int32_t xpt_add_periph(struct cam_periph *periph); -void xpt_remove_periph(struct cam_periph *periph); +void xpt_remove_periph(struct cam_periph *periph, + int topology_lock_held); void xpt_announce_periph(struct cam_periph *periph, char *announce_string); #endif Modified: user/ae/bootcode/sys/cam/scsi/scsi_cd.c ============================================================================== --- user/ae/bootcode/sys/cam/scsi/scsi_cd.c Thu Jun 21 14:35:46 2012 (r237398) +++ user/ae/bootcode/sys/cam/scsi/scsi_cd.c Thu Jun 21 14:37:05 2012 (r237399) @@ -1049,7 +1049,11 @@ cdclose(struct disk *dp) softc = (struct cd_softc *)periph->softc; cam_periph_lock(periph); - cam_periph_hold(periph, PRIBIO); + if (cam_periph_hold(periph, PRIBIO) != 0) { + cam_periph_unlock(periph); + cam_periph_release(periph); + return (0); + } CAM_DEBUG(periph->path, CAM_DEBUG_TRACE | CAM_DEBUG_PERIPH, ("cdclose\n")); Modified: user/ae/bootcode/sys/cam/scsi/scsi_da.c ============================================================================== --- user/ae/bootcode/sys/cam/scsi/scsi_da.c Thu Jun 21 14:35:46 2012 (r237398) +++ user/ae/bootcode/sys/cam/scsi/scsi_da.c Thu Jun 21 14:37:05 2012 (r237399) @@ -982,14 +982,13 @@ daclose(struct disk *dp) { struct cam_periph *periph; struct da_softc *softc; - int error; periph = (struct cam_periph *)dp->d_drv1; if (periph == NULL) return (0); cam_periph_lock(periph); - if ((error = cam_periph_hold(periph, PRIBIO)) != 0) { + if (cam_periph_hold(periph, PRIBIO) != 0) { cam_periph_unlock(periph); cam_periph_release(periph); return (0); Modified: user/ae/bootcode/sys/cam/scsi/scsi_enc.c ============================================================================== --- user/ae/bootcode/sys/cam/scsi/scsi_enc.c Thu Jun 21 14:35:46 2012 (r237398) +++ user/ae/bootcode/sys/cam/scsi/scsi_enc.c Thu Jun 21 14:37:05 2012 (r237399) @@ -114,6 +114,16 @@ enc_init(void) } static void +enc_devgonecb(void *arg) +{ + struct cam_periph *periph; + + periph = (struct cam_periph *)arg; + + cam_periph_release(periph); +} + +static void enc_oninvalidate(struct cam_periph *periph) { struct enc_softc *enc; @@ -141,6 +151,8 @@ enc_oninvalidate(struct cam_periph *peri } callout_drain(&enc->status_updater); + destroy_dev_sched_cb(enc->enc_dev, enc_devgonecb, periph); + xpt_print(periph->path, "lost device\n"); } @@ -152,9 +164,7 @@ enc_dtor(struct cam_periph *periph) enc = periph->softc; xpt_print(periph->path, "removing device entry\n"); - cam_periph_unlock(periph); - destroy_dev(enc->enc_dev); - cam_periph_lock(periph); + /* If the sub-driver has a cleanup routine, call it */ if (enc->enc_vec.softc_cleanup != NULL) @@ -951,9 +961,19 @@ enc_ctor(struct cam_periph *periph, void goto out; } } + + if (cam_periph_acquire(periph) != CAM_REQ_CMP) { + xpt_print(periph->path, "%s: lost periph during " + "registration!\n", __func__); + cam_periph_lock(periph); + + return (CAM_REQ_CMP_ERR); + } + enc->enc_dev = make_dev(&enc_cdevsw, periph->unit_number, UID_ROOT, GID_OPERATOR, 0600, "%s%d", periph->periph_name, periph->unit_number); + cam_periph_lock(periph); enc->enc_dev->si_drv1 = periph; Modified: user/ae/bootcode/sys/cam/scsi/scsi_pass.c ============================================================================== --- user/ae/bootcode/sys/cam/scsi/scsi_pass.c Thu Jun 21 14:35:46 2012 (r237398) +++ user/ae/bootcode/sys/cam/scsi/scsi_pass.c Thu Jun 21 14:37:05 2012 (r237399) @@ -55,7 +55,8 @@ __FBSDID("$FreeBSD$"); typedef enum { PASS_FLAG_OPEN = 0x01, PASS_FLAG_LOCKED = 0x02, - PASS_FLAG_INVALID = 0x04 + PASS_FLAG_INVALID = 0x04, + PASS_FLAG_INITIAL_PHYSPATH = 0x08 } pass_flags; typedef enum { @@ -133,7 +134,18 @@ passinit(void) printf("pass: Failed to attach master async callback " "due to status 0x%x!\n", status); } - + +} + +static void +passdevgonecb(void *arg) +{ + struct cam_periph *periph; + + periph = (struct cam_periph *)arg; + + xpt_print(periph->path, "%s: devfs entry is gone\n", __func__); + cam_periph_release(periph); } static void @@ -151,6 +163,12 @@ passoninvalidate(struct cam_periph *peri softc->flags |= PASS_FLAG_INVALID; /* + * Tell devfs this device has gone away, and ask for a callback + * when it has cleaned up its state. + */ + destroy_dev_sched_cb(softc->dev, passdevgonecb, periph); + + /* * XXX Return all queued I/O with ENXIO. * XXX Handle any transactions queued to the card * with XPT_ABORT_CCB. @@ -176,11 +194,6 @@ passcleanup(struct cam_periph *periph) cam_periph_unlock(periph); taskqueue_drain(taskqueue_thread, &softc->add_physpath_task); - /* - * passcleanup() is indirectly a d_close method via passclose, - * so using destroy_dev(9) directly can result in deadlock. - */ - destroy_dev_sched(softc->dev); cam_periph_lock(periph); free(softc, M_DEVBUF); @@ -199,6 +212,12 @@ pass_add_physpath(void *context, int pen */ periph = context; softc = periph->softc; + cam_periph_lock(periph); + if (periph->flags & CAM_PERIPH_INVALID) { + cam_periph_unlock(periph); + return; + } + cam_periph_unlock(periph); physpath = malloc(MAXPATHLEN, M_DEVBUF, M_WAITOK); if (xpt_getattr(physpath, MAXPATHLEN, "GEOM::physpath", periph->path) == 0 @@ -208,6 +227,19 @@ pass_add_physpath(void *context, int pen softc->dev, softc->alias_dev, physpath); } free(physpath, M_DEVBUF); + + /* + * Now that we've made our alias, we no longer have to have a + * reference to the device. + */ + cam_periph_lock(periph); + if ((softc->flags & PASS_FLAG_INITIAL_PHYSPATH) == 0) { + softc->flags |= PASS_FLAG_INITIAL_PHYSPATH; + cam_periph_unlock(periph); + dev_rel(softc->dev); + } + else + cam_periph_unlock(periph); } static void @@ -281,12 +313,12 @@ passregister(struct cam_periph *periph, cgd = (struct ccb_getdev *)arg; if (periph == NULL) { - printf("passregister: periph was NULL!!\n"); + printf("%s: periph was NULL!!\n", __func__); return(CAM_REQ_CMP_ERR); } if (cgd == NULL) { - printf("passregister: no getdev CCB, can't register device\n"); + printf("%s: no getdev CCB, can't register device\n", __func__); return(CAM_REQ_CMP_ERR); } @@ -294,8 +326,8 @@ passregister(struct cam_periph *periph, M_DEVBUF, M_NOWAIT); if (softc == NULL) { - printf("passregister: Unable to probe new device. " - "Unable to allocate softc\n"); + printf("%s: Unable to probe new device. " + "Unable to allocate softc\n", __func__); return(CAM_REQ_CMP_ERR); } @@ -331,10 +363,31 @@ passregister(struct cam_periph *periph, DEVSTAT_TYPE_PASS, DEVSTAT_PRIORITY_PASS); + /* + * Acquire a reference to the periph before we create the devfs + * instance for it. We'll release this reference once the devfs + * instance has been freed. + */ + if (cam_periph_acquire(periph) != CAM_REQ_CMP) { + xpt_print(periph->path, "%s: lost periph during " + "registration!\n", __func__); + mtx_lock(periph->sim->mtx); + return (CAM_REQ_CMP_ERR); + } + /* Register the device */ softc->dev = make_dev(&pass_cdevsw, periph->unit_number, UID_ROOT, GID_OPERATOR, 0600, "%s%d", periph->periph_name, periph->unit_number); + + /* + * Now that we have made the devfs instance, hold a reference to it + * until the task queue has run to setup the physical path alias. + * That way devfs won't get rid of the device before we add our + * alias. + */ + dev_ref(softc->dev); + mtx_lock(periph->sim->mtx); softc->dev->si_drv1 = periph; Modified: user/ae/bootcode/sys/dev/puc/puc_cfg.h ============================================================================== --- user/ae/bootcode/sys/dev/puc/puc_cfg.h Thu Jun 21 14:35:46 2012 (r237398) +++ user/ae/bootcode/sys/dev/puc/puc_cfg.h Thu Jun 21 14:37:05 2012 (r237399) @@ -79,7 +79,7 @@ struct puc_cfg { int8_t ports; int8_t rid; /* Rid of first port */ int8_t d_rid; /* Delta rid of next ports */ - int8_t d_ofs; /* Delta offset of next ports */ + int16_t d_ofs; /* Delta offset of next ports */ puc_config_f *config_function; }; Modified: user/ae/bootcode/sys/dev/puc/pucdata.c ============================================================================== --- user/ae/bootcode/sys/dev/puc/pucdata.c Thu Jun 21 14:35:46 2012 (r237398) +++ user/ae/bootcode/sys/dev/puc/pucdata.c Thu Jun 21 14:37:05 2012 (r237399) @@ -507,6 +507,18 @@ const struct puc_cfg puc_pci_devices[] = .config_function = puc_config_quatech }, + { 0x1393, 0x1024, 0xffff, 0, + "Moxa Technologies, Smartio CP-102E/PCIe", + DEFAULT_RCLK * 8, + PUC_PORT_2S, 0x14, 0, 0x200 + }, + + { 0x1393, 0x1025, 0xffff, 0, + "Moxa Technologies, Smartio CP-102EL/PCIe", + DEFAULT_RCLK * 8, + PUC_PORT_2S, 0x14, 0, 0x200, + }, + { 0x1393, 0x1040, 0xffff, 0, "Moxa Technologies, Smartio C104H/PCI", DEFAULT_RCLK * 8, @@ -550,6 +562,19 @@ const struct puc_cfg puc_pci_devices[] = PUC_PORT_4S, 0x18, 0, 8, }, + { 0x1393, 0x1144, 0xffff, 0, + "Moxa Technologies, Smartio CP-114EL/PCIe", + DEFAULT_RCLK * 8, + PUC_PORT_4S, 0x14, 0, -1, + .config_function = puc_config_moxa + }, + + { 0x1393, 0x1182, 0xffff, 0, + "Moxa Technologies, Smartio CP-118EL-A/PCIe", + DEFAULT_RCLK * 8, + PUC_PORT_8S, 0x14, 0, 0x200, + }, + { 0x1393, 0x1680, 0xffff, 0, "Moxa Technologies, C168H/PCI", DEFAULT_RCLK * 8, @@ -568,6 +593,12 @@ const struct puc_cfg puc_pci_devices[] = PUC_PORT_8S, 0x18, 0, 8, }, + { 0x1393, 0x1683, 0xffff, 0, + "Moxa Technologies, Smartio CP-168EL-A/PCIe", + DEFAULT_RCLK * 8, + PUC_PORT_8S, 0x14, 0, 0x200, + }, + { 0x13a8, 0x0152, 0xffff, 0, "Exar XR17C/D152", DEFAULT_RCLK * 8, @@ -1127,9 +1158,7 @@ static int puc_config_moxa(struct puc_softc *sc, enum puc_cfg_cmd cmd, int port, intptr_t *res) { - const struct puc_cfg *cfg = sc->sc_cfg; - - if (cmd == PUC_CFG_GET_OFS && cfg->device == 0x1045) { + if (cmd == PUC_CFG_GET_OFS) { *res = ((port == 3) ? 7 : port) * 0x200; return 0; } Modified: user/ae/bootcode/sys/dev/viawd/viawd.c ============================================================================== --- user/ae/bootcode/sys/dev/viawd/viawd.c Thu Jun 21 14:35:46 2012 (r237398) +++ user/ae/bootcode/sys/dev/viawd/viawd.c Thu Jun 21 14:37:05 2012 (r237399) @@ -168,14 +168,18 @@ viawd_attach(device_t dev) } /* Allocate I/O register space. */ - sc->wd_rid = 0; - sc->wd_res = bus_alloc_resource(dev, SYS_RES_MEMORY, &sc->wd_rid, - pmbase, pmbase + VIAWD_MEM_LEN - 1, VIAWD_MEM_LEN, + sc->wd_rid = VIAWD_CONFIG_BASE; + sc->wd_res = bus_alloc_resource_any(sb_dev, SYS_RES_MEMORY, &sc->wd_rid, RF_ACTIVE | RF_SHAREABLE); if (sc->wd_res == NULL) { device_printf(dev, "Unable to map watchdog memory\n"); goto fail; } + if (rman_get_size(sc->wd_res) < VIAWD_MEM_LEN) { + device_printf(dev, "Bad size for watchdog memory: %#x\n", + (unsigned)rman_get_size(sc->wd_res)); + goto fail; + } /* Check if watchdog fired last boot. */ reg = viawd_read_4(sc, VIAWD_MEM_CTRL); @@ -192,7 +196,7 @@ viawd_attach(device_t dev) return (0); fail: if (sc->wd_res != NULL) - bus_release_resource(dev, SYS_RES_MEMORY, + bus_release_resource(sb_dev, SYS_RES_MEMORY, sc->wd_rid, sc->wd_res); return (ENXIO); } @@ -224,7 +228,7 @@ viawd_detach(device_t dev) } if (sc->wd_res != NULL) - bus_release_resource(sc->dev, SYS_RES_MEMORY, + bus_release_resource(sc->sb_dev, SYS_RES_MEMORY, sc->wd_rid, sc->wd_res); return (0); Modified: user/ae/bootcode/sys/dev/xen/balloon/balloon.c ============================================================================== --- user/ae/bootcode/sys/dev/xen/balloon/balloon.c Thu Jun 21 14:35:46 2012 (r237398) +++ user/ae/bootcode/sys/dev/xen/balloon/balloon.c Thu Jun 21 14:37:05 2012 (r237399) @@ -436,6 +436,9 @@ balloon_init_watcher(void *arg) { int err; + if (!is_running_on_xen()) + return; + err = xs_register_watch(&target_watch); if (err) printf("Failed to set balloon watcher\n"); Modified: user/ae/bootcode/sys/fs/nfsclient/nfs_clbio.c ============================================================================== --- user/ae/bootcode/sys/fs/nfsclient/nfs_clbio.c Thu Jun 21 14:35:46 2012 (r237398) +++ user/ae/bootcode/sys/fs/nfsclient/nfs_clbio.c Thu Jun 21 14:37:05 2012 (r237399) @@ -722,7 +722,7 @@ ncl_bioread(struct vnode *vp, struct uio }; if (n > 0) { - error = uiomove(bp->b_data + on, (int)n, uio); + error = vn_io_fault_uiomove(bp->b_data + on, (int)n, uio); } if (vp->v_type == VLNK) n = 0; @@ -1203,7 +1203,7 @@ again: } local_resid = uio->uio_resid; - error = uiomove((char *)bp->b_data + on, n, uio); + error = vn_io_fault_uiomove((char *)bp->b_data + on, n, uio); if (error != 0 && !bp_cached) { /* Modified: user/ae/bootcode/sys/fs/nfsclient/nfs_clvfsops.c ============================================================================== --- user/ae/bootcode/sys/fs/nfsclient/nfs_clvfsops.c Thu Jun 21 14:35:46 2012 (r237398) +++ user/ae/bootcode/sys/fs/nfsclient/nfs_clvfsops.c Thu Jun 21 14:37:05 2012 (r237399) @@ -1136,7 +1136,8 @@ nfs_mount(struct mount *mp) out: if (!error) { MNT_ILOCK(mp); - mp->mnt_kern_flag |= (MNTK_MPSAFE|MNTK_LOOKUP_SHARED); + mp->mnt_kern_flag |= MNTK_MPSAFE | MNTK_LOOKUP_SHARED | + MNTK_NO_IOPF; MNT_IUNLOCK(mp); } return (error); Modified: user/ae/bootcode/sys/kern/vfs_vnops.c ============================================================================== --- user/ae/bootcode/sys/kern/vfs_vnops.c Thu Jun 21 14:35:46 2012 (r237398) *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***