Commit 58d4f14f authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Jens Axboe
Browse files

block: always use a percpu variable for disk stats



percpu variables have a perfectly fine working stub implementation
for UP kernels, so use that.

Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarKonstantin Khlebnikov <khlebnikov@yandex-team.ru>
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent 9123bf6f
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -378,7 +378,7 @@ static inline void hd_struct_put(struct hd_struct *part)

static inline void hd_free_part(struct hd_struct *part)
{
	free_part_stats(part);
	free_percpu(part->dkstats);
	kfree(part->info);
	percpu_ref_exit(&part->ref);
}
+3 −9
Original line number Diff line number Diff line
@@ -92,7 +92,6 @@ const char *bdevname(struct block_device *bdev, char *buf)
}
EXPORT_SYMBOL(bdevname);

#ifdef CONFIG_SMP
static void part_stat_read_all(struct hd_struct *part, struct disk_stats *stat)
{
	int cpu;
@@ -112,12 +111,6 @@ static void part_stat_read_all(struct hd_struct *part, struct disk_stats *stat)
		stat->io_ticks += ptr->io_ticks;
	}
}
#else /* CONFIG_SMP */
static void part_stat_read_all(struct hd_struct *part, struct disk_stats *stat)
{
	memcpy(stat, &part->dkstats, sizeof(struct disk_stats));
}
#endif /* CONFIG_SMP */

static unsigned int part_in_flight(struct request_queue *q,
		struct hd_struct *part)
@@ -1688,14 +1681,15 @@ struct gendisk *__alloc_disk_node(int minors, int node_id)

	disk = kzalloc_node(sizeof(struct gendisk), GFP_KERNEL, node_id);
	if (disk) {
		if (!init_part_stats(&disk->part0)) {
		disk->part0.dkstats = alloc_percpu(struct disk_stats);
		if (!disk->part0.dkstats) {
			kfree(disk);
			return NULL;
		}
		init_rwsem(&disk->lookup_sem);
		disk->node_id = node_id;
		if (disk_expand_part_tbl(disk, 0)) {
			free_part_stats(&disk->part0);
			free_percpu(disk->part0.dkstats);
			kfree(disk);
			return NULL;
		}
+3 −2
Original line number Diff line number Diff line
@@ -387,7 +387,8 @@ static struct hd_struct *add_partition(struct gendisk *disk, int partno,
	if (!p)
		return ERR_PTR(-EBUSY);

	if (!init_part_stats(p)) {
	p->dkstats = alloc_percpu(struct disk_stats);
	if (!p->dkstats) {
		err = -ENOMEM;
		goto out_free;
	}
@@ -468,7 +469,7 @@ static struct hd_struct *add_partition(struct gendisk *disk, int partno,
out_free_info:
	kfree(p->info);
out_free_stats:
	free_part_stats(p);
	free_percpu(p->dkstats);
out_free:
	kfree(p);
	return ERR_PTR(err);
+0 −13
Original line number Diff line number Diff line
@@ -39,15 +39,6 @@ extern struct class block_class;
#include <linux/fs.h>
#include <linux/workqueue.h>

struct disk_stats {
	u64 nsecs[NR_STAT_GROUPS];
	unsigned long sectors[NR_STAT_GROUPS];
	unsigned long ios[NR_STAT_GROUPS];
	unsigned long merges[NR_STAT_GROUPS];
	unsigned long io_ticks;
	local_t in_flight[2];
};

#define PARTITION_META_INFO_VOLNAMELTH	64
/*
 * Enough for the string representation of any kind of UUID plus NULL.
@@ -72,11 +63,7 @@ struct hd_struct {
	seqcount_t nr_sects_seq;
#endif
	unsigned long stamp;
#ifdef	CONFIG_SMP
	struct disk_stats __percpu *dkstats;
#else
	struct disk_stats dkstats;
#endif
	struct percpu_ref ref;

	sector_t alignment_offset;
+11 −44
Original line number Diff line number Diff line
@@ -4,19 +4,23 @@

#include <linux/genhd.h>

struct disk_stats {
	u64 nsecs[NR_STAT_GROUPS];
	unsigned long sectors[NR_STAT_GROUPS];
	unsigned long ios[NR_STAT_GROUPS];
	unsigned long merges[NR_STAT_GROUPS];
	unsigned long io_ticks;
	local_t in_flight[2];
};

/*
 * Macros to operate on percpu disk statistics:
 *
 * {disk|part|all}_stat_{add|sub|inc|dec}() modify the stat counters
 * and should be called between disk_stat_lock() and
 * disk_stat_unlock().
 * {disk|part|all}_stat_{add|sub|inc|dec}() modify the stat counters and should
 * be called between disk_stat_lock() and disk_stat_unlock().
 *
 * part_stat_read() can be called at any time.
 *
 * part_stat_{add|set_all}() and {init|free}_part_stats are for
 * internal use only.
 */
#ifdef	CONFIG_SMP
#define part_stat_lock()	({ rcu_read_lock(); get_cpu(); })
#define part_stat_unlock()	do { put_cpu(); rcu_read_unlock(); } while (0)

@@ -44,43 +48,6 @@ static inline void part_stat_set_all(struct hd_struct *part, int value)
				sizeof(struct disk_stats));
}

static inline int init_part_stats(struct hd_struct *part)
{
	part->dkstats = alloc_percpu(struct disk_stats);
	if (!part->dkstats)
		return 0;
	return 1;
}

static inline void free_part_stats(struct hd_struct *part)
{
	free_percpu(part->dkstats);
}

#else /* !CONFIG_SMP */
#define part_stat_lock()	({ rcu_read_lock(); 0; })
#define part_stat_unlock()	rcu_read_unlock()

#define part_stat_get(part, field)		((part)->dkstats.field)
#define part_stat_get_cpu(part, field, cpu)	part_stat_get(part, field)
#define part_stat_read(part, field)		part_stat_get(part, field)

static inline void part_stat_set_all(struct hd_struct *part, int value)
{
	memset(&part->dkstats, value, sizeof(struct disk_stats));
}

static inline int init_part_stats(struct hd_struct *part)
{
	return 1;
}

static inline void free_part_stats(struct hd_struct *part)
{
}

#endif /* CONFIG_SMP */

#define part_stat_read_accum(part, field)				\
	(part_stat_read(part, field[STAT_READ]) +			\
	 part_stat_read(part, field[STAT_WRITE]) +			\