summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2019-02-06 11:42:13 -0500
committerKent Overstreet <kent.overstreet@linux.dev>2023-10-22 17:08:15 -0400
commit4c97e04aa8818da266a690543aca28e2e7c26820 (patch)
tree4e5568716eea0192460dc49c14ed94436485edc7
parentfe112812ae41bfed0aa61cdfbe8233e4122e5cb8 (diff)
downloadlinux-stable-4c97e04aa8818da266a690543aca28e2e7c26820.tar.gz
linux-stable-4c97e04aa8818da266a690543aca28e2e7c26820.tar.bz2
linux-stable-4c97e04aa8818da266a690543aca28e2e7c26820.zip
bcachefs: percpu utility code
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
-rw-r--r--fs/bcachefs/buckets.c5
-rw-r--r--fs/bcachefs/replicas.c6
-rw-r--r--fs/bcachefs/sysfs.c13
-rw-r--r--fs/bcachefs/util.h23
4 files changed, 30 insertions, 17 deletions
diff --git a/fs/bcachefs/buckets.c b/fs/bcachefs/buckets.c
index d40aa69532cc..d919c1cacee5 100644
--- a/fs/bcachefs/buckets.c
+++ b/fs/bcachefs/buckets.c
@@ -1005,10 +1005,7 @@ void bch2_mark_update(struct btree_insert *trans,
static u64 bch2_recalc_sectors_available(struct bch_fs *c)
{
- int cpu;
-
- for_each_possible_cpu(cpu)
- per_cpu_ptr(c->pcpu, cpu)->sectors_available = 0;
+ percpu_u64_set(&c->pcpu->sectors_available, 0);
return avail_factor(bch2_fs_sectors_free(c));
}
diff --git a/fs/bcachefs/replicas.c b/fs/bcachefs/replicas.c
index 34a5475cfaba..5663441fd7ce 100644
--- a/fs/bcachefs/replicas.c
+++ b/fs/bcachefs/replicas.c
@@ -426,14 +426,12 @@ int bch2_replicas_gc_end(struct bch_fs *c, int ret)
struct bch_replicas_entry *e =
cpu_replicas_entry(&c->replicas, i);
struct bch_replicas_cpu n;
- u64 v = 0;
- int cpu;
+ u64 v;
if (__replicas_has_entry(&c->replicas_gc, e))
continue;
- for_each_possible_cpu(cpu)
- v += *per_cpu_ptr(&c->usage[0]->data[i], cpu);
+ v = percpu_u64_get(&c->usage[0]->data[i]);
if (!v)
continue;
diff --git a/fs/bcachefs/sysfs.c b/fs/bcachefs/sysfs.c
index f33a533ee6b8..8ad7b6026d1b 100644
--- a/fs/bcachefs/sysfs.c
+++ b/fs/bcachefs/sysfs.c
@@ -893,20 +893,15 @@ static const char * const bch2_rw[] = {
static ssize_t show_dev_iodone(struct bch_dev *ca, char *buf)
{
struct printbuf out = _PBUF(buf, PAGE_SIZE);
- int rw, i, cpu;
+ int rw, i;
for (rw = 0; rw < 2; rw++) {
pr_buf(&out, "%s:\n", bch2_rw[rw]);
- for (i = 1; i < BCH_DATA_NR; i++) {
- u64 n = 0;
-
- for_each_possible_cpu(cpu)
- n += per_cpu_ptr(ca->io_done, cpu)->sectors[rw][i];
-
+ for (i = 1; i < BCH_DATA_NR; i++)
pr_buf(&out, "%-12s:%12llu\n",
- bch2_data_types[i], n << 9);
- }
+ bch2_data_types[i],
+ percpu_u64_get(&ca->io_done->sectors[rw][i]) << 9);
}
return out.pos - buf;
diff --git a/fs/bcachefs/util.h b/fs/bcachefs/util.h
index fa1a3adc87df..dc40a52ac8c7 100644
--- a/fs/bcachefs/util.h
+++ b/fs/bcachefs/util.h
@@ -12,6 +12,7 @@
#include <linux/llist.h>
#include <linux/log2.h>
#include <linux/percpu.h>
+#include <linux/preempt.h>
#include <linux/ratelimit.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
@@ -701,6 +702,28 @@ do { \
} \
} while (0)
+static inline u64 percpu_u64_get(u64 __percpu *src)
+{
+ u64 ret = 0;
+ int cpu;
+
+ for_each_possible_cpu(cpu)
+ ret += *per_cpu_ptr(src, cpu);
+ return ret;
+}
+
+static inline void percpu_u64_set(u64 __percpu *dst, u64 src)
+{
+ int cpu;
+
+ for_each_possible_cpu(cpu)
+ *per_cpu_ptr(dst, cpu) = 0;
+
+ preempt_disable();
+ *this_cpu_ptr(dst) = src;
+ preempt_enable();
+}
+
static inline void acc_u64s(u64 *acc, const u64 *src, unsigned nr)
{
unsigned i;