In hwpmc, do not double-close the logging file.
hwpmc(4) must not voluntarily call fo_close(), doing this causes double-close of the file. It seems to almost avoid bad consequences for pipes, but other types of files demonstrate random memory access. To fix, remove fo_close() calls, which also do not provide the declared wake-up of waiters consistently. Instead, send a signal to the logger and configure the logger process to not block it. Since logger never returns to userspace, the signal only causes termination of the interruptible sleeps in fo_write(). Reported and tested by: pho Reviewed by: markj Sponsored by: The FreeBSD Foundation MFC after: 1 week X-Differential revision: https://reviews.freebsd.org/D12882
This commit is contained in:
parent
bd63e82975
commit
ea4d25f90b
@ -49,6 +49,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/pmclog.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/signalvar.h>
|
||||
#include <sys/syscallsubr.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/uio.h>
|
||||
@ -250,6 +251,7 @@ pmclog_loop(void *arg)
|
||||
struct ucred *ownercred;
|
||||
struct ucred *mycred;
|
||||
struct thread *td;
|
||||
sigset_t unb;
|
||||
struct uio auio;
|
||||
struct iovec aiov;
|
||||
size_t nbytes;
|
||||
@ -257,6 +259,11 @@ pmclog_loop(void *arg)
|
||||
po = (struct pmc_owner *) arg;
|
||||
p = po->po_owner;
|
||||
td = curthread;
|
||||
|
||||
SIGEMPTYSET(unb);
|
||||
SIGADDSET(unb, SIGHUP);
|
||||
(void)kern_sigprocmask(td, SIG_UNBLOCK, &unb, NULL, 0);
|
||||
|
||||
mycred = td->td_ucred;
|
||||
|
||||
PROC_LOCK(p);
|
||||
@ -291,16 +298,8 @@ pmclog_loop(void *arg)
|
||||
mtx_unlock_spin(&po->po_mtx);
|
||||
|
||||
/* No more buffers and shutdown required. */
|
||||
if (po->po_flags & PMC_PO_SHUTDOWN) {
|
||||
mtx_unlock(&pmc_kthread_mtx);
|
||||
/*
|
||||
* Close the file to get PMCLOG_EOF
|
||||
* error in pmclog(3).
|
||||
*/
|
||||
fo_close(po->po_file, curthread);
|
||||
mtx_lock(&pmc_kthread_mtx);
|
||||
if (po->po_flags & PMC_PO_SHUTDOWN)
|
||||
break;
|
||||
}
|
||||
|
||||
(void) msleep(po, &pmc_kthread_mtx, PWAIT,
|
||||
"pmcloop", 0);
|
||||
@ -541,19 +540,16 @@ pmclog_schedule_io(struct pmc_owner *po)
|
||||
static void
|
||||
pmclog_stop_kthread(struct pmc_owner *po)
|
||||
{
|
||||
/*
|
||||
* Close the file to force the thread out of fo_write,
|
||||
* unset flag, wakeup the helper thread,
|
||||
* wait for it to exit
|
||||
*/
|
||||
|
||||
if (po->po_file != NULL)
|
||||
fo_close(po->po_file, curthread);
|
||||
|
||||
mtx_lock(&pmc_kthread_mtx);
|
||||
po->po_flags &= ~PMC_PO_OWNS_LOGFILE;
|
||||
if (po->po_kthread != NULL) {
|
||||
PROC_LOCK(po->po_kthread);
|
||||
kern_psignal(po->po_kthread, SIGHUP);
|
||||
PROC_UNLOCK(po->po_kthread);
|
||||
}
|
||||
wakeup_one(po);
|
||||
if (po->po_kthread)
|
||||
while (po->po_kthread)
|
||||
msleep(po->po_kthread, &pmc_kthread_mtx, PPAUSE, "pmckstp", 0);
|
||||
mtx_unlock(&pmc_kthread_mtx);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user