Module Name: src
Committed By: ad
Date: Sun Jan 12 18:37:10 UTC 2020
Modified Files:
src/sys/kern: kern_rwlock.c vfs_vnops.c
src/sys/sys: lwp.h
Log Message:
- Shuffle some items around in struct lwp to save space. Remove an unused
item or two.
- For lockstat, get a useful callsite for vnode locks (caller to vn_lock()).
To generate a diff of this commit:
cvs rdiff -u -r1.59 -r1.60 src/sys/kern/kern_rwlock.c
cvs rdiff -u -r1.204 -r1.205 src/sys/kern/vfs_vnops.c
cvs rdiff -u -r1.193 -r1.194 src/sys/sys/lwp.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/kern/kern_rwlock.c
diff -u src/sys/kern/kern_rwlock.c:1.59 src/sys/kern/kern_rwlock.c:1.60
--- src/sys/kern/kern_rwlock.c:1.59 Mon Dec 9 21:02:10 2019
+++ src/sys/kern/kern_rwlock.c Sun Jan 12 18:37:10 2020
@@ -1,7 +1,8 @@
-/* $NetBSD: kern_rwlock.c,v 1.59 2019/12/09 21:02:10 ad Exp $ */
+/* $NetBSD: kern_rwlock.c,v 1.60 2020/01/12 18:37:10 ad Exp $ */
/*-
- * Copyright (c) 2002, 2006, 2007, 2008, 2009, 2019 The NetBSD Foundation, Inc.
+ * Copyright (c) 2002, 2006, 2007, 2008, 2009, 2019, 2020
+ * The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
@@ -38,7 +39,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_rwlock.c,v 1.59 2019/12/09 21:02:10 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_rwlock.c,v 1.60 2020/01/12 18:37:10 ad Exp $");
#define __RWLOCK_PRIVATE
@@ -420,9 +421,13 @@ rw_vector_enter(krwlock_t *rw, const krw
}
KPREEMPT_ENABLE(curlwp);
- LOCKSTAT_EVENT(lsflag, rw, LB_RWLOCK |
- (op == RW_WRITER ? LB_SLEEP1 : LB_SLEEP2), slpcnt, slptime);
- LOCKSTAT_EVENT(lsflag, rw, LB_RWLOCK | LB_SPIN, spincnt, spintime);
+ LOCKSTAT_EVENT_RA(lsflag, rw, LB_RWLOCK |
+ (op == RW_WRITER ? LB_SLEEP1 : LB_SLEEP2), slpcnt, slptime,
+ (l->l_rwcallsite != 0 ? l->l_rwcallsite :
+ (uintptr_t)__builtin_return_address(0)));
+ LOCKSTAT_EVENT_RA(lsflag, rw, LB_RWLOCK | LB_SPIN, spincnt, spintime,
+ (l->l_rwcallsite != 0 ? l->l_rwcallsite :
+ (uintptr_t)__builtin_return_address(0)));
LOCKSTAT_EXIT(lsflag);
RW_DASSERT(rw, (op != RW_READER && RW_OWNER(rw) == curthread) ||
Index: src/sys/kern/vfs_vnops.c
diff -u src/sys/kern/vfs_vnops.c:1.204 src/sys/kern/vfs_vnops.c:1.205
--- src/sys/kern/vfs_vnops.c:1.204 Mon Dec 16 22:47:54 2019
+++ src/sys/kern/vfs_vnops.c Sun Jan 12 18:37:10 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: vfs_vnops.c,v 1.204 2019/12/16 22:47:54 ad Exp $ */
+/* $NetBSD: vfs_vnops.c,v 1.205 2020/01/12 18:37:10 ad Exp $ */
/*-
* Copyright (c) 2009 The NetBSD Foundation, Inc.
@@ -66,7 +66,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vfs_vnops.c,v 1.204 2019/12/16 22:47:54 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vfs_vnops.c,v 1.205 2020/01/12 18:37:10 ad Exp $");
#include "veriexec.h"
@@ -1030,6 +1030,7 @@ vn_mmap(struct file *fp, off_t *offp, si
int
vn_lock(struct vnode *vp, int flags)
{
+ struct lwp *l;
int error;
#if 0
@@ -1044,10 +1045,17 @@ vn_lock(struct vnode *vp, int flags)
WAPBL_JUNLOCK_ASSERT(wapbl_vptomp(vp));
#endif
+ /* Get a more useful report for lockstat. */
+ l = curlwp;
+ KASSERT(l->l_rwcallsite == 0);
+ l->l_rwcallsite = (uintptr_t)__builtin_return_address(0);
+
error = VOP_LOCK(vp, flags);
if ((flags & LK_RETRY) != 0 && error == ENOENT)
error = VOP_LOCK(vp, flags);
+ l->l_rwcallsite = 0;
+
KASSERT((flags & LK_RETRY) == 0 || (flags & LK_NOWAIT) != 0 ||
error == 0);
Index: src/sys/sys/lwp.h
diff -u src/sys/sys/lwp.h:1.193 src/sys/sys/lwp.h:1.194
--- src/sys/sys/lwp.h:1.193 Wed Jan 8 17:38:43 2020
+++ src/sys/sys/lwp.h Sun Jan 12 18:37:10 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: lwp.h,v 1.193 2020/01/08 17:38:43 ad Exp $ */
+/* $NetBSD: lwp.h,v 1.194 2020/01/12 18:37:10 ad Exp $ */
/*
* Copyright (c) 2001, 2006, 2007, 2008, 2009, 2010, 2019
@@ -92,17 +92,17 @@ struct lwp {
kmutex_t * volatile l_mutex; /* l: ptr to mutex on sched state */
void *l_addr; /* l: PCB address; use lwp_getpcb() */
struct mdlwp l_md; /* l: machine-dependent fields. */
- int l_flag; /* l: misc flag values */
- int l_stat; /* l: overall LWP status */
struct bintime l_rtime; /* l: real time */
struct bintime l_stime; /* l: start time (while ONPROC) */
+ int l_flag; /* l: misc flag values */
u_int l_swtime; /* l: time swapped in or out */
u_int l_rticks; /* l: Saved start time of run */
u_int l_rticksum; /* l: Sum of ticks spent running */
u_int l_slpticks; /* l: Saved start time of sleep */
u_int l_slpticksum; /* l: Sum of ticks spent sleeping */
int l_biglocks; /* l: biglock count before sleep */
- int l_class; /* l: scheduling class */
+ short l_stat; /* l: overall LWP status */
+ short l_class; /* l: scheduling class */
int l_kpriority; /* !: has kernel priority boost */
pri_t l_kpribase; /* !: kernel priority base level */
pri_t l_priority; /* l: scheduler priority */
@@ -110,13 +110,13 @@ struct lwp {
pri_t l_protectprio; /* l: for PTHREAD_PRIO_PROTECT */
pri_t l_auxprio; /* l: max(inherit,protect) priority */
int l_protectdepth; /* l: for PTHREAD_PRIO_PROTECT */
- SLIST_HEAD(, turnstile) l_pi_lenders; /* l: ts lending us priority */
- volatile uint64_t l_ncsw; /* l: total context switches */
- volatile uint64_t l_nivcsw; /* l: involuntary context switches */
u_int l_cpticks; /* (: Ticks of CPU time */
+ psetid_t l_psid; /* l: assigned processor-set ID */
fixpt_t l_pctcpu; /* p: %cpu during l_swtime */
fixpt_t l_estcpu; /* l: cpu time for SCHED_4BSD */
- psetid_t l_psid; /* l: assigned processor-set ID */
+ volatile uint64_t l_ncsw; /* l: total context switches */
+ volatile uint64_t l_nivcsw; /* l: involuntary context switches */
+ SLIST_HEAD(, turnstile) l_pi_lenders; /* l: ts lending us priority */
struct cpu_info *l_target_cpu; /* l: target CPU to migrate */
struct lwpctl *l_lwpctl; /* p: lwpctl block kernel address */
struct lcpage *l_lcpage; /* p: lwpctl containing page */
@@ -129,11 +129,9 @@ struct lwp {
wchan_t l_wchan; /* l: sleep address */
const char *l_wmesg; /* l: reason for sleep */
struct sleepq *l_sleepq; /* l: current sleep queue */
- int l_sleeperr; /* !: error before unblock */
- u_int l_slptime; /* l: time since last blocked */
callout_t l_timeout_ch; /* !: callout for tsleep */
- u_int l_emap_gen; /* !: emap generation number */
kcondvar_t l_waitcv; /* a: vfork() wait */
+ u_int l_slptime; /* l: time since last blocked */
bool l_vforkwaiting; /* a: vfork() waiting */
#if PCU_UNIT_COUNT > 0
@@ -142,21 +140,21 @@ struct lwp {
#endif
/* Process level and global state, misc. */
+ lwpid_t l_lid; /* (: LWP identifier; local to proc */
LIST_ENTRY(lwp) l_list; /* a: entry on list of all LWPs */
void *l_ctxlink; /* p: uc_link {get,set}context */
struct proc *l_proc; /* p: parent process */
LIST_ENTRY(lwp) l_sibling; /* p: entry on proc's list of LWPs */
+ char *l_name; /* (: name, optional */
lwpid_t l_waiter; /* p: first LWP waiting on us */
lwpid_t l_waitingfor; /* p: specific LWP we are waiting on */
int l_prflag; /* p: process level flags */
u_int l_refcnt; /* p: reference count on this LWP */
- lwpid_t l_lid; /* (: LWP identifier; local to proc */
- char *l_name; /* (: name, optional */
/* State of select() or poll(). */
int l_selflag; /* S: polling state flags */
- SLIST_HEAD(,selinfo) l_selwait; /* S: descriptors waited on */
int l_selret; /* S: return value of select/poll */
+ SLIST_HEAD(,selinfo) l_selwait; /* S: descriptors waited on */
uintptr_t l_selrec; /* !: argument for selrecord() */
struct selcluster *l_selcluster;/* !: associated cluster data */
void * l_selbits; /* (: select() bit-field */
@@ -184,7 +182,6 @@ struct lwp {
struct filedesc *l_fd; /* !: cached copy of proc::p_fd */
void *l_emuldata; /* !: kernel lwp-private data */
struct fstrans_lwp_info *l_fstrans; /* (: fstrans private data */
- u_int l_cv_signalled; /* c: restarted by cv_signal() */
u_short l_shlocks; /* !: lockdebug: shared locks held */
u_short l_exlocks; /* !: lockdebug: excl. locks held */
u_short l_psrefs; /* !: count of psref held */
@@ -199,6 +196,7 @@ struct lwp {
uintptr_t l_pfailaddr; /* !: for kernel preemption */
uintptr_t l_pfaillock; /* !: for kernel preemption */
_TAILQ_HEAD(,struct lockdebug,volatile) l_ld_locks;/* !: locks held by LWP */
+ uintptr_t l_rwcallsite; /* !: rwlock actual callsite */
int l_tcgen; /* !: for timecounter removal */
/* These are only used by 'options SYSCALL_TIMES'. */