Module Name: src Committed By: dholland Date: Mon Aug 28 04:57:11 UTC 2017
Modified Files: src/sys/kern: kern_ktrace.c Log Message: If we go to allocate and find someone else has at the same time, don't trigger a refcount leak of the other guy's object. From mjg@freebsd. While here also remove a bogus use of lbolt on the same path. To generate a diff of this commit: cvs rdiff -u -r1.171 -r1.172 src/sys/kern/kern_ktrace.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_ktrace.c diff -u src/sys/kern/kern_ktrace.c:1.171 src/sys/kern/kern_ktrace.c:1.172 --- src/sys/kern/kern_ktrace.c:1.171 Fri Jul 28 15:16:39 2017 +++ src/sys/kern/kern_ktrace.c Mon Aug 28 04:57:11 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: kern_ktrace.c,v 1.171 2017/07/28 15:16:39 riastradh Exp $ */ +/* $NetBSD: kern_ktrace.c,v 1.172 2017/08/28 04:57:11 dholland Exp $ */ /*- * Copyright (c) 2006, 2007, 2008 The NetBSD Foundation, Inc. @@ -61,7 +61,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: kern_ktrace.c,v 1.171 2017/07/28 15:16:39 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_ktrace.c,v 1.172 2017/08/28 04:57:11 dholland Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -985,7 +985,7 @@ ktrace_common(lwp_t *curl, int ops, int { struct proc *p; struct pgrp *pg; - struct ktr_desc *ktd = NULL; + struct ktr_desc *ktd = NULL, *nktd; file_t *fp = *fpp; int ret = 0; int error = 0; @@ -1015,22 +1015,22 @@ ktrace_common(lwp_t *curl, int ops, int ktd = ktd_lookup(fp); mutex_exit(&ktrace_lock); if (ktd == NULL) { - ktd = kmem_alloc(sizeof(*ktd), KM_SLEEP); - TAILQ_INIT(&ktd->ktd_queue); - callout_init(&ktd->ktd_wakch, CALLOUT_MPSAFE); - cv_init(&ktd->ktd_cv, "ktrwait"); - cv_init(&ktd->ktd_sync_cv, "ktrsync"); - ktd->ktd_flags = 0; - ktd->ktd_qcount = 0; - ktd->ktd_error = 0; - ktd->ktd_errcnt = 0; - ktd->ktd_delayqcnt = ktd_delayqcnt; - ktd->ktd_wakedelay = mstohz(ktd_wakedelay); - ktd->ktd_intrwakdl = mstohz(ktd_intrwakdl); - ktd->ktd_ref = 0; - ktd->ktd_fp = fp; + nktd = kmem_alloc(sizeof(*nktd), KM_SLEEP); + TAILQ_INIT(&nktd->ktd_queue); + callout_init(&nktd->ktd_wakch, CALLOUT_MPSAFE); + cv_init(&nktd->ktd_cv, "ktrwait"); + cv_init(&nktd->ktd_sync_cv, "ktrsync"); + nktd->ktd_flags = 0; + nktd->ktd_qcount = 0; + nktd->ktd_error = 0; + nktd->ktd_errcnt = 0; + nktd->ktd_delayqcnt = ktd_delayqcnt; + nktd->ktd_wakedelay = mstohz(ktd_wakedelay); + nktd->ktd_intrwakdl = mstohz(ktd_intrwakdl); + nktd->ktd_ref = 0; + nktd->ktd_fp = fp; mutex_enter(&ktrace_lock); - ktdref(ktd); + ktdref(nktd); mutex_exit(&ktrace_lock); /* @@ -1038,16 +1038,16 @@ ktrace_common(lwp_t *curl, int ops, int * whether ktruss or ktrace. */ if (fp->f_type == DTYPE_PIPE) - ktd->ktd_flags |= KTDF_INTERACTIVE; + nktd->ktd_flags |= KTDF_INTERACTIVE; mutex_enter(&fp->f_lock); fp->f_count++; mutex_exit(&fp->f_lock); error = kthread_create(PRI_NONE, KTHREAD_MPSAFE, NULL, - ktrace_thread, ktd, &ktd->ktd_lwp, "ktrace"); + ktrace_thread, nktd, &nktd->ktd_lwp, "ktrace"); if (error != 0) { - kmem_free(ktd, sizeof(*ktd)); - ktd = NULL; + kmem_free(nktd, sizeof(*nktd)); + nktd = NULL; mutex_enter(&fp->f_lock); fp->f_count--; mutex_exit(&fp->f_lock); @@ -1055,16 +1055,15 @@ ktrace_common(lwp_t *curl, int ops, int } mutex_enter(&ktrace_lock); - if (ktd_lookup(fp) != NULL) { - ktdrel(ktd); - ktd = NULL; - } else - TAILQ_INSERT_TAIL(&ktdq, ktd, ktd_list); - if (ktd == NULL) - cv_wait(&lbolt, &ktrace_lock); + ktd = ktd_lookup(fp); + if (ktd != NULL) { + ktdrel(nktd); + nktd = NULL; + } else { + TAILQ_INSERT_TAIL(&ktdq, nktd, ktd_list); + ktd = nktd; + } mutex_exit(&ktrace_lock); - if (ktd == NULL) - goto done; } break;