block: remove rcu_read_lock() from part_stat_lock()
authorKonstantin Khlebnikov <khlebnikov@yandex-team.ru>
Wed, 27 May 2020 05:24:17 +0000 (07:24 +0200)
committerJens Axboe <axboe@kernel.dk>
Wed, 27 May 2020 11:21:23 +0000 (05:21 -0600)
The RCU lock is required only in disk_map_sector_rcu() to lookup the
partition.  After that request holds reference to related hd_struct.

Replace get_cpu() with preempt_disable() - returned cpu index is unused.

[hch: rebased]

Signed-off-by: Konstantin Khlebnikov <khlebnikov@yandex-team.ru>
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
block/genhd.c
include/linux/part_stat.h

index 3e7df0a..1a76593 100644 (file)
@@ -321,11 +321,12 @@ struct hd_struct *disk_map_sector_rcu(struct gendisk *disk, sector_t sector)
        struct hd_struct *part;
        int i;
 
+       rcu_read_lock();
        ptbl = rcu_dereference(disk->part_tbl);
 
        part = rcu_dereference(ptbl->last_lookup);
        if (part && sector_in_part(part, sector) && hd_struct_try_get(part))
-               return part;
+               goto out_unlock;
 
        for (i = 1; i < ptbl->len; i++) {
                part = rcu_dereference(ptbl->part[i]);
@@ -339,10 +340,14 @@ struct hd_struct *disk_map_sector_rcu(struct gendisk *disk, sector_t sector)
                        if (!hd_struct_try_get(part))
                                break;
                        rcu_assign_pointer(ptbl->last_lookup, part);
-                       return part;
+                       goto out_unlock;
                }
        }
-       return &disk->part0;
+
+       part = &disk->part0;
+out_unlock:
+       rcu_read_unlock();
+       return part;
 }
 
 /**
index 6644197..a6b0938 100644 (file)
@@ -21,8 +21,8 @@ struct disk_stats {
  *
  * part_stat_read() can be called at any time.
  */
-#define part_stat_lock()       ({ rcu_read_lock(); get_cpu(); })
-#define part_stat_unlock()     do { put_cpu(); rcu_read_unlock(); } while (0)
+#define part_stat_lock()       preempt_disable()
+#define part_stat_unlock()     preempt_enable()
 
 #define part_stat_get_cpu(part, field, cpu)                            \
        (per_cpu_ptr((part)->dkstats, (cpu))->field)