spi: Replace spi_pcpu_stats_totalize() macro by a C function
authorGeert Uytterhoeven <geert+renesas@glider.be>
Tue, 28 Feb 2023 14:43:08 +0000 (15:43 +0100)
committerMark Brown <broonie@kernel.org>
Sun, 5 Mar 2023 23:41:25 +0000 (23:41 +0000)
spi_pcpu_stats_totalize() is a rather large macro, and is instantiated
28 times, causing a large amount of duplication in the amount of
generated code.

Reduce the duplication by replacing spi_pcpu_stats_totalize() by a real
C function, and absorb all other common code from
spi_statistics_##name##_show().  As (a) the old "field" parameter was
the name of a structure member, which cannot be passed to a function,
and (b) passing a pointer to the member is also not an option, due to
the loop over all possible CPUs, the "field" parameter is replaced by an
"offset" parameter, pointing to a location within the structure.

This reduces kernel size by ca. 4 KiB (on arm32 and arm64).

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Link: https://lore.kernel.org/r/cb7690d9d04c06eec23dbb98fbb5444082125cff.1677594432.git.geert+renesas@glider.be
Signed-off-by: Mark Brown <broonie@kernel.org>
drivers/spi/spi.c

index 44b85a8d47f112f795fb0a8a46397daff7999bcf..798030c0c5ce9f5fc683c66a7274d471730a2a91 100644 (file)
@@ -117,24 +117,28 @@ static struct spi_statistics __percpu *spi_alloc_pcpu_stats(struct device *dev)
        return pcpu_stats;
 }
 
-#define spi_pcpu_stats_totalize(ret, in, field)                                \
-do {                                                                   \
-       int i;                                                          \
-       ret = 0;                                                        \
-       for_each_possible_cpu(i) {                                      \
-               const struct spi_statistics *pcpu_stats;                \
-               u64 inc;                                                \
-               unsigned int start;                                     \
-               pcpu_stats = per_cpu_ptr(in, i);                        \
-               do {                                                    \
-                       start = u64_stats_fetch_begin(          \
-                                       &pcpu_stats->syncp);            \
-                       inc = u64_stats_read(&pcpu_stats->field);       \
-               } while (u64_stats_fetch_retry(                 \
-                                       &pcpu_stats->syncp, start));    \
-               ret += inc;                                             \
-       }                                                               \
-} while (0)
+static ssize_t spi_emit_pcpu_stats(struct spi_statistics __percpu *stat,
+                                  char *buf, size_t offset)
+{
+       u64 val = 0;
+       int i;
+
+       for_each_possible_cpu(i) {
+               const struct spi_statistics *pcpu_stats;
+               u64_stats_t *field;
+               unsigned int start;
+               u64 inc;
+
+               pcpu_stats = per_cpu_ptr(stat, i);
+               field = (void *)pcpu_stats + offset;
+               do {
+                       start = u64_stats_fetch_begin(&pcpu_stats->syncp);
+                       inc = u64_stats_read(field);
+               } while (u64_stats_fetch_retry(&pcpu_stats->syncp, start));
+               val += inc;
+       }
+       return sysfs_emit(buf, "%llu\n", val);
+}
 
 #define SPI_STATISTICS_ATTRS(field, file)                              \
 static ssize_t spi_controller_##field##_show(struct device *dev,       \
@@ -165,11 +169,8 @@ static struct device_attribute dev_attr_spi_device_##field = {             \
 static ssize_t spi_statistics_##name##_show(struct spi_statistics __percpu *stat, \
                                            char *buf)                  \
 {                                                                      \
-       ssize_t len;                                                    \
-       u64 val;                                                        \
-       spi_pcpu_stats_totalize(val, stat, field);                      \
-       len = sysfs_emit(buf, "%llu\n", val);                           \
-       return len;                                                     \
+       return spi_emit_pcpu_stats(stat, buf,                           \
+                       offsetof(struct spi_statistics, field));        \
 }                                                                      \
 SPI_STATISTICS_ATTRS(name, file)