Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 16 Nov 2011 15:25:13 +0000 (UTC)
From:      Fabien Thomas <fabient@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org
Subject:   svn commit: r227555 - in stable/8: lib/libpmc sys/dev/hwpmc sys/sys usr.sbin/pmcstat
Message-ID:  <201111161525.pAGFPDQ6054533@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: fabient
Date: Wed Nov 16 15:25:12 2011
New Revision: 227555
URL: http://svn.freebsd.org/changeset/base/227555

Log:
  MFC r226514,r226526,r226986:
  Add a flush of the current PMC log buffer before displaying the next top.
  
  As the underlying block is 4KB if the PMC throughput is low the measurement
  will be reported on the next tick. pmcstat(8) use the modified flush API to
  reclaim current buffer before displaying next top.

Modified:
  stable/8/lib/libpmc/libpmc.c
  stable/8/lib/libpmc/pmc.3
  stable/8/lib/libpmc/pmc.h
  stable/8/lib/libpmc/pmc_configure_logfile.3
  stable/8/sys/dev/hwpmc/hwpmc_logging.c
  stable/8/sys/dev/hwpmc/hwpmc_mod.c
  stable/8/sys/sys/pmc.h
  stable/8/sys/sys/pmclog.h
  stable/8/usr.sbin/pmcstat/pmcstat.c
  stable/8/usr.sbin/pmcstat/pmcstat_log.c
Directory Properties:
  stable/8/lib/libpmc/   (props changed)
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)
  stable/8/usr.sbin/pmcstat/   (props changed)

Modified: stable/8/lib/libpmc/libpmc.c
==============================================================================
--- stable/8/lib/libpmc/libpmc.c	Wed Nov 16 15:23:42 2011	(r227554)
+++ stable/8/lib/libpmc/libpmc.c	Wed Nov 16 15:25:12 2011	(r227555)
@@ -2560,6 +2560,12 @@ pmc_flush_logfile(void)
 }
 
 int
