s390/cpum_sf: Add flag to process full SDBs only
authorHendrik Brueckner <brueckner@linux.vnet.ibm.com>
Fri, 13 Dec 2013 11:45:01 +0000 (12:45 +0100)
committerMartin Schwidefsky <schwidefsky@de.ibm.com>
Mon, 16 Dec 2013 13:38:01 +0000 (14:38 +0100)
Add the PERF_CPUM_SF_FULL_BLOCKS flag to process only sample-data-blocks that
have the block-full-indicator bit set.  Sample-data-blocks that are partially
filled are discarded.  Use this flag if the sampling buffer is likely to be
shared among perf events that use different sampling modes.  In such
environments, flushing sample-data-blocks that are not completely filled, might
cause invalid-data-formats.

Setting PERF_CPUM_SF_FULL_BLOCKS prevents potentially invalid sampling data to
be processed but, in contrast, also discards valid samples in partially filled
sample-data-blocks.  Note that sample-data-blocks might not become full for
small sampling frequencies or for workload that is scheduled for tiny intervals.

To sample with the PERF_CPUM_SF_FULL_BLOCKS flag, set the perf->attr.config1
to 0x0004.  For example:

perf record -e cpum_sf/config=0xB000,config1=0x0004/

Signed-off-by: Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
arch/s390/include/asm/perf_event.h
arch/s390/kernel/perf_cpum_sf.c

index bd4573f1d65ca150a5463743ad56ed402edd203b..159a8ec6da9afc30e26a3fe1ffe10ec5f7c26745 100644 (file)
@@ -59,6 +59,7 @@ struct perf_sf_sde_regs {
 #define PERF_CPUM_SF_DIAG_MODE         0x0002    /* Diagnostic-sampling flag */
 #define PERF_CPUM_SF_MODE_MASK         (PERF_CPUM_SF_BASIC_MODE| \
                                         PERF_CPUM_SF_DIAG_MODE)
+#define PERF_CPUM_SF_FULL_BLOCKS       0x0004    /* Process full SDBs only */
 
 #define REG_NONE               0
 #define REG_OVERFLOW           1
@@ -69,6 +70,7 @@ struct perf_sf_sde_regs {
 #define SAMPL_RATE(hwc)                ((hwc)->event_base)
 #define SAMPL_FLAGS(hwc)       ((hwc)->config_base)
 #define SAMPL_DIAG_MODE(hwc)   (SAMPL_FLAGS(hwc) & PERF_CPUM_SF_DIAG_MODE)
+#define SDB_FULL_BLOCKS(hwc)   (SAMPL_FLAGS(hwc) & PERF_CPUM_SF_FULL_BLOCKS)
 
 /* Structure for sampling data entries to be passed as perf raw sample data
  * to user space.  Note that raw sample data must be aligned and, thus, might
index b4ec058c4f10f068ae8c759b1bec563894c7744f..3c3bc8d7b22080e09cf5ee26ffb04718a49cd5b5 100644 (file)
@@ -733,6 +733,10 @@ static int __hw_perf_event_init(struct perf_event *event)
                SAMPL_FLAGS(hwc) |= PERF_CPUM_SF_DIAG_MODE;
        }
 
+       /* Check and set other sampling flags */
+       if (attr->config1 & PERF_CPUM_SF_FULL_BLOCKS)
+               SAMPL_FLAGS(hwc) |= PERF_CPUM_SF_FULL_BLOCKS;
+
        /* The sampling information (si) contains information about the
         * min/max sampling intervals and the CPU speed.  So calculate the
         * correct sampling interval and avoid the whole period adjust
@@ -1203,8 +1207,10 @@ static void hw_collect_samples(struct perf_event *event, unsigned long *sdbt,
  * register of the specified perf event.
  *
  * Only full sample-data-blocks are processed. Specify the flash_all flag
- * to also walk through partially filled sample-data-blocks.
- *
+ * to also walk through partially filled sample-data-blocks.  It is ignored
+ * if PERF_CPUM_SF_FULL_BLOCKS is set. The PERF_CPUM_SF_FULL_BLOCKS flag
+ * enforces the processing of full sample-data-blocks only (trailer entries
+ * with the block-full-indicator bit set).
  */
 static void hw_perf_event_update(struct perf_event *event, int flush_all)
 {
@@ -1214,6 +1220,9 @@ static void hw_perf_event_update(struct perf_event *event, int flush_all)
        unsigned long long event_overflow, sampl_overflow, num_sdb, te_flags;
        int done;
 
+       if (flush_all && SDB_FULL_BLOCKS(hwc))
+               flush_all = 0;
+
        sdbt = (unsigned long *) TEAR_REG(hwc);
        done = event_overflow = sampl_overflow = num_sdb = 0;
        while (!done) {