CVS commit: [prg-localcount2] src/sys/kern
Module Name:src Committed By: pgoyette Date: Wed May 17 04:33:03 UTC 2017 Modified Files: src/sys/kern [prg-localcount2]: subr_devsw.c Log Message: Allow the argument to {b,c}devsw_release() to be NULL, and treat it as a No-Op To generate a diff of this commit: cvs rdiff -u -r1.37.2.3 -r1.37.2.4 src/sys/kern/subr_devsw.c 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/subr_devsw.c diff -u src/sys/kern/subr_devsw.c:1.37.2.3 src/sys/kern/subr_devsw.c:1.37.2.4 --- src/sys/kern/subr_devsw.c:1.37.2.3 Fri Apr 28 03:41:26 2017 +++ src/sys/kern/subr_devsw.c Wed May 17 04:33:03 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: subr_devsw.c,v 1.37.2.3 2017/04/28 03:41:26 pgoyette Exp $ */ +/* $NetBSD: subr_devsw.c,v 1.37.2.4 2017/05/17 04:33:03 pgoyette Exp $ */ /*- * Copyright (c) 2001, 2002, 2007, 2008 The NetBSD Foundation, Inc. @@ -69,7 +69,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: subr_devsw.c,v 1.37.2.3 2017/04/28 03:41:26 pgoyette Exp $"); +__KERNEL_RCSID(0, "$NetBSD: subr_devsw.c,v 1.37.2.4 2017/05/17 04:33:03 pgoyette Exp $"); #ifdef _KERNEL_OPT #include "opt_dtrace.h" @@ -505,8 +505,7 @@ void bdevsw_release(const struct bdevsw *bd) { - KASSERT(bd != NULL); - if (bd->d_localcount != NULL) + if (bd != NULL && bd->d_localcount != NULL) localcount_release(bd->d_localcount, _cv, _lock); } @@ -569,8 +568,7 @@ void cdevsw_release(const struct cdevsw *cd) { - KASSERT(cd != NULL); - if (cd->d_localcount != NULL) + if (cd != NULL && cd->d_localcount != NULL) localcount_release(cd->d_localcount, _cv, _lock); }
CVS commit: [prg-localcount2] src/sys/kern
Module Name:src Committed By: pgoyette Date: Wed May 17 01:42:17 UTC 2017 Modified Files: src/sys/kern [prg-localcount2]: kern_event.c Log Message: Import fix from HEAD for NULL deref To generate a diff of this commit: cvs rdiff -u -r1.88.8.2 -r1.88.8.3 src/sys/kern/kern_event.c 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_event.c diff -u src/sys/kern/kern_event.c:1.88.8.2 src/sys/kern/kern_event.c:1.88.8.3 --- src/sys/kern/kern_event.c:1.88.8.2 Thu May 11 02:58:40 2017 +++ src/sys/kern/kern_event.c Wed May 17 01:42:17 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: kern_event.c,v 1.88.8.2 2017/05/11 02:58:40 pgoyette Exp $ */ +/* $NetBSD: kern_event.c,v 1.88.8.3 2017/05/17 01:42:17 pgoyette Exp $ */ /*- * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc. @@ -58,7 +58,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: kern_event.c,v 1.88.8.2 2017/05/11 02:58:40 pgoyette Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_event.c,v 1.88.8.3 2017/05/17 01:42:17 pgoyette Exp $"); #include #include @@ -1020,9 +1020,10 @@ kqueue_register(struct kqueue *kq, struc KERNEL_UNLOCK_ONE(NULL); /* XXXSMP */ if (error != 0) { #ifdef DIAGNOSTIC + printf("%s: event not supported for file type" -" %d (error %d)\n", __func__, -((file_t *)kn->kn_obj)->f_type, error); +" %d (error %d)\n", __func__, kn->kn_obj ? +((file_t *)kn->kn_obj)->f_type : -1, error); #endif /* knote_detach() drops fdp->fd_lock */ knote_detach(kn, fdp, false);
CVS commit: [prg-localcount2] src/sys/kern
Module Name:src Committed By: pgoyette Date: Fri May 12 22:12:23 UTC 2017 Modified Files: src/sys/kern [prg-localcount2]: subr_localcount.c Log Message: When we're draining the localcount's references, transfer the local CPU's reference count to the global total, and then zero it. Any further calls to localcount_release() will adjust only the global counter. Avoids a race condition which depends on having localcount_release() being aware of whether the local CPU's contribution has already been accounted for. Thanks to Kengo NAKAHARA for bringing up the question, and to riastradh@ for the solution. To generate a diff of this commit: cvs rdiff -u -r1.1.6.4 -r1.1.6.5 src/sys/kern/subr_localcount.c 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/subr_localcount.c diff -u src/sys/kern/subr_localcount.c:1.1.6.4 src/sys/kern/subr_localcount.c:1.1.6.5 --- src/sys/kern/subr_localcount.c:1.1.6.4 Thu May 11 21:31:12 2017 +++ src/sys/kern/subr_localcount.c Fri May 12 22:12:23 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: subr_localcount.c,v 1.1.6.4 2017/05/11 21:31:12 pgoyette Exp $ */ +/* $NetBSD: subr_localcount.c,v 1.1.6.5 2017/05/12 22:12:23 pgoyette Exp $ */ /*- * Copyright (c) 2016 The NetBSD Foundation, Inc. @@ -44,7 +44,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: subr_localcount.c,v 1.1.6.4 2017/05/11 21:31:12 pgoyette Exp $"); +__KERNEL_RCSID(0, "$NetBSD: subr_localcount.c,v 1.1.6.5 2017/05/12 22:12:23 pgoyette Exp $"); #include #include @@ -148,6 +148,14 @@ localcount_fini(struct localcount *lc) percpu_free(lc->lc_percpu, sizeof(uint64_t)); } +/* + * localcount_xc(cookie0, cookie1) + * + * Accumulate and transfer the per-CPU reference counts to a + * global total, resetting the per-CPU counter to zero. Once + * localcount_drain() has started, we only maintain the total + * count in localcount_release(). + */ static void localcount_xc(void *cookie0, void *cookie1) { @@ -158,6 +166,7 @@ localcount_xc(void *cookie0, void *cooki mutex_enter(interlock); localp = percpu_getref(lc->lc_percpu); *lc->lc_totalp += *localp; + *localp -= *localp; /* ie, *localp = 0; */ percpu_putref(lc->lc_percpu); mutex_exit(interlock); } @@ -235,9 +244,7 @@ localcount_release(struct localcount *lc * the last reference. */ mutex_enter(interlock); - localcount_adjust(lc, -1); - *lc->lc_totalp -= 1; - if (*lc->lc_totalp == 0) + if (--*lc->lc_totalp == 0) cv_broadcast(cv); mutex_exit(interlock); goto out;
CVS commit: [prg-localcount2] src/sys/kern
Module Name:src Committed By: pgoyette Date: Thu May 11 21:31:12 UTC 2017 Modified Files: src/sys/kern [prg-localcount2]: subr_localcount.c Log Message: Use kpreempt_{dis,en}able() rather than splsoftserial() for blocking the local execution of the low-priority xcall. Thanks to Kengo NAKAHARA for pointing this out. To generate a diff of this commit: cvs rdiff -u -r1.1.6.3 -r1.1.6.4 src/sys/kern/subr_localcount.c 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/subr_localcount.c diff -u src/sys/kern/subr_localcount.c:1.1.6.3 src/sys/kern/subr_localcount.c:1.1.6.4 --- src/sys/kern/subr_localcount.c:1.1.6.3 Tue May 2 03:19:22 2017 +++ src/sys/kern/subr_localcount.c Thu May 11 21:31:12 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: subr_localcount.c,v 1.1.6.3 2017/05/02 03:19:22 pgoyette Exp $ */ +/* $NetBSD: subr_localcount.c,v 1.1.6.4 2017/05/11 21:31:12 pgoyette Exp $ */ /*- * Copyright (c) 2016 The NetBSD Foundation, Inc. @@ -44,7 +44,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: subr_localcount.c,v 1.1.6.3 2017/05/02 03:19:22 pgoyette Exp $"); +__KERNEL_RCSID(0, "$NetBSD: subr_localcount.c,v 1.1.6.4 2017/05/11 21:31:12 pgoyette Exp $"); #include #include @@ -215,7 +215,6 @@ localcount_acquire(struct localcount *lc void localcount_release(struct localcount *lc, kcondvar_t *cv, kmutex_t *interlock) { - int s; /* * Block xcall so that if someone begins draining after we see @@ -227,7 +226,7 @@ localcount_release(struct localcount *lc * lc->lc_totalp as null, this CPU will not wake * localcount_drain. */ - s = splsoftserial(); + kpreempt_disable(); KDASSERT(mutex_ownable(interlock)); if (__predict_false(lc->lc_totalp != NULL)) { @@ -245,5 +244,5 @@ localcount_release(struct localcount *lc } localcount_adjust(lc, -1); -out: splx(s); + out: kpreempt_enable(); }
CVS commit: [prg-localcount2] src/sys/kern
Module Name:src Committed By: pgoyette Date: Sun Apr 30 05:18:53 UTC 2017 Modified Files: src/sys/kern [prg-localcount2]: subr_autoconf.c Log Message: Release the interlock mutex before calling device_release(). Ensure that device_release() gets called even if the (ca->ca_detach)() call fails. To generate a diff of this commit: cvs rdiff -u -r1.252.4.2 -r1.252.4.3 src/sys/kern/subr_autoconf.c 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/subr_autoconf.c diff -u src/sys/kern/subr_autoconf.c:1.252.4.2 src/sys/kern/subr_autoconf.c:1.252.4.3 --- src/sys/kern/subr_autoconf.c:1.252.4.2 Fri Apr 28 06:00:33 2017 +++ src/sys/kern/subr_autoconf.c Sun Apr 30 05:18:53 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: subr_autoconf.c,v 1.252.4.2 2017/04/28 06:00:33 pgoyette Exp $ */ +/* $NetBSD: subr_autoconf.c,v 1.252.4.3 2017/04/30 05:18:53 pgoyette Exp $ */ /* * Copyright (c) 1996, 2000 Christopher G. Demetriou @@ -77,7 +77,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: subr_autoconf.c,v 1.252.4.2 2017/04/28 06:00:33 pgoyette Exp $"); +__KERNEL_RCSID(0, "$NetBSD: subr_autoconf.c,v 1.252.4.3 2017/04/30 05:18:53 pgoyette Exp $"); #ifdef _KERNEL_OPT #include "opt_ddb.h" @@ -1277,9 +1277,13 @@ config_devunlink(device_t dev, struct de /* * Release the reference that was held by (the caller of) - * config_detach_release() + * config_detach_release(). Note that since device_release() + * might need to acquire the alldevs.lock mutex, we need to + * release and then reacquire the mutex. */ + mutex_exit(); device_release(dev); + mutex_enter(); /* Now wait for references to drain - no new refs are possible */ localcount_drain(>dv_localcnt, _drain_cv, @@ -1866,6 +1870,8 @@ out: } } config_alldevs_exit(); + if (rv != 0) + device_release(dev); return rv; }
CVS commit: [prg-localcount2] src/sys/kern
Module Name:src Committed By: pgoyette Date: Fri Apr 28 03:41:26 UTC 2017 Modified Files: src/sys/kern [prg-localcount2]: subr_devsw.c Log Message: Use printf() instead of aprintf_normal(), fix the sense of a comparison To generate a diff of this commit: cvs rdiff -u -r1.37.2.2 -r1.37.2.3 src/sys/kern/subr_devsw.c 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/subr_devsw.c diff -u src/sys/kern/subr_devsw.c:1.37.2.2 src/sys/kern/subr_devsw.c:1.37.2.3 --- src/sys/kern/subr_devsw.c:1.37.2.2 Fri Apr 28 02:36:10 2017 +++ src/sys/kern/subr_devsw.c Fri Apr 28 03:41:26 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: subr_devsw.c,v 1.37.2.2 2017/04/28 02:36:10 pgoyette Exp $ */ +/* $NetBSD: subr_devsw.c,v 1.37.2.3 2017/04/28 03:41:26 pgoyette Exp $ */ /*- * Copyright (c) 2001, 2002, 2007, 2008 The NetBSD Foundation, Inc. @@ -69,7 +69,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: subr_devsw.c,v 1.37.2.2 2017/04/28 02:36:10 pgoyette Exp $"); +__KERNEL_RCSID(0, "$NetBSD: subr_devsw.c,v 1.37.2.3 2017/04/28 03:41:26 pgoyette Exp $"); #ifdef _KERNEL_OPT #include "opt_dtrace.h" @@ -151,19 +151,18 @@ devsw_attach(const char *devname, if (bdev != NULL) { if (bdev->d_localcount == NULL) { - aprint_normal("%s: %s's bdevsw has no localcount", + printf("%s: %s's bdevsw has no localcount", __func__, devname); return EINVAL; } if (bdev->d_localcount == cdev->d_localcount) { - aprint_normal("%s: %s uses same localcount for both " - cdevsw and bdevsw", __func__, devname); + printf("%s: %s uses same localcount for both " + "cdevsw and bdevsw", __func__, devname); return EINVAL; } } - if (cdev != NULL) { - aprint_normal("%s: %s's cdevsw has no localcount", - __func__, devname); + if (cdev == NULL) { + printf("%s: %s's cdevsw has no localcount", __func__, devname); return EINVAL; } @@ -308,8 +307,7 @@ bdevsw_attach(const struct bdevsw *devsw return (EEXIST); if (devsw->d_localcount == NULL) { - aprint_normal("%s: %s's bdevsw has no localcount", - __func__, devname); + printf("%s: bdevsw has no localcount", __func__); return EINVAL; } localcount_init(devsw->d_localcount); @@ -365,8 +363,7 @@ cdevsw_attach(const struct cdevsw *devsw return (EEXIST); if (devsw->d_localcount == NULL) { - aprint_normal("%s: %s's cdevsw has no localcount", - __func__, devname); + printf("%s: cdevsw has no localcount", __func__); return EINVAL; } localcount_init(devsw->d_localcount);
CVS commit: [prg-localcount2] src/sys/kern
Module Name:src Committed By: pgoyette Date: Fri Apr 28 02:36:10 UTC 2017 Modified Files: src/sys/kern [prg-localcount2]: subr_devsw.c Log Message: No need to panic if a modular driver doesn't include the required localcount members in the {b,c}devsw. Just log a console message and return EINVAL to signal failure. To generate a diff of this commit: cvs rdiff -u -r1.37.2.1 -r1.37.2.2 src/sys/kern/subr_devsw.c 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/subr_devsw.c diff -u src/sys/kern/subr_devsw.c:1.37.2.1 src/sys/kern/subr_devsw.c:1.37.2.2 --- src/sys/kern/subr_devsw.c:1.37.2.1 Thu Apr 27 05:36:37 2017 +++ src/sys/kern/subr_devsw.c Fri Apr 28 02:36:10 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: subr_devsw.c,v 1.37.2.1 2017/04/27 05:36:37 pgoyette Exp $ */ +/* $NetBSD: subr_devsw.c,v 1.37.2.2 2017/04/28 02:36:10 pgoyette Exp $ */ /*- * Copyright (c) 2001, 2002, 2007, 2008 The NetBSD Foundation, Inc. @@ -69,7 +69,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: subr_devsw.c,v 1.37.2.1 2017/04/27 05:36:37 pgoyette Exp $"); +__KERNEL_RCSID(0, "$NetBSD: subr_devsw.c,v 1.37.2.2 2017/04/28 02:36:10 pgoyette Exp $"); #ifdef _KERNEL_OPT #include "opt_dtrace.h" @@ -150,15 +150,22 @@ devsw_attach(const char *devname, mutex_enter(_lock); if (bdev != NULL) { - KASSERTMSG(bdev->d_localcount != NULL, - "%s: bdev %s has no d_localcount", __func__, devname); - KASSERTMSG(bdev->d_localcount != cdev->d_localcount, - "%s: bdev and cdev for %s have same d_localcount", + if (bdev->d_localcount == NULL) { + aprint_normal("%s: %s's bdevsw has no localcount", + __func__, devname); + return EINVAL; + } + if (bdev->d_localcount == cdev->d_localcount) { + aprint_normal("%s: %s uses same localcount for both " + cdevsw and bdevsw", __func__, devname); + return EINVAL; + } + } + if (cdev != NULL) { + aprint_normal("%s: %s's cdevsw has no localcount", __func__, devname); + return EINVAL; } - if (cdev != NULL) - KASSERTMSG(cdev->d_localcount != NULL, - "%s: cdev %s has no d_localcount", __func__, devname); for (i = 0 ; i < max_devsw_convs ; i++) { conv = _conv[i]; @@ -300,8 +307,11 @@ bdevsw_attach(const struct bdevsw *devsw if (bdevsw[*devmajor] != NULL) return (EEXIST); - KASSERTMSG(devsw->d_localcount != NULL, "%s: bdev for major %d has " - "no localcount", __func__, *devmajor); + if (devsw->d_localcount == NULL) { + aprint_normal("%s: %s's bdevsw has no localcount", + __func__, devname); + return EINVAL; + } localcount_init(devsw->d_localcount); /* ensure visibility of the bdevsw */ @@ -354,8 +364,11 @@ cdevsw_attach(const struct cdevsw *devsw if (cdevsw[*devmajor] != NULL) return (EEXIST); - KASSERTMSG(devsw->d_localcount != NULL, "%s: cdev for major %d has " - "no localcount", __func__, *devmajor); + if (devsw->d_localcount == NULL) { + aprint_normal("%s: %s's cdevsw has no localcount", + __func__, devname); + return EINVAL; + } localcount_init(devsw->d_localcount); /* ensure visibility of the cdevsw */