From owner-svn-src-all@FreeBSD.ORG Tue Feb 8 00:16:37 2011 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 4E249106564A; Tue, 8 Feb 2011 00:16:37 +0000 (UTC) (envelope-from mdf@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 3ABA28FC1A; Tue, 8 Feb 2011 00:16:37 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id p180Gbsx027254; Tue, 8 Feb 2011 00:16:37 GMT (envelope-from mdf@svn.freebsd.org) Received: (from mdf@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id p180GaFp027241; Tue, 8 Feb 2011 00:16:36 GMT (envelope-from mdf@svn.freebsd.org) Message-Id: <201102080016.p180GaFp027241@svn.freebsd.org> From: Matthew D Fleming Date: Tue, 8 Feb 2011 00:16:36 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r218424 - in head/sys: dev/sio kern pc98/cbus sys ufs/ffs X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 08 Feb 2011 00:16:37 -0000 Author: mdf Date: Tue Feb 8 00:16:36 2011 New Revision: 218424 URL: http://svn.freebsd.org/changeset/base/218424 Log: Based on discussions on the svn-src mailing list, rework r218195: - entirely eliminate some calls to uio_yeild() as being unnecessary, such as in a sysctl handler. - move should_yield() and maybe_yield() to kern_synch.c and move the prototypes from sys/uio.h to sys/proc.h - add a slightly more generic kern_yield() that can replace the functionality of uio_yield(). - replace source uses of uio_yield() with the functional equivalent, or in some cases do not change the thread priority when switching. - fix a logic inversion bug in vlrureclaim(), pointed out by bde@. - instead of using the per-cpu last switched ticks, use a per thread variable for should_yield(). With PREEMPTION, the only reasonable use of this is to determine if a lock has been held a long time and relinquish it. Without PREEMPTION, this is essentially the same as the per-cpu variable. Modified: head/sys/dev/sio/sio.c head/sys/kern/kern_synch.c head/sys/kern/kern_sysctl.c head/sys/kern/subr_uio.c head/sys/kern/vfs_bio.c head/sys/kern/vfs_mount.c head/sys/kern/vfs_subr.c head/sys/kern/vfs_vnops.c head/sys/pc98/cbus/sio.c head/sys/sys/proc.h head/sys/sys/uio.h head/sys/ufs/ffs/ffs_softdep.c Modified: head/sys/dev/sio/sio.c ============================================================================== --- head/sys/dev/sio/sio.c Mon Feb 7 23:00:24 2011 (r218423) +++ head/sys/dev/sio/sio.c Tue Feb 8 00:16:36 2011 (r218424) @@ -1466,7 +1466,6 @@ sysctl_siots(SYSCTL_HANDLER_ARGS) error = SYSCTL_OUT(req, buf, len); if (error != 0) return (error); - uio_yield(); } return (0); } Modified: head/sys/kern/kern_synch.c ============================================================================== --- head/sys/kern/kern_synch.c Mon Feb 7 23:00:24 2011 (r218423) +++ head/sys/kern/kern_synch.c Tue Feb 8 00:16:36 2011 (r218424) @@ -413,9 +413,10 @@ mi_switch(int flags, struct thread *newt */ if (kdb_active) kdb_switch(); - if (flags & SW_VOL) + if (flags & SW_VOL) { td->td_ru.ru_nvcsw++; - else + td->td_swvoltick = ticks; + } else td->td_ru.ru_nivcsw++; #ifdef SCHED_STATS SCHED_STAT_INC(sched_switch_stats[flags & SW_TYPE_MASK]); @@ -538,6 +539,36 @@ synch_setup(void *dummy) loadav(NULL); } +int +should_yield(void) +{ + + return (ticks - curthread->td_swvoltick >= hogticks); +} + +void +maybe_yield(void) +{ + + if (should_yield()) + kern_yield(curthread->td_user_pri); +} + +void +kern_yield(int prio) +{ + struct thread *td; + + td = curthread; + DROP_GIANT(); + thread_lock(td); + if (prio >= 0) + sched_prio(td, prio); + mi_switch(SW_VOL | SWT_RELINQUISH, NULL); + thread_unlock(td); + PICKUP_GIANT(); +} + /* * General purpose yield system call. */ Modified: head/sys/kern/kern_sysctl.c ============================================================================== --- head/sys/kern/kern_sysctl.c Mon Feb 7 23:00:24 2011 (r218423) +++ head/sys/kern/kern_sysctl.c Tue Feb 8 00:16:36 2011 (r218424) @@ -1568,7 +1568,7 @@ userland_sysctl(struct thread *td, int * SYSCTL_XUNLOCK(); if (error != EAGAIN) break; - uio_yield(); + kern_yield(curthread->td_user_pri); } CURVNET_RESTORE(); Modified: head/sys/kern/subr_uio.c ============================================================================== --- head/sys/kern/subr_uio.c Mon Feb 7 23:00:24 2011 (r218423) +++ head/sys/kern/subr_uio.c Tue Feb 8 00:16:36 2011 (r218424) @@ -352,33 +352,11 @@ again: return (0); } -int -should_yield(void) -{ - - return (ticks - PCPU_GET(switchticks) >= hogticks); -} - -void -maybe_yield(void) -{ - - if (should_yield()) - uio_yield(); -} - void uio_yield(void) { - struct thread *td; - td = curthread; - DROP_GIANT(); - thread_lock(td); - sched_prio(td, td->td_user_pri); - mi_switch(SW_INVOL | SWT_RELINQUISH, NULL); - thread_unlock(td); - PICKUP_GIANT(); + kern_yield(curthread->td_user_pri); } int Modified: head/sys/kern/vfs_bio.c ============================================================================== --- head/sys/kern/vfs_bio.c Mon Feb 7 23:00:24 2011 (r218423) +++ head/sys/kern/vfs_bio.c Tue Feb 8 00:16:36 2011 (r218424) @@ -2234,7 +2234,7 @@ buf_daemon() while (numdirtybuffers > lodirtybuffers) { if (buf_do_flush(NULL) == 0) break; - uio_yield(); + kern_yield(-1); } lodirtybuffers = lodirtysave; Modified: head/sys/kern/vfs_mount.c ============================================================================== --- head/sys/kern/vfs_mount.c Mon Feb 7 23:00:24 2011 (r218423) +++ head/sys/kern/vfs_mount.c Tue Feb 8 00:16:36 2011 (r218424) @@ -1661,7 +1661,7 @@ __mnt_vnode_next(struct vnode **mvp, str KASSERT((*mvp)->v_mount == mp, ("marker vnode mount list mismatch")); if (should_yield()) { MNT_IUNLOCK(mp); - uio_yield(); + kern_yield(-1); MNT_ILOCK(mp); } vp = TAILQ_NEXT(*mvp, v_nmntvnodes); Modified: head/sys/kern/vfs_subr.c ============================================================================== --- head/sys/kern/vfs_subr.c Mon Feb 7 23:00:24 2011 (r218423) +++ head/sys/kern/vfs_subr.c Tue Feb 8 00:16:36 2011 (r218424) @@ -707,15 +707,15 @@ vlrureclaim(struct mount *mp) vdropl(vp); done++; next_iter_mntunlocked: - if (should_yield()) + if (!should_yield()) goto relock_mnt; goto yield; next_iter: - if (should_yield()) + if (!should_yield()) continue; MNT_IUNLOCK(mp); yield: - uio_yield(); + kern_yield(-1); relock_mnt: MNT_ILOCK(mp); } @@ -828,7 +828,7 @@ vnlru_proc(void) vnlru_nowhere++; tsleep(vnlruproc, PPAUSE, "vlrup", hz * 3); } else - uio_yield(); + kern_yield(-1); } } Modified: head/sys/kern/vfs_vnops.c ============================================================================== --- head/sys/kern/vfs_vnops.c Mon Feb 7 23:00:24 2011 (r218423) +++ head/sys/kern/vfs_vnops.c Tue Feb 8 00:16:36 2011 (r218424) @@ -444,7 +444,7 @@ vn_rdwr(rw, vp, base, len, offset, segfl * Package up an I/O request on a vnode into a uio and do it. The I/O * request is split up into smaller chunks and we try to avoid saturating * the buffer cache while potentially holding a vnode locked, so we - * check bwillwrite() before calling vn_rdwr(). We also call uio_yield() + * check bwillwrite() before calling vn_rdwr(). We also call kern_yield() * to give other processes a chance to lock the vnode (either other processes * core'ing the same binary, or unrelated processes scanning the directory). */ @@ -491,7 +491,7 @@ vn_rdwr_inchunks(rw, vp, base, len, offs break; offset += chunk; base = (char *)base + chunk; - uio_yield(); + kern_yield(curthread->td_user_pri); } while (len); if (aresid) *aresid = len + iaresid; Modified: head/sys/pc98/cbus/sio.c ============================================================================== --- head/sys/pc98/cbus/sio.c Mon Feb 7 23:00:24 2011 (r218423) +++ head/sys/pc98/cbus/sio.c Tue Feb 8 00:16:36 2011 (r218424) @@ -2250,7 +2250,6 @@ sysctl_siots(SYSCTL_HANDLER_ARGS) error = SYSCTL_OUT(req, buf, len); if (error != 0) return (error); - uio_yield(); } return (0); } Modified: head/sys/sys/proc.h ============================================================================== --- head/sys/sys/proc.h Mon Feb 7 23:00:24 2011 (r218423) +++ head/sys/sys/proc.h Tue Feb 8 00:16:36 2011 (r218424) @@ -242,6 +242,7 @@ struct thread { 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. */ struct rusage td_ru; /* (t) rusage information. */ struct rusage_ext td_rux; /* (t) Internal rusage information. */ uint64_t td_incruntime; /* (t) Cpu ticks to transfer to proc. */ @@ -822,9 +823,11 @@ void fork_exit(void (*)(void *, struct t struct trapframe *); void fork_return(struct thread *, struct trapframe *); int inferior(struct proc *p); +void kern_yield(int); void kick_proc0(void); int leavepgrp(struct proc *p); int maybe_preempt(struct thread *td); +void maybe_yield(void); void mi_switch(int flags, struct thread *newtd); int p_candebug(struct thread *td, struct proc *p); int p_cansee(struct thread *td, struct proc *p); @@ -847,6 +850,7 @@ void sess_hold(struct session *); void sess_release(struct session *); 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); Modified: head/sys/sys/uio.h ============================================================================== --- head/sys/sys/uio.h Mon Feb 7 23:00:24 2011 (r218423) +++ head/sys/sys/uio.h Tue Feb 8 00:16:36 2011 (r218424) @@ -95,8 +95,6 @@ int copyinstrfrom(const void * __restric size_t len, size_t * __restrict copied, int seg); int copyinuio(struct iovec *iovp, u_int iovcnt, struct uio **uiop); void uio_yield(void); -void maybe_yield(void); -int should_yield(void); int uiomove(void *cp, int n, struct uio *uio); int uiomove_frombuf(void *buf, int buflen, struct uio *uio); int uiomove_fromphys(struct vm_page *ma[], vm_offset_t offset, int n, Modified: head/sys/ufs/ffs/ffs_softdep.c ============================================================================== --- head/sys/ufs/ffs/ffs_softdep.c Mon Feb 7 23:00:24 2011 (r218423) +++ head/sys/ufs/ffs/ffs_softdep.c Tue Feb 8 00:16:36 2011 (r218424) @@ -1380,7 +1380,7 @@ softdep_process_worklist(mp, full) */ if (should_yield()) { FREE_LOCK(&lk); - uio_yield(); + kern_yield(-1); bwillwrite(); ACQUIRE_LOCK(&lk); }