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: Shaohua Li<shaohua.li@intel.com>
Signed-off-by: Jens Axboe <jaxboe@fusionio.com>
This commit is contained in:
Shaohua Li 2011-03-22 08:35:35 +01:00 committed by Jens Axboe
parent 5e84ea3a9c
commit 1e9bb8808a
3 changed files with 12 additions and 10 deletions

View File

@ -477,7 +477,8 @@ static void start_io_acct(struct dm_io *io)
cpu = part_stat_lock(); cpu = part_stat_lock();
part_round_stats(cpu, &dm_disk(md)->part0); part_round_stats(cpu, &dm_disk(md)->part0);
part_stat_unlock(); 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) 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 * After this is decremented the bio must not be touched if it is
* a flush. * a flush.
*/ */
dm_disk(md)->part0.in_flight[rw] = pending = pending = atomic_dec_return(&md->pending[rw]);
atomic_dec_return(&md->pending[rw]); atomic_set(&dm_disk(md)->part0.in_flight[rw], pending);
pending += atomic_read(&md->pending[rw^0x1]); pending += atomic_read(&md->pending[rw^0x1]);
/* nudge anyone waiting on suspend queue */ /* nudge anyone waiting on suspend queue */

View File

@ -290,7 +290,8 @@ ssize_t part_inflight_show(struct device *dev,
{ {
struct hd_struct *p = dev_to_part(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 #ifdef CONFIG_FAIL_MAKE_REQUEST

View File

@ -109,7 +109,7 @@ struct hd_struct {
int make_it_fail; int make_it_fail;
#endif #endif
unsigned long stamp; unsigned long stamp;
int in_flight[2]; atomic_t in_flight[2];
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
struct disk_stats __percpu *dkstats; struct disk_stats __percpu *dkstats;
#else #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) 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) 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) 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) 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) 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) static inline struct partition_meta_info *alloc_part_info(struct gendisk *disk)