[PATCH 08/13] drivers/oprofile: convert stats to use seqnum_ops

From: Shuah Khan
Date: Tue Nov 10 2020 - 14:54:54 EST


seqnum_ops api is introduced to be used when a variable is used as
a sequence/stat counter and doesn't guard object lifetimes. This
clearly differentiates atomic_t usages that guard object lifetimes.

seqnum32 variables wrap around to INT_MIN when it overflows and
should not be used to guard resource lifetimes, device usage and
open counts that control state changes, and pm states.

atomic_t variables used for stats are atomic counters. Overflow will
wrap around and reset the stats and no change with the conversion.

Convert them to use seqnum_ops.

Signed-off-by: Shuah Khan <skhan@xxxxxxxxxxxxxxxxxxx>
---
drivers/oprofile/buffer_sync.c | 9 +++++----
drivers/oprofile/event_buffer.c | 3 ++-
drivers/oprofile/oprof.c | 3 ++-
drivers/oprofile/oprofile_stats.c | 11 ++++++-----
drivers/oprofile/oprofile_stats.h | 11 ++++++-----
drivers/oprofile/oprofilefs.c | 3 ++-
include/linux/oprofile.h | 3 ++-
7 files changed, 25 insertions(+), 18 deletions(-)

diff --git a/drivers/oprofile/buffer_sync.c b/drivers/oprofile/buffer_sync.c
index cc917865f13a..0503d467429b 100644
--- a/drivers/oprofile/buffer_sync.c
+++ b/drivers/oprofile/buffer_sync.c
@@ -34,6 +34,7 @@
#include <linux/sched/mm.h>
#include <linux/sched/task.h>
#include <linux/gfp.h>
+#include <linux/seqnum_ops.h>

#include "oprofile_stats.h"
#include "event_buffer.h"
@@ -347,7 +348,7 @@ static void add_data(struct op_entry *entry, struct mm_struct *mm)
if (cookie == NO_COOKIE)
offset = pc;
if (cookie == INVALID_COOKIE) {
- atomic_inc(&oprofile_stats.sample_lost_no_mapping);
+ seqnum32_inc(&oprofile_stats.sample_lost_no_mapping);
offset = pc;
}
if (cookie != last_cookie) {
@@ -391,14 +392,14 @@ add_sample(struct mm_struct *mm, struct op_sample *s, int in_kernel)
/* add userspace sample */

if (!mm) {
- atomic_inc(&oprofile_stats.sample_lost_no_mm);
+ seqnum32_inc(&oprofile_stats.sample_lost_no_mm);
return 0;
}

cookie = lookup_dcookie(mm, s->eip, &offset);

if (cookie == INVALID_COOKIE) {
- atomic_inc(&oprofile_stats.sample_lost_no_mapping);
+ seqnum32_inc(&oprofile_stats.sample_lost_no_mapping);
return 0;
}

@@ -556,7 +557,7 @@ void sync_buffer(int cpu)
/* ignore backtraces if failed to add a sample */
if (state == sb_bt_start) {
state = sb_bt_ignore;
- atomic_inc(&oprofile_stats.bt_lost_no_mapping);
+ seqnum32_inc(&oprofile_stats.bt_lost_no_mapping);
}
}
release_mm(mm);
diff --git a/drivers/oprofile/event_buffer.c b/drivers/oprofile/event_buffer.c
index 6c9edc8bbc95..6ec2f1ed8d94 100644
--- a/drivers/oprofile/event_buffer.c
+++ b/drivers/oprofile/event_buffer.c
@@ -19,6 +19,7 @@
#include <linux/dcookies.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
+#include <linux/seqnum_ops.h>

#include "oprof.h"
#include "event_buffer.h"
@@ -53,7 +54,7 @@ void add_event_entry(unsigned long value)
}

if (buffer_pos == buffer_size) {
- atomic_inc(&oprofile_stats.event_lost_overflow);
+ seqnum32_inc(&oprofile_stats.event_lost_overflow);
return;
}

diff --git a/drivers/oprofile/oprof.c b/drivers/oprofile/oprof.c
index ed2c3ec07024..f3183ef0f607 100644
--- a/drivers/oprofile/oprof.c
+++ b/drivers/oprofile/oprof.c
@@ -15,6 +15,7 @@
#include <linux/workqueue.h>
#include <linux/time.h>
#include <linux/mutex.h>
+#include <linux/seqnum_ops.h>

#include "oprof.h"
#include "event_buffer.h"
@@ -110,7 +111,7 @@ static void switch_worker(struct work_struct *work)
if (oprofile_ops.switch_events())
return;

