Author: kib
Date: Wed Nov  1 11:32:52 2017
New Revision: 325275
URL: https://svnweb.freebsd.org/changeset/base/325275

Log:
  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

Modified:
  head/sys/dev/hwpmc/hwpmc_logging.c

Modified: head/sys/dev/hwpmc/hwpmc_logging.c
==============================================================================
--- head/sys/dev/hwpmc/hwpmc_logging.c  Wed Nov  1 11:16:18 2017        
(r325274)
+++ head/sys/dev/hwpmc/hwpmc_logging.c  Wed Nov  1 11:32:52 2017        
(r325275)
@@ -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);
 }
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to