+pmc_close_logfile(void)
+{
+	return (PMC_CALL(CLOSELOG,0));
+}
+
+int
 pmc_get_driver_stats(struct pmc_driverstats *ds)
 {
 	struct pmc_op_getdriverstats gms;

Modified: stable/8/lib/libpmc/pmc.3
==============================================================================
--- stable/8/lib/libpmc/pmc.3	Wed Nov 16 15:23:42 2011	(r227554)
+++ stable/8/lib/libpmc/pmc.3	Wed Nov 16 15:25:12 2011	(r227555)
@@ -322,6 +322,10 @@ to write logged events to.
 Flush all pending log data in
 .Xr hwpmc 4 Ns Ap s
 buffers.
+.It Fn pmc_close_logfile
+Flush all pending log data and close
+.Xr hwpmc 4 Ns Ap s
+side of the stream.
 .It Fn pmc_writelog
 Append arbitrary user data to the current log file.
 .El

Modified: stable/8/lib/libpmc/pmc.h
==============================================================================
--- stable/8/lib/libpmc/pmc.h	Wed Nov 16 15:23:42 2011	(r227554)
+++ stable/8/lib/libpmc/pmc.h	Wed Nov 16 15:25:12 2011	(r227555)
@@ -76,6 +76,7 @@ int	pmc_attach(pmc_id_t _pmcid, pid_t _p
 int	pmc_capabilities(pmc_id_t _pmc, uint32_t *_caps);
 int	pmc_configure_logfile(int _fd);
 int	pmc_flush_logfile(void);
+int	pmc_close_logfile(void);
 int	pmc_detach(pmc_id_t _pmcid, pid_t _pid);
 int	pmc_disable(int _cpu, int _pmc);
 int	pmc_enable(int _cpu, int _pmc);

Modified: stable/8/lib/libpmc/pmc_configure_logfile.3
==============================================================================
--- stable/8/lib/libpmc/pmc_configure_logfile.3	Wed Nov 16 15:23:42 2011	(r227554)
+++ stable/8/lib/libpmc/pmc_configure_logfile.3	Wed Nov 16 15:25:12 2011	(r227555)
@@ -29,7 +29,8 @@
 .Sh NAME
 .Nm pmc_configure_logfile ,
 .Nm pmc_flush_logfile ,
-.Nm pmc_writelog
+.Nm pmc_writelog ,
+.Nm pmc_close_logfile
 .Nd log file management
 .Sh LIBRARY
 .Lb libpmc
@@ -41,6 +42,8 @@
 .Fn pmc_flush_logfile void
 .Ft int
 .Fn pmc_writelog "uint32_t userdata"
+.Ft int
+.Fn pmc_close_logfile void
 .Sh DESCRIPTION
 The functions manage logging of
 .Xr hwpmc 4
@@ -72,6 +75,12 @@ Function
 will append a log entry containing the value of argument
 .Fa userdata
 to the log file.
+.Pp
+Function
+.Fn pmc_close_logfile
+will flush all pending log data and close
+.Xr hwpmc 4 Ns Ap s
+side of the stream.
 .Sh RETURN VALUES
 .Rv -std
 .Sh ERRORS

Modified: stable/8/sys/dev/hwpmc/hwpmc_logging.c
==============================================================================
--- stable/8/sys/dev/hwpmc/hwpmc_logging.c	Wed Nov 16 15:23:42 2011	(r227554)
+++ stable/8/sys/dev/hwpmc/hwpmc_logging.c	Wed Nov 16 15:25:12 2011	(r227555)
@@ -237,7 +237,7 @@ pmclog_get_buffer(struct pmc_owner *po)
 static void
 pmclog_loop(void *arg)
 {
-	int error, last_buffer;
+	int error;
 	struct pmc_owner *po;
 	struct pmclog_buffer *lb;
 	struct proc *p;
@@ -252,7 +252,6 @@ pmclog_loop(void *arg)
 	p = po->po_owner;
 	td = curthread;
 	mycred = td->td_ucred;
-	last_buffer = 0;
 
 	PROC_LOCK(p);
 	ownercred = crhold(p->p_ucred);
@@ -285,14 +284,22 @@ pmclog_loop(void *arg)
 			if ((lb = TAILQ_FIRST(&po->po_logbuffers)) == NULL) {
 				mtx_unlock_spin(&po->po_mtx);
 
+				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);
+				}
+
 				(void) msleep(po, &pmc_kthread_mtx, PWAIT,
 				    "pmcloop", 0);
 				continue;
 			}
 
 			TAILQ_REMOVE(&po->po_logbuffers, lb, plb_next);
-			if (po->po_flags & PMC_PO_SHUTDOWN)
-				last_buffer = TAILQ_EMPTY(&po->po_logbuffers);
 			mtx_unlock_spin(&po->po_mtx);
 		}
 
@@ -335,14 +342,6 @@ pmclog_loop(void *arg)
 			break;
 		}
 
-		if (last_buffer) {
-			/*
-			 * Close the file to get PMCLOG_EOF error
-			 * in pmclog(3).
-			 */
-			fo_close(po->po_file, curthread);
-		}
-
 		mtx_lock(&pmc_kthread_mtx);
 
 		/* put the used buffer back into the global pool */
@@ -692,6 +691,7 @@ int
 pmclog_flush(struct pmc_owner *po)
 {
 	int error;
+	struct pmclog_buffer *lb;
 
 	PMCDBG(LOG,FLS,1, "po=%p", po);
 
@@ -714,11 +714,38 @@ pmclog_flush(struct pmc_owner *po)
 	}
 
 	/*
-	 * Schedule the current buffer if any.
+	 * Schedule the current buffer if any and not empty.
+	 */
+	mtx_lock_spin(&po->po_mtx);
+	lb = po->po_curbuf;
+	if (lb && lb->plb_ptr != lb->plb_base) {
+		pmclog_schedule_io(po);
+	} else
+		error = ENOBUFS;
+	mtx_unlock_spin(&po->po_mtx);
+
+ error:
+	mtx_unlock(&pmc_kthread_mtx);
+
+	return (error);
+}
+
+int
+pmclog_close(struct pmc_owner *po)
+{
+
+	PMCDBG(LOG,CLO,1, "po=%p", po);
+
+	mtx_lock(&pmc_kthread_mtx);
+
+	/*
+	 * Schedule the current buffer.
 	 */
 	mtx_lock_spin(&po->po_mtx);
 	if (po->po_curbuf)
 		pmclog_schedule_io(po);
+	else
+		wakeup_one(po);
 	mtx_unlock_spin(&po->po_mtx);
 
 	/*
@@ -727,13 +754,11 @@ pmclog_flush(struct pmc_owner *po)
 	 */
 	po->po_flags |= PMC_PO_SHUTDOWN;
 
- error:
 	mtx_unlock(&pmc_kthread_mtx);
 
-	return (error);
+	return (0);
 }
 
