Re: [PATCH 2/8] md: add is_force parameter for some funcs

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 





On 11/5/19 10:56 PM, Song Liu wrote:
On Fri, Nov 1, 2019 at 7:23 AM <jgq516@xxxxxxxxx> wrote:
From: Guoqing Jiang <guoqing.jiang@xxxxxxxxxxxxxxx>

The related resources (spin_lock, list and waitqueue) are needed
for address raid1 reorder overlap issue too, so add "is_force"
parameter to funcs (mddev_create/destroy_serial_pool).
I don't think is_force is a good name. Maybe just call it "force"?

Naming is difficult to me :-), I can change it if you wish.

This parameter is set to true if we want to enable or disable
raid1 io serialization by writinng sysfs node (in later patch),
rdevs_init_serial is added and called when io serialization is
enabled.

Also rdev_init_serial and clear_bit(CollisionCheck, &rdev->flags)
should be called between suspend and resume.

Signed-off-by: Guoqing Jiang <guoqing.jiang@xxxxxxxxxxxxxxx>
---
  drivers/md/md-bitmap.c |  4 +--
  drivers/md/md.c        | 64 ++++++++++++++++++++++++++++--------------
  drivers/md/md.h        |  2 +-
  3 files changed, 46 insertions(+), 24 deletions(-)

diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c
index 5058716918ef..eff297cf5a81 100644
--- a/drivers/md/md-bitmap.c
+++ b/drivers/md/md-bitmap.c
@@ -1908,7 +1908,7 @@ int md_bitmap_load(struct mddev *mddev)
                 goto out;

         rdev_for_each(rdev, mddev)
-               mddev_create_serial_pool(mddev, rdev, true);
+               mddev_create_serial_pool(mddev, rdev, true, false);

         if (mddev_is_clustered(mddev))
                 md_cluster_ops->load_bitmaps(mddev, mddev->bitmap_info.nodes);
@@ -2484,7 +2484,7 @@ backlog_store(struct mddev *mddev, const char *buf, size_t len)
                 struct md_rdev *rdev;

                 rdev_for_each(rdev, mddev)
-                       mddev_create_serial_pool(mddev, rdev, false);
+                       mddev_create_serial_pool(mddev, rdev, false, false);
         }
         if (old_mwb != backlog)
                 md_bitmap_update_sb(mddev->bitmap);
diff --git a/drivers/md/md.c b/drivers/md/md.c
index bbf10b9301b6..43b7da334e4a 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -127,9 +127,6 @@ static inline int speed_max(struct mddev *mddev)

  static int rdev_init_serial(struct md_rdev *rdev)
  {
-       if (rdev->bdev->bd_queue->nr_hw_queues == 1)
-               return 0;
-
         spin_lock_init(&rdev->serial_list_lock);
         INIT_LIST_HEAD(&rdev->serial_list);
         init_waitqueue_head(&rdev->serial_io_wait);
@@ -138,17 +135,27 @@ static int rdev_init_serial(struct md_rdev *rdev)
         return 1;
  }

+static void rdevs_init_serial(struct mddev *mddev)
+{
+       struct md_rdev *rdev;
+
+       rdev_for_each(rdev, mddev)
+               rdev_init_serial(rdev);
+}
+
  /*
- * Create serial_info_pool if rdev is the first multi-queue device flaged
- * with writemostly, also write-behind mode is enabled.
+ * Create serial_info_pool for raid1 under conditions:
+ * 1. rdev is the first multi-queue device flaged with writemostly,
+ *    also write-behind mode is enabled.
+ * 2. is_force is true which means we want to enable serialization
+ *    for normal raid1 array.
   */
  void mddev_create_serial_pool(struct mddev *mddev, struct md_rdev *rdev,
-                         bool is_suspend)
+                             bool is_suspend, bool is_force)
  {
-       if (mddev->bitmap_info.max_write_behind == 0)
-               return;
-
-       if (!test_bit(WriteMostly, &rdev->flags) || !rdev_init_serial(rdev))
+       if (!is_force && (mddev->bitmap_info.max_write_behind == 0 ||
+                         (rdev && (rdev->bdev->bd_queue->nr_hw_queues == 1 ||
+                                   !test_bit(WriteMostly, &rdev->flags)))))
                 return;

         if (mddev->serial_info_pool == NULL) {
@@ -156,6 +163,10 @@ void mddev_create_serial_pool(struct mddev *mddev, struct md_rdev *rdev,

                 if (!is_suspend)
                         mddev_suspend(mddev);
+               if (is_force)
+                       rdevs_init_serial(mddev);
+               if (!is_force && rdev)
+                       rdev_init_serial(rdev);
                 noio_flag = memalloc_noio_save();
                 mddev->serial_info_pool =
                         mempool_create_kmalloc_pool(NR_SERIAL_INFOS,
@@ -171,11 +182,13 @@ EXPORT_SYMBOL_GPL(mddev_create_serial_pool);

  /*
   * Destroy serial_info_pool if rdev is the last device flaged with
- * CollisionCheck.
+ * CollisionCheck, or is_force is true when we disable serialization
+ * for normal raid1.
   */
-static void mddev_destroy_serial_pool(struct mddev *mddev, struct md_rdev *rdev)
+static void mddev_destroy_serial_pool(struct mddev *mddev, struct md_rdev *rdev,
+                                     bool is_force)
I guess mddev_destroy_serial_pool() doesn't need an extra argument. We
can just to clear_bit, etc.. no?

Let me explain a little bit, the function are used in below cases:

1. write-behind mode is enabled and write-mostly device has multi queues,
the pool should be destroyed if the last device flagged with CollisionCheck
is removed from array, or the write-mostly flag will be cleared from the last
device.

2. if we want to enable/disable serialization for normal raid1 in later patch,
which means the pool could be created/destroyed whether bitmap is existed
or not, and all member device should be flagged with CollisionCheck.

The new argument is introduced to distinguish the two cases.

Thanks,
Guoqing



[Index of Archives]     [Linux RAID Wiki]     [ATA RAID]     [Linux SCSI Target Infrastructure]     [Linux Block]     [Linux IDE]     [Linux SCSI]     [Linux Hams]     [Device Mapper]     [Device Mapper Cryptographics]     [Kernel]     [Linux Admin]     [Linux Net]     [GFS]     [RPM]     [git]     [Yosemite Forum]


  Powered by Linux