On 2019/12/31 22:55, houtao (A) wrote:
diff --git a/block/genhd.c b/block/genhd.c index 6e8543ca6912..179e0056fae1 100644 --- a/block/genhd.c +++ b/block/genhd.c @@ -279,7 +279,14 @@ struct hd_struct *disk_map_sector_rcu(struct gendisk *disk, sector_t sector) part = rcu_dereference(ptbl->part[i]); if (part && sector_in_part(part, sector)) { - rcu_assign_pointer(ptbl->last_lookup, part); + struct hd_struct *old; + + if (!hd_struct_try_get(part)) + break; + + old = xchg(&ptbl->last_lookup, part); + if (old) + hd_struct_put(old); return part; } } @@ -1231,7 +1238,11 @@ static void disk_replace_part_tbl(struct gendisk *disk, rcu_assign_pointer(disk->part_tbl, new_ptbl); if (old_ptbl) { - rcu_assign_pointer(old_ptbl->last_lookup, NULL); + struct hd_struct *part; + + part = xchg(&old_ptbl->last_lookup, NULL); + if (part) + hd_struct_put(part); kfree_rcu(old_ptbl, rcu_head); } } diff --git a/block/partition-generic.c b/block/partition-generic.c index 98d60a59b843..441c1c591c04 100644 --- a/block/partition-generic.c +++ b/block/partition-generic.c @@ -285,7 +285,8 @@ void delete_partition(struct gendisk *disk, int partno) return; rcu_assign_pointer(ptbl->part[partno], NULL); - rcu_assign_pointer(ptbl->last_lookup, NULL); + if (cmpxchg(&ptbl->last_lookup, part, NULL) == part) + hd_struct_put(part); kobject_put(part->holder_dir); device_del(part_to_dev(part));
This change will add more calling of hd_struct_try_get()/hd_struct_put() when set last_lookup. Thus, Tao warried abort extra overhead. We test the patch on a SSD disk by fio with config: [global] rw=randread bs=4k numjobs=2 ioengine=libaio iodepth=32 direct=1 runtime=120 size=100G group_reporting time_based [sda1] filename=/dev/sda1 [sda2] filename=/dev/sda2 [sda3] filename=/dev/sda3 [sda4] filename=/dev/sda4 Compared with the previous version, io bandwidth have no any degeneration. Thanks, Yufen