Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1e9bb880 authored by Shaohua Li's avatar Shaohua Li Committed by Jens Axboe
Browse files

block: fix non-atomic access to genhd inflight structures



After the stack plugging introduction, these are called lockless.
Ensure that the counters are updated atomically.

Signed-off-by: default avatarShaohua <Li&lt;shaohua.li@intel.com>
Signed-off-by: default avatarJens Axboe <jaxboe@fusionio.com>
parent 5e84ea3a
Loading
Loading
Loading
Loading
+4 −3
Original line number Diff line number Diff line
@@ -477,7 +477,8 @@ static void start_io_acct(struct dm_io *io)
	cpu = part_stat_lock();
	part_round_stats(cpu, &dm_disk(md)->part0);
	part_stat_unlock();
	dm_disk(md)->part0.in_flight[rw] = atomic_inc_return(&md->pending[rw]);
	atomic_set(&dm_disk(md)->part0.in_flight[rw],
		atomic_inc_return(&md->pending[rw]));
}

static void end_io_acct(struct dm_io *io)
@@ -497,8 +498,8 @@ static void end_io_acct(struct dm_io *io)
	 * After this is decremented the bio must not be touched if it is
	 * a flush.
	 */
	dm_disk(md)->part0.in_flight[rw] = pending =
		atomic_dec_return(&md->pending[rw]);
	pending = atomic_dec_return(&md->pending[rw]);
	atomic_set(&dm_disk(md)->part0.in_flight[rw], pending);
	pending += atomic_read(&md->pending[rw^0x1]);

	/* nudge anyone waiting on suspend queue */
+2 −1
Original line number Diff line number Diff line
@@ -290,7 +290,8 @@ ssize_t part_inflight_show(struct device *dev,
{
	struct hd_struct *p = dev_to_part(dev);

	return sprintf(buf, "%8u %8u\n", p->in_flight[0], p->in_flight[1]);
	return sprintf(buf, "%8u %8u\n", atomic_read(&p->in_flight[0]),
		atomic_read(&p->in_flight[1]));
}

#ifdef CONFIG_FAIL_MAKE_REQUEST
+6 −6
Original line number Diff line number Diff line
@@ -109,7 +109,7 @@ struct hd_struct {
	int make_it_fail;
#endif
	unsigned long stamp;
	int in_flight[2];
	atomic_t in_flight[2];
#ifdef	CONFIG_SMP
	struct disk_stats __percpu *dkstats;
#else
@@ -370,21 +370,21 @@ static inline void free_part_stats(struct hd_struct *part)

static inline void part_inc_in_flight(struct hd_struct *part, int rw)
{
	part->in_flight[rw]++;
	atomic_inc(&part->in_flight[rw]);
	if (part->partno)
		part_to_disk(part)->part0.in_flight[rw]++;
		atomic_inc(&part_to_disk(part)->part0.in_flight[rw]);
}

static inline void part_dec_in_flight(struct hd_struct *part, int rw)
{
	part->in_flight[rw]--;
	atomic_dec(&part->in_flight[rw]);
	if (part->partno)
		part_to_disk(part)->part0.in_flight[rw]--;
		atomic_dec(&part_to_disk(part)->part0.in_flight[rw]);
}

static inline int part_in_flight(struct hd_struct *part)
{
	return part->in_flight[0] + part->in_flight[1];
	return atomic_read(&part->in_flight[0]) + atomic_read(&part->in_flight[1]);
}

static inline struct partition_meta_info *alloc_part_info(struct gendisk *disk)