client/server: convert ss_data to use an offset instead of fixed position
authorNiklas Cassel <niklas.cassel@wdc.com>
Thu, 3 Feb 2022 19:28:25 +0000 (19:28 +0000)
committerJens Axboe <axboe@kernel.dk>
Thu, 3 Feb 2022 22:30:06 +0000 (15:30 -0700)
Store the location of the ss_data in the payload itself, rather than
assuming that it is always located at a fixed location, directly after
the cmd_ts_pdu data.

This is done as a cleanup patch in order to be able to handle
clat_prio_stats, which just like ss_data, may or may not be part of the
payload.

Server version is intentionally not incremented, as it will be incremented
in a later patch in the series. No need to bump it multiple times for the
same patch series.

Signed-off-by: Niklas Cassel <niklas.cassel@wdc.com>
Reviewed-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
Link: https://lore.kernel.org/r/20220203192814.18552-5-Niklas.Cassel@wdc.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
client.c
server.c
stat.h

index 83be6a57bfd5c8a6bd1b6b0d2ad1d44a59af8822..cf082c74e689500d4829544133407bc50e76b1ac 100644 (file)
--- a/client.c
+++ b/client.c
@@ -1762,7 +1762,6 @@ int fio_handle_client(struct fio_client *client)
 {
        struct client_ops *ops = client->ops;
        struct fio_net_cmd *cmd;
-       int size;
 
        dprint(FD_NET, "client: handle %s\n", client->hostname);
 
@@ -1796,14 +1795,17 @@ int fio_handle_client(struct fio_client *client)
                }
        case FIO_NET_CMD_TS: {
                struct cmd_ts_pdu *p = (struct cmd_ts_pdu *) cmd->payload;
+               uint64_t offset;
 
                dprint(FD_NET, "client: ts->ss_state = %u\n", (unsigned int) le32_to_cpu(p->ts.ss_state));
                if (le32_to_cpu(p->ts.ss_state) & FIO_SS_DATA) {
                        dprint(FD_NET, "client: received steadystate ring buffers\n");
 
-                       size = le64_to_cpu(p->ts.ss_dur);
-                       p->ts.ss_iops_data = (uint64_t *) ((struct cmd_ts_pdu *)cmd->payload + 1);
-                       p->ts.ss_bw_data = p->ts.ss_iops_data + size;
+                       offset = le64_to_cpu(p->ts.ss_iops_data_offset);
+                       p->ts.ss_iops_data = (uint64_t *)((char *)p + offset);
+
+                       offset = le64_to_cpu(p->ts.ss_bw_data_offset);
+                       p->ts.ss_bw_data = (uint64_t *)((char *)p + offset);
                }
 
                convert_ts(&p->ts, &p->ts);
index 6905df905088666fd6109da37d04e7a17d9b5e6b..05b65631fb9051952b7fa13a5ecb87406ee649ff 100644 (file)
--- a/server.c
+++ b/server.c
@@ -1685,8 +1685,10 @@ void fio_server_send_ts(struct thread_stat *ts, struct group_run_stats *rs)
 {
        struct cmd_ts_pdu p;
        int i, j, k;
-       void *ss_buf;
-       uint64_t *ss_iops, *ss_bw;
+       size_t ss_extra_size = 0;
+       size_t extended_buf_size = 0;
+       void *extended_buf;
+       void *extended_buf_wp;
 
        dprint(FD_NET, "server sending end stats\n");
 
@@ -1810,26 +1812,53 @@ void fio_server_send_ts(struct thread_stat *ts, struct group_run_stats *rs)
        convert_gs(&p.rs, rs);
 
        dprint(FD_NET, "ts->ss_state = %d\n", ts->ss_state);
-       if (ts->ss_state & FIO_SS_DATA) {
-               dprint(FD_NET, "server sending steadystate ring buffers\n");
+       if (ts->ss_state & FIO_SS_DATA)
+               ss_extra_size = 2 * ts->ss_dur * sizeof(uint64_t);
 
-               ss_buf = malloc(sizeof(p) + 2*ts->ss_dur*sizeof(uint64_t));
+       extended_buf_size += ss_extra_size;
+       if (!extended_buf_size) {
+               fio_net_queue_cmd(FIO_NET_CMD_TS, &p, sizeof(p), NULL, SK_F_COPY);
+               return;
+       }
 
-               memcpy(ss_buf, &p, sizeof(p));
+       extended_buf_size += sizeof(p);
+       extended_buf = calloc(1, extended_buf_size);
+       if (!extended_buf) {
+               log_err("fio: failed to allocate FIO_NET_CMD_TS buffer\n");
+               return;
+       }
+
+       memcpy(extended_buf, &p, sizeof(p));
+       extended_buf_wp = (struct cmd_ts_pdu *)extended_buf + 1;
 
-               ss_iops = (uint64_t *) ((struct cmd_ts_pdu *)ss_buf + 1);
-               ss_bw = ss_iops + (int) ts->ss_dur;
-               for (i = 0; i < ts->ss_dur; i++) {
+       if (ss_extra_size) {
+               uint64_t *ss_iops, *ss_bw;
+               uint64_t offset;
+               struct cmd_ts_pdu *ptr = extended_buf;
+
+               dprint(FD_NET, "server sending steadystate ring buffers\n");
+
+               /* ss iops */
+               ss_iops = (uint64_t *) extended_buf_wp;
+               for (i = 0; i < ts->ss_dur; i++)
                        ss_iops[i] = cpu_to_le64(ts->ss_iops_data[i]);
-                       ss_bw[i] = cpu_to_le64(ts->ss_bw_data[i]);
-               }
 
-               fio_net_queue_cmd(FIO_NET_CMD_TS, ss_buf, sizeof(p) + 2*ts->ss_dur*sizeof(uint64_t), NULL, SK_F_COPY);
+               offset = (char *)extended_buf_wp - (char *)extended_buf;
+               ptr->ts.ss_iops_data_offset = cpu_to_le64(offset);
+               extended_buf_wp = ss_iops + (int) ts->ss_dur;
+
+               /* ss bw */
+               ss_bw = extended_buf_wp;
+               for (i = 0; i < ts->ss_dur; i++)
+                       ss_bw[i] = cpu_to_le64(ts->ss_bw_data[i]);
 
-               free(ss_buf);
+               offset = (char *)extended_buf_wp - (char *)extended_buf;
+               ptr->ts.ss_bw_data_offset = cpu_to_le64(offset);
+               extended_buf_wp = ss_bw + (int) ts->ss_dur;
        }
-       else
-               fio_net_queue_cmd(FIO_NET_CMD_TS, &p, sizeof(p), NULL, SK_F_COPY);
+
+       fio_net_queue_cmd(FIO_NET_CMD_TS, extended_buf, extended_buf_size, NULL, SK_F_COPY);
+       free(extended_buf);
 }
 
 void fio_server_send_gs(struct group_run_stats *rs)
diff --git a/stat.h b/stat.h
index 3ce821a701a11f8c8149e3de0b889252cb8e7735..5fa20f7441010d0d6f9c8d0862ad0583c4357b0c 100644 (file)
--- a/stat.h
+++ b/stat.h
@@ -262,11 +262,21 @@ struct thread_stat {
 
        union {
                uint64_t *ss_iops_data;
+               /*
+                * For FIO_NET_CMD_TS, the pointed to data will temporarily
+                * be stored at this offset from the start of the payload.
+                */
+               uint64_t ss_iops_data_offset;
                uint64_t pad4;
        };
 
        union {
                uint64_t *ss_bw_data;
+               /*
+                * For FIO_NET_CMD_TS, the pointed to data will temporarily
+                * be stored at this offset from the start of the payload.
+                */
+               uint64_t ss_bw_data_offset;
                uint64_t pad5;
        };