Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F106975960
D12882.id34570.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
9 KB
Referenced Files
None
Subscribers
None
D12882.id34570.diff
View Options
Index: sys/dev/hwpmc/hwpmc_logging.c
===================================================================
--- sys/dev/hwpmc/hwpmc_logging.c
+++ sys/dev/hwpmc/hwpmc_logging.c
@@ -49,6 +49,7 @@
#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>
@@ -234,6 +235,54 @@
return (plb ? 0 : ENOMEM);
}
+struct pmclog_proc_init_args {
+ struct proc *kthr;
+ struct pmc_owner *po;
+ bool exit;
+ bool acted;
+};
+
+int
+pmclog_proc_create(struct thread *td, void **handlep)
+{
+ struct pmclog_proc_init_args *ia;
+ int error;
+
+ ia = malloc(sizeof(*ia), M_TEMP, M_WAITOK | M_ZERO);
+ error = kproc_create(pmclog_loop, ia, &ia->kthr,
+ RFHIGHPID, 0, "hwpmc: proc(%d)", td->td_proc->p_pid);
+ if (error == 0)
+ *handlep = ia;
+ return (error);
+}
+
+void
+pmclog_proc_ignite(void *handle, struct pmc_owner *po)
+{
+ struct pmclog_proc_init_args *ia;
+
+ ia = handle;
+ mtx_lock(&pmc_kthread_mtx);
+ MPASS(!ia->acted);
+ MPASS(ia->po == NULL);
+ MPASS(!ia->exit);
+ MPASS(ia->kthr != NULL);
+ if (po == NULL) {
+ ia->exit = true;
+ } else {
+ ia->po = po;
+ KASSERT(po->po_kthread == NULL,
+ ("[pmclog,%d] po=%p kthread (%p) already present",
+ __LINE__, po, po->po_kthread));
+ po->po_kthread = ia->kthr;
+ }
+ wakeup(ia);
+ while (!ia->acted)
+ msleep(ia, &pmc_kthread_mtx, PWAIT, "pmclogw", 0);
+ mtx_unlock(&pmc_kthread_mtx);
+ free(ia, M_TEMP);
+}
+
/*
* Log handler loop.
*
@@ -243,20 +292,45 @@
static void
pmclog_loop(void *arg)
{
- int error;
+ struct pmclog_proc_init_args *ia;
struct pmc_owner *po;
struct pmclog_buffer *lb;
struct proc *p;
struct ucred *ownercred;
struct ucred *mycred;
struct thread *td;
+ sigset_t unb;
struct uio auio;
struct iovec aiov;
size_t nbytes;
+ int error;
- 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);
+
+ ia = arg;
+ MPASS(ia->kthr == curproc);
+ MPASS(!ia->acted);
+ mtx_lock(&pmc_kthread_mtx);
+ while (ia->po == NULL && !ia->exit)
+ msleep(ia, &pmc_kthread_mtx, PWAIT, "pmclogi", 0);
+ if (ia->exit) {
+ ia->acted = true;
+ wakeup(ia);
+ mtx_unlock(&pmc_kthread_mtx);
+ kproc_exit(0);
+ }
+ MPASS(ia->po != NULL);
+ po = ia->po;
+ ia->acted = true;
+ wakeup(ia);
+ mtx_unlock(&pmc_kthread_mtx);
+ ia = NULL;
+
+ p = po->po_owner;
mycred = td->td_ucred;
PROC_LOCK(p);
@@ -291,16 +365,8 @@
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 +607,16 @@
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 != NULL)
msleep(po->po_kthread, &pmc_kthread_mtx, PPAUSE, "pmckstp", 0);
mtx_unlock(&pmc_kthread_mtx);
}
@@ -572,15 +635,11 @@
int
pmclog_configure_log(struct pmc_mdep *md, struct pmc_owner *po, int logfd)
{
- int error;
struct proc *p;
cap_rights_t rights;
- /*
- * As long as it is possible to get a LOR between pmc_sx lock and
- * proctree/allproc sx locks used for adding a new process, assure
- * the former is not held here.
- */
- sx_assert(&pmc_sx, SA_UNLOCKED);
+ int error;
+
+ sx_assert(&pmc_sx, SA_XLOCKED);
PMCDBG2(LOG,CFG,1, "config po=%p logfd=%d", po, logfd);
p = po->po_owner;
@@ -589,9 +648,6 @@
if (po->po_flags & PMC_PO_OWNS_LOGFILE)
return (EBUSY);
- KASSERT(po->po_kthread == NULL,
- ("[pmclog,%d] po=%p kthread (%p) already present", __LINE__, po,
- po->po_kthread));
KASSERT(po->po_file == NULL,
("[pmclog,%d] po=%p file (%p) already present", __LINE__, po,
po->po_file));
@@ -604,10 +660,6 @@
/* mark process as owning a log file */
po->po_flags |= PMC_PO_OWNS_LOGFILE;
- error = kproc_create(pmclog_loop, po, &po->po_kthread,
- RFHIGHPID, 0, "hwpmc: proc(%d)", p->p_pid);
- if (error)
- goto error;
/* mark process as using HWPMCs */
PROC_LOCK(p);
@@ -624,10 +676,6 @@
return (0);
error:
- /* shutdown the thread */
- if (po->po_kthread)
- pmclog_stop_kthread(po);
-
KASSERT(po->po_kthread == NULL, ("[pmclog,%d] po=%p kthread not "
"stopped", __LINE__, po));
@@ -685,8 +733,11 @@
}
/* drop a reference to the fd */
- error = fdrop(po->po_file, curthread);
- po->po_file = NULL;
+ if (po->po_file != NULL) {
+ error = fdrop(po->po_file, curthread);
+ po->po_file = NULL;
+ } else
+ error = 0;
po->po_error = 0;
return (error);
Index: sys/dev/hwpmc/hwpmc_mod.c
===================================================================
--- sys/dev/hwpmc/hwpmc_mod.c
+++ sys/dev/hwpmc/hwpmc_mod.c
@@ -311,27 +311,23 @@
/* The `sysent' for the new syscall */
static struct sysent pmc_sysent = {
- 2, /* sy_narg */
- pmc_syscall_handler /* sy_call */
+ .sy_narg = 2,
+ .sy_call = pmc_syscall_handler,
};
static struct syscall_module_data pmc_syscall_mod = {
- load,
- NULL,
- &pmc_syscall_num,
- &pmc_sysent,
-#if (__FreeBSD_version >= 1100000)
- { 0, NULL },
- SY_THR_STATIC_KLD,
-#else
- { 0, NULL }
-#endif
+ .chainevh = load,
+ .chainarg = NULL,
+ .offset = &pmc_syscall_num,
+ .new_sysent = &pmc_sysent,
+ .old_sysent = { .sy_narg = 0, .sy_call = NULL },
+ .flags = SY_THR_STATIC_KLD,
};
static moduledata_t pmc_mod = {
- PMC_MODULE_NAME,
- syscall_module_handler,
- &pmc_syscall_mod
+ .name = PMC_MODULE_NAME,
+ .evhand = syscall_module_handler,
+ .priv = &pmc_syscall_mod,
};
#ifdef EARLY_AP_STARTUP
@@ -2858,21 +2854,30 @@
static int
pmc_syscall_handler(struct thread *td, void *syscall_args)
{
- int error, is_sx_downgraded, is_sx_locked, op;
+ int error, is_sx_downgraded, op;
struct pmc_syscall_args *c;
+ void *pmclog_proc_handle;
void *arg;
- PMC_GET_SX_XLOCK(ENOSYS);
-
- DROP_GIANT();
-
- is_sx_downgraded = 0;
- is_sx_locked = 1;
-
- c = (struct pmc_syscall_args *) syscall_args;
-
+ c = (struct pmc_syscall_args *)syscall_args;
op = c->pmop_code;
arg = c->pmop_data;
+ if (op == PMC_OP_CONFIGURELOG) {
+ /*
+ * We cannot create the logging process inside
+ * pmclog_configure_log() because there is a LOR
+ * between pmc_sx and process structure locks.
+ * Instead, pre-create the process and ignite the loop
+ * if everything is fine, otherwise direct the process
+ * to exit.
+ */
+ error = pmclog_proc_create(td, &pmclog_proc_handle);
+ if (error != 0)
+ goto done_syscall;
+ }
+
+ PMC_GET_SX_XLOCK(ENOSYS);
+ is_sx_downgraded = 0;
PMCDBG3(MOD,PMS,1, "syscall op=%d \"%s\" arg=%p", op,
pmc_op_to_name[op], arg);
@@ -2880,8 +2885,7 @@
error = 0;
atomic_add_int(&pmc_stats.pm_syscalls, 1);
- switch(op)
- {
+ switch (op) {
/*
@@ -2897,15 +2901,16 @@
struct pmc_owner *po;
struct pmc_op_configurelog cl;
- sx_assert(&pmc_sx, SX_XLOCKED);
-
- if ((error = copyin(arg, &cl, sizeof(cl))) != 0)
+ if ((error = copyin(arg, &cl, sizeof(cl))) != 0) {
+ pmclog_proc_ignite(pmclog_proc_handle, NULL);
break;
+ }
/* mark this process as owning a log file */
p = td->td_proc;
if ((po = pmc_find_owner_descriptor(p)) == NULL)
if ((po = pmc_allocate_owner_descriptor(p)) == NULL) {
+ pmclog_proc_ignite(pmclog_proc_handle, NULL);
error = ENOMEM;
break;
}
@@ -2917,10 +2922,11 @@
* de-configure it.
*/
if (cl.pm_logfd >= 0) {
- sx_xunlock(&pmc_sx);
- is_sx_locked = 0;
error = pmclog_configure_log(md, po, cl.pm_logfd);
+ pmclog_proc_ignite(pmclog_proc_handle, error == 0 ?
+ po : NULL);
} else if (po->po_flags & PMC_PO_OWNS_LOGFILE) {
+ pmclog_proc_ignite(pmclog_proc_handle, NULL);
pmclog_process_closelog(po);
error = pmclog_close(po);
if (error == 0) {
@@ -2930,11 +2936,10 @@
pmc_stop(pm);
error = pmclog_deconfigure_log(po);
}
- } else
+ } else {
+ pmclog_proc_ignite(pmclog_proc_handle, NULL);
error = EINVAL;
-
- if (error)
- break;
+ }
}
break;
@@ -4029,19 +4034,15 @@
break;
}
- if (is_sx_locked != 0) {
- if (is_sx_downgraded)
- sx_sunlock(&pmc_sx);
- else
- sx_xunlock(&pmc_sx);
- }
-
+ if (is_sx_downgraded)
+ sx_sunlock(&pmc_sx);
+ else
+ sx_xunlock(&pmc_sx);
+done_syscall:
if (error)
atomic_add_int(&pmc_stats.pm_syscall_errors, 1);
- PICKUP_GIANT();
-
- return error;
+ return (error);
}
/*
Index: sys/sys/pmclog.h
===================================================================
--- sys/sys/pmclog.h
+++ sys/sys/pmclog.h
@@ -260,6 +260,8 @@
int pmclog_flush(struct pmc_owner *_po);
int pmclog_close(struct pmc_owner *_po);
void pmclog_initialize(void);
+int pmclog_proc_create(struct thread *td, void **handlep);
+void pmclog_proc_ignite(void *handle, struct pmc_owner *po);
void pmclog_process_callchain(struct pmc *_pm, struct pmc_sample *_ps);
void pmclog_process_closelog(struct pmc_owner *po);
void pmclog_process_dropnotify(struct pmc_owner *po);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Jan 9, 9:19 AM (4 h, 48 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15731213
Default Alt Text
D12882.id34570.diff (9 KB)
Attached To
Mode
D12882: Several hwpmc(4) fixes mostly for logging.
Attached
Detach File
Event Timeline
Log In to Comment