Unverified Commit fc12d4bb authored by Geert Uytterhoeven's avatar Geert Uytterhoeven Committed by Mark Brown
Browse files

spi: Replace spi_pcpu_stats_totalize() macro by a C function



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: default avatarGeert Uytterhoeven <geert+renesas@glider.be>
Link: https://lore.kernel.org/r/cb7690d9d04c06eec23dbb98fbb5444082125cff.1677594432.git.geert+renesas@glider.be


Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent fe15c26e
Loading
Loading
Loading
Loading
+24 −23
Original line number Diff line number Diff line
@@ -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)