dataplacement: update ruh info initialization
authorAnkit Kumar <ankit.kumar@samsung.com>
Mon, 15 Jul 2024 08:21:04 +0000 (13:51 +0530)
committerVincent Fu <vincent.fu@samsung.com>
Mon, 15 Jul 2024 19:48:53 +0000 (15:48 -0400)
The current way of initilization limits ruhs to 128. This commit
updates the way we fetch ruhs. We now fetch the ruhs info in two steps.
The first step only gets us the number of ruhs from the ioengine. This
is used by fdp backend to allocate the correct buffer size for the
second step, where we fetch the actual ruhs info. Fio no longer limits
the maximum number of ruhs for a device.

Signed-off-by: Ankit Kumar <ankit.kumar@samsung.com>
Signed-off-by: Vincent Fu <vincent.fu@samsung.com>
[Vincent: edited commit message]

dataplacement.c

index 8a4c8e64419c33e0912b6e921fb6ec6561abbca5..ec1427c843214d60a33ca5d99571abc23e49d39a 100644 (file)
@@ -43,18 +43,19 @@ static int fdp_ruh_info(struct thread_data *td, struct fio_file *f,
 static int init_ruh_info(struct thread_data *td, struct fio_file *f)
 {
        struct fio_ruhs_info *ruhs, *tmp;
+       uint32_t nr_ruhs;
        int i, ret;
 
-       ruhs = scalloc(1, sizeof(*ruhs) + FDP_MAX_RUHS * sizeof(*ruhs->plis));
-       if (!ruhs)
-               return -ENOMEM;
-
        /* set up the data structure used for FDP to work with the supplied stream IDs */
        if (td->o.dp_type == FIO_DP_STREAMS) {
                if (!td->o.dp_nr_ids) {
                        log_err("fio: stream IDs must be provided for dataplacement=streams\n");
                        return -EINVAL;
                }
+               ruhs = scalloc(1, sizeof(*ruhs) + FDP_MAX_RUHS * sizeof(*ruhs->plis));
+               if (!ruhs)
+                       return -ENOMEM;
+
                ruhs->nr_ruhs = td->o.dp_nr_ids;
                for (int i = 0; i < ruhs->nr_ruhs; i++)
                        ruhs->plis[i] = td->o.dp_ids[i];
@@ -63,6 +64,11 @@ static int init_ruh_info(struct thread_data *td, struct fio_file *f)
                return 0;
        }
 
+       /*
+        * Since we don't know the actual number of ruhs. Only fetch the header.
+        * We will reallocate this buffer and then fetch all the ruhs again.
+        */
+       ruhs = calloc(1, sizeof(*ruhs));
        ret = fdp_ruh_info(td, f, ruhs);
        if (ret) {
                log_info("fio: ruh info failed for %s (%d)\n",
@@ -70,19 +76,38 @@ static int init_ruh_info(struct thread_data *td, struct fio_file *f)
                goto out;
        }
 
-       if (ruhs->nr_ruhs > FDP_MAX_RUHS)
-               ruhs->nr_ruhs = FDP_MAX_RUHS;
+       nr_ruhs = ruhs->nr_ruhs;
+       ruhs = realloc(ruhs, sizeof(*ruhs) + nr_ruhs * sizeof(*ruhs->plis));
+       if (!ruhs) {
+               log_info("fio: ruhs buffer realloc failed for %s\n",
+                        f->file_name);
+               ret = -ENOMEM;
+               goto out;
+       }
 
-       if (td->o.dp_nr_ids == 0) {
-               f->ruhs_info = ruhs;
-               return 0;
+       ruhs->nr_ruhs = nr_ruhs;
+       ret = fdp_ruh_info(td, f, ruhs);
+       if (ret) {
+               log_info("fio: ruh info failed for %s (%d)\n",
+                        f->file_name, -ret);
+               goto out;
        }
 
-       for (i = 0; i < td->o.dp_nr_ids; i++) {
-               if (td->o.dp_ids[i] >= ruhs->nr_ruhs) {
+       if (td->o.dp_nr_ids == 0) {
+               if (ruhs->nr_ruhs > FDP_MAX_RUHS)
+                       ruhs->nr_ruhs = FDP_MAX_RUHS;
+       } else {
+               if (td->o.dp_nr_ids > FDP_MAX_RUHS) {
                        ret = -EINVAL;
                        goto out;
                }
+               for (i = 0; i < td->o.dp_nr_ids; i++) {
+                       if (td->o.dp_ids[i] >= ruhs->nr_ruhs) {
+                               ret = -EINVAL;
+                               goto out;
+                       }
+               }
+               ruhs->nr_ruhs = td->o.dp_nr_ids;
        }
 
        tmp = scalloc(1, sizeof(*tmp) + ruhs->nr_ruhs * sizeof(*tmp->plis));
@@ -91,12 +116,23 @@ static int init_ruh_info(struct thread_data *td, struct fio_file *f)
                goto out;
        }
 
+       if (td->o.dp_nr_ids == 0) {
+               for (i = 0; i < ruhs->nr_ruhs; i++)
+                       tmp->plis[i] = ruhs->plis[i];
+
+               tmp->nr_ruhs = ruhs->nr_ruhs;
+               f->ruhs_info = tmp;
+               free(ruhs);
+
+               return 0;
+       }
+
        tmp->nr_ruhs = td->o.dp_nr_ids;
        for (i = 0; i < td->o.dp_nr_ids; i++)
                tmp->plis[i] = ruhs->plis[td->o.dp_ids[i]];
        f->ruhs_info = tmp;
 out:
-       sfree(ruhs);
+       free(ruhs);
        return ret;
 }