- atomic_inc(&oprofile_stats.multiplex_counter);
+ seqnum32_inc(&oprofile_stats.multiplex_counter);
start_switch_worker();
}

diff --git a/drivers/oprofile/oprofile_stats.c b/drivers/oprofile/oprofile_stats.c
index 59659cea4582..04e9b2a0d35a 100644
--- a/drivers/oprofile/oprofile_stats.c
+++ b/drivers/oprofile/oprofile_stats.c
@@ -11,6 +11,7 @@
#include <linux/smp.h>
#include <linux/cpumask.h>
#include <linux/threads.h>
+#include <linux/seqnum_ops.h>

#include "oprofile_stats.h"
#include "cpu_buffer.h"
@@ -30,11 +31,11 @@ void oprofile_reset_stats(void)
cpu_buf->sample_invalid_eip = 0;
}

- atomic_set(&oprofile_stats.sample_lost_no_mm, 0);
- atomic_set(&oprofile_stats.sample_lost_no_mapping, 0);
- atomic_set(&oprofile_stats.event_lost_overflow, 0);
- atomic_set(&oprofile_stats.bt_lost_no_mapping, 0);
- atomic_set(&oprofile_stats.multiplex_counter, 0);
+ seqnum32_set(&oprofile_stats.sample_lost_no_mm, 0);
+ seqnum32_set(&oprofile_stats.sample_lost_no_mapping, 0);
+ seqnum32_set(&oprofile_stats.event_lost_overflow, 0);
+ seqnum32_set(&oprofile_stats.bt_lost_no_mapping, 0);
+ seqnum32_set(&oprofile_stats.multiplex_counter, 0);
}


diff --git a/drivers/oprofile/oprofile_stats.h b/drivers/oprofile/oprofile_stats.h
index 1fc622bd1834..229bcbb16527 100644
--- a/drivers/oprofile/oprofile_stats.h
+++ b/drivers/oprofile/oprofile_stats.h
@@ -11,13 +11,14 @@
#define OPROFILE_STATS_H

#include <linux/atomic.h>
+#include <linux/seqnum_ops.h>

struct oprofile_stat_struct {
- atomic_t sample_lost_no_mm;
- atomic_t sample_lost_no_mapping;
- atomic_t bt_lost_no_mapping;
- atomic_t event_lost_overflow;
- atomic_t multiplex_counter;
+ struct seqnum32 sample_lost_no_mm;
+ struct seqnum32 sample_lost_no_mapping;
+ struct seqnum32 bt_lost_no_mapping;
+ struct seqnum32 event_lost_overflow;
+ struct seqnum32 multiplex_counter;
};

extern struct oprofile_stat_struct oprofile_stats;
diff --git a/drivers/oprofile/oprofilefs.c b/drivers/oprofile/oprofilefs.c
index 0875f2f122b3..c5749b9aca11 100644
--- a/drivers/oprofile/oprofilefs.c
+++ b/drivers/oprofile/oprofilefs.c
@@ -17,6 +17,7 @@
#include <linux/fs_context.h>
#include <linux/pagemap.h>
#include <linux/uaccess.h>
+#include <linux/seqnum_ops.h>

#include "oprof.h"

@@ -193,7 +194,7 @@ static const struct file_operations atomic_ro_fops = {


int oprofilefs_create_ro_atomic(struct dentry *root,
- char const *name, atomic_t *val)
+ char const *name, struct seqnum32 *val)
{
return __oprofilefs_create_file(root, name,
&atomic_ro_fops, 0444, val);
diff --git a/include/linux/oprofile.h b/include/linux/oprofile.h
index b2a0f15f11fe..f770254a0c8a 100644
--- a/include/linux/oprofile.h
+++ b/include/linux/oprofile.h
@@ -19,6 +19,7 @@
#include <linux/errno.h>
#include <linux/printk.h>
#include <linux/atomic.h>
+#include <linux/seqnum_ops.h>

/* Each escaped entry is prefixed by ESCAPE_CODE
* then one of the following codes, then the
@@ -140,7 +141,7 @@ int oprofilefs_create_ro_ulong(struct dentry * root,

/** Create a file for read-only access to an atomic_t. */
int oprofilefs_create_ro_atomic(struct dentry * root,
- char const * name, atomic_t * val);
+ char const *name, struct seqnum32 *val);

/** create a directory */
struct dentry *oprofilefs_mkdir(struct dentry *parent, char const *name);
--
2.27.0