-
 void
 pmclog_process_callchain(struct pmc *pm, struct pmc_sample *ps)
 {

Modified: stable/8/sys/dev/hwpmc/hwpmc_mod.c
==============================================================================
--- stable/8/sys/dev/hwpmc/hwpmc_mod.c	Wed Nov 16 15:23:42 2011	(r227554)
+++ stable/8/sys/dev/hwpmc/hwpmc_mod.c	Wed Nov 16 15:25:12 2011	(r227555)
@@ -2891,7 +2891,7 @@ pmc_syscall_handler(struct thread *td, v
 			error = pmclog_configure_log(md, po, cl.pm_logfd);
 		} else if (po->po_flags & PMC_PO_OWNS_LOGFILE) {
 			pmclog_process_closelog(po);
-			error = pmclog_flush(po);
+			error = pmclog_close(po);
 			if (error == 0) {
 				LIST_FOREACH(pm, &po->po_pmcs, pm_next)
 				    if (pm->pm_flags & PMC_F_NEEDS_LOGFILE &&
@@ -2907,7 +2907,6 @@ pmc_syscall_handler(struct thread *td, v
 	}
 	break;
 
-
 	/*
 	 * Flush a log file.
 	 */
@@ -2928,6 +2927,25 @@ pmc_syscall_handler(struct thread *td, v
 	break;
 
 	/*
+	 * Close a log file.
+	 */
+
+	case PMC_OP_CLOSELOG:
+	{
+		struct pmc_owner *po;
+
+		sx_assert(&pmc_sx, SX_XLOCKED);
+
+		if ((po = pmc_find_owner_descriptor(td->td_proc)) == NULL) {
+			error = EINVAL;
+			break;
+		}
+
+		error = pmclog_close(po);
+	}
+	break;
+
+	/*
 	 * Retrieve hardware configuration.
 	 */
 

Modified: stable/8/sys/sys/pmc.h
==============================================================================
--- stable/8/sys/sys/pmc.h	Wed Nov 16 15:23:42 2011	(r227554)
+++ stable/8/sys/sys/pmc.h	Wed Nov 16 15:25:12 2011	(r227555)
@@ -300,7 +300,8 @@ enum pmc_event {
 	__PMC_OP(PMCSETCOUNT, "Set initial count/sampling rate")	\
 	__PMC_OP(PMCSTART, "Start a PMC")				\
 	__PMC_OP(PMCSTOP, "Start a PMC")				\
-	__PMC_OP(WRITELOG, "Write a cookie to the log file")
+	__PMC_OP(WRITELOG, "Write a cookie to the log file")		\
+	__PMC_OP(CLOSELOG, "Close log file")
 
 
 enum pmc_ops {
@@ -1037,6 +1038,7 @@ extern struct pmc_debugflags pmc_debugfl
 #define	PMC_DEBUG_MIN_SIO		9 /* schedule i/o */
 #define	PMC_DEBUG_MIN_FLS	       10 /* flush */
 #define	PMC_DEBUG_MIN_SAM	       11 /* sample */
+#define	PMC_DEBUG_MIN_CLO	       12 /* close */
 
 #else
 #define	PMCDBG(M,N,L,F,...)		/* nothing */

Modified: stable/8/sys/sys/pmclog.h
==============================================================================
--- stable/8/sys/sys/pmclog.h	Wed Nov 16 15:23:42 2011	(r227554)
+++ stable/8/sys/sys/pmclog.h	Wed Nov 16 15:25:12 2011	(r227555)
@@ -243,6 +243,7 @@ int	pmclog_configure_log(struct pmc_mdep
     int _logfd);
 int	pmclog_deconfigure_log(struct pmc_owner *_po);
 int	pmclog_flush(struct pmc_owner *_po);
+int	pmclog_close(struct pmc_owner *_po);
 void	pmclog_initialize(void);
 void	pmclog_process_callchain(struct pmc *_pm, struct pmc_sample *_ps);
 void	pmclog_process_closelog(struct pmc_owner *po);

Modified: stable/8/usr.sbin/pmcstat/pmcstat.c
==============================================================================
--- stable/8/usr.sbin/pmcstat/pmcstat.c	Wed Nov 16 15:23:42 2011	(r227554)
+++ stable/8/usr.sbin/pmcstat/pmcstat.c	Wed Nov 16 15:25:12 2011	(r227555)
@@ -555,7 +555,7 @@ main(int argc, char **argv)
 	int option, npmc, ncpu, haltedcpus;
 	int c, check_driver_stats, current_cpu, current_sampling_count;
 	int do_callchain, do_descendants, do_logproccsw, do_logprocexit;
-	int do_print;
+	int do_print, do_read;
 	size_t dummy;
 	int graphdepth;
 	int pipefd[2], rfd;
@@ -797,7 +797,9 @@ main(int argc, char **argv)
 			break;
 
 		case 'o':	/* outputfile */
-			if (args.pa_printfile != NULL)
+			if (args.pa_printfile != NULL &&
+			    args.pa_printfile != stdout &&
+			    args.pa_printfile != stderr)
 				(void) fclose(args.pa_printfile);
 			if ((args.pa_printfile = fopen(optarg, "w")) == NULL)
 				errx(EX_OSERR, "ERROR: cannot open \"%s\" for "
@@ -1329,7 +1331,7 @@ main(int argc, char **argv)
 	 * are killed by a SIGINT.
 	 */
 	runstate = PMCSTAT_RUNNING;
-	do_print = 0;
+	do_print = do_read = 0;
 	do {
 		if ((c = kevent(pmcstat_kq, NULL, 0, &kev, 1, NULL)) <= 0) {
 			if (errno != EINTR)
@@ -1352,8 +1354,10 @@ main(int argc, char **argv)
 			    (args.pa_flags & FLAG_DO_TOP)) {
 				if (pmcstat_keypress_log())
 					runstate = pmcstat_close_log();
-			} else
+			} else {
+				do_read = 0;
 				runstate = pmcstat_process_log();
+			}
 			break;
 
 		case EVFILT_SIGNAL:
@@ -1378,9 +1382,6 @@ main(int argc, char **argv)
 				/* Kill the child process if we started it */
 				if (args.pa_flags & FLAG_HAS_COMMANDLINE)
 					pmcstat_kill_process();
-				/* Close the pipe to self, if present. */
-				if (args.pa_flags & FLAG_HAS_PIPE)
-					(void) close(pipefd[READPIPEFD]);
 				runstate = pmcstat_close_log();
 			} else if (kev.ident == SIGWINCH) {
 				if (ioctl(fileno(args.pa_printfile),
@@ -1395,12 +1396,15 @@ main(int argc, char **argv)
 			break;
 
 		case EVFILT_TIMER: /* print out counting PMCs */
+			if ((args.pa_flags & FLAG_DO_TOP) &&
+			     pmc_flush_logfile() == 0)
+				do_read = 1;
 			do_print = 1;
 			break;
 
 		}
 
-		if (do_print) {
+		if (do_print && !do_read) {
 			if ((args.pa_required & FLAG_HAS_OUTPUT_LOGFILE) == 0) {
 				pmcstat_print_pmcs();
 				if (runstate == PMCSTAT_FINISHED && /* final newline */
@@ -1421,7 +1425,7 @@ main(int argc, char **argv)
 
 	/* flush any pending log entries */
 	if (args.pa_flags & (FLAG_HAS_OUTPUT_LOGFILE | FLAG_HAS_PIPE))
-		pmc_flush_logfile();
+		pmc_close_logfile();
 
 	pmcstat_cleanup();
 

Modified: stable/8/usr.sbin/pmcstat/pmcstat_log.c
==============================================================================
--- stable/8/usr.sbin/pmcstat/pmcstat_log.c	Wed Nov 16 15:23:42 2011	(r227554)
+++ stable/8/usr.sbin/pmcstat/pmcstat_log.c	Wed Nov 16 15:25:12 2011	(r227555)
@@ -1703,7 +1703,7 @@ pmcstat_close_log(void)
 	 * so keep the status to EXITING.
 	 */
 	if (args.pa_logfd != -1) {
-		if (pmc_flush_logfile() < 0)
+		if (pmc_close_logfile() < 0)
 			err(EX_OSERR, "ERROR: logging failed");
 	}
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201111161525.pAGFPDQ6054533>