Wrap thread_data in thread_segment
authorJens Axboe <axboe@kernel.dk>
Fri, 13 Nov 2020 15:33:50 +0000 (08:33 -0700)
committerJens Axboe <axboe@kernel.dk>
Fri, 13 Nov 2020 15:36:05 +0000 (08:36 -0700)
No functional changes in this patch, just in preparation for having
multiple shm segments for the thread_data structures. They are getting
very large, and since it's hard to know upfront how many we need, let's
instead refactor the code a bit to allow us to add chunks of them as
needed when parsing the job file (or command line).

Signed-off-by: Jens Axboe <axboe@kernel.dk>
backend.c
fio.h
gettime-thread.c
init.c
server.c

index f91f3caf9b7d82fe31b0385d5942a7b4f4414318..d2b97db07d6421372a0f2f87eee1b4528fbbe337 100644 (file)
--- a/backend.c
+++ b/backend.c
@@ -63,7 +63,6 @@ struct io_log *agg_io_log[DDIR_RWDIR_CNT];
 int groupid = 0;
 unsigned int thread_number = 0;
 unsigned int stat_number = 0;
-int shm_id = 0;
 int temp_stall_ts;
 unsigned long done_secs = 0;
 #ifdef PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
@@ -76,7 +75,7 @@ pthread_mutex_t overlap_check = PTHREAD_MUTEX_INITIALIZER;
 
 static void sig_int(int sig)
 {
-       if (threads) {
+       if (segments[0].threads) {
                if (is_backend)
                        fio_server_got_signal(sig);
                else {
diff --git a/fio.h b/fio.h
index 9d189eb878911fc2bb4a6e8c48e0384e2dacbef5..691976a3b58a8ebe4695800a018474247acdb4b9 100644 (file)
--- a/fio.h
+++ b/fio.h
@@ -467,6 +467,11 @@ struct thread_data {
 
 };
 
+struct thread_segment {
+       struct thread_data *threads;
+       int shm_id;
+};
+
 /*
  * when should interactive ETA output be generated
  */
@@ -510,10 +515,13 @@ enum {
 #define __fio_stringify_1(x)   #x
 #define __fio_stringify(x)     __fio_stringify_1(x)
 
+#define REAL_MAX_JOBS          4096
+#define JOBS_PER_SEG           8
+#define REAL_MAX_SEG           (REAL_MAX_JOBS / JOBS_PER_SEG)
+
 extern bool exitall_on_terminate;
 extern unsigned int thread_number;
 extern unsigned int stat_number;
-extern int shm_id;
 extern int groupid;
 extern int output_format;
 extern int append_terse_output;
@@ -542,7 +550,7 @@ extern char *trigger_remote_cmd;
 extern long long trigger_timeout;
 extern char *aux_path;
 
-extern struct thread_data *threads;
+extern struct thread_segment segments[REAL_MAX_SEG];
 
 static inline bool is_running_backend(void)
 {
@@ -557,8 +565,6 @@ static inline void fio_ro_check(const struct thread_data *td, struct io_u *io_u)
               !(io_u->ddir == DDIR_TRIM && !td_trim(td)));
 }
 
-#define REAL_MAX_JOBS          4096
-
 static inline bool should_fsync(struct thread_data *td)
 {
        if (td->last_was_sync)
@@ -709,7 +715,7 @@ extern void lat_target_reset(struct thread_data *);
  * Iterates all threads/processes within all the defined jobs
  */
 #define for_each_td(td, i)     \
-       for ((i) = 0, (td) = &threads[0]; (i) < (int) thread_number; (i)++, (td)++)
+       for ((i) = 0, (td) = &segments[0].threads[0]; (i) < (int) thread_number; (i)++, (td)++)
 #define for_each_file(td, f, i)        \
        if ((td)->files_index)                                          \
                for ((i) = 0, (f) = (td)->files[0];                     \
index 953e4e67e36db81e39aae9bb073b332f8bd373ab..9b82e537220e703d2c00c7342ce8bfef3223a656 100644 (file)
@@ -58,7 +58,7 @@ static void *gtod_thread_main(void *data)
         * but I'm not sure what to use outside of a simple CPU nop to relax
         * it - we don't want to lose precision.
         */
-       while (threads) {
+       while (segments[0].threads) {
                fio_gtod_update();
                nop;
        }
diff --git a/init.c b/init.c
index 7f64ce21a36aec1bedf4d609f7cb63866923643a..36b10eaad13025d95cab46368323af2440e52d52 100644 (file)
--- a/init.c
+++ b/init.c
@@ -51,7 +51,7 @@ static bool parse_only;
 static bool merge_blktrace_only;
 
 static struct thread_data def_thread;
-struct thread_data *threads = NULL;
+struct thread_segment segments[REAL_MAX_SEG];
 static char **job_sections;
 static int nr_job_sections;
 
@@ -301,17 +301,17 @@ static struct option l_opts[FIO_NR_OPTIONS] = {
 
 void free_threads_shm(void)
 {
-       if (threads) {
-               void *tp = threads;
+       if (segments[0].threads) {
+               void *tp = segments[0].threads;
 #ifndef CONFIG_NO_SHM
                struct shmid_ds sbuf;
 
-               threads = NULL;
+               segments[0].threads = NULL;
                shmdt(tp);
-               shmctl(shm_id, IPC_RMID, &sbuf);
-               shm_id = -1;
+               shmctl(segments[0].shm_id, IPC_RMID, &sbuf);
+               segments[0].shm_id = -1;
 #else
-               threads = NULL;
+               segments[0].threads = NULL;
                free(tp);
 #endif
        }
@@ -319,7 +319,7 @@ void free_threads_shm(void)
 
 static void free_shm(void)
 {
-       if (threads) {
+       if (segments[0].threads) {
                flow_exit();
                fio_debug_jobp = NULL;
                fio_warned = NULL;
@@ -345,9 +345,10 @@ static void free_shm(void)
  */
 static int setup_thread_area(void)
 {
+       struct thread_segment *seg = &segments[0];
        int i;
 
-       if (threads)
+       if (seg->threads)
                return 0;
 
        /*
@@ -360,16 +361,16 @@ static int setup_thread_area(void)
                size += 2 * sizeof(unsigned int);
 
 #ifndef CONFIG_NO_SHM
-               shm_id = shmget(0, size, IPC_CREAT | 0600);
-               if (shm_id != -1)
+               seg->shm_id = shmget(0, size, IPC_CREAT | 0600);
+               if (seg->shm_id != -1)
                        break;
                if (errno != EINVAL && errno != ENOMEM && errno != ENOSPC) {
                        perror("shmget");
                        break;
                }
 #else
-               threads = malloc(size);
-               if (threads)
+               seg->threads = malloc(size);
+               if (seg->threads)
                        break;
 #endif
 
@@ -377,22 +378,22 @@ static int setup_thread_area(void)
        } while (max_jobs);
 
 #ifndef CONFIG_NO_SHM
-       if (shm_id == -1)
+       if (seg->shm_id == -1)
                return 1;
 
-       threads = shmat(shm_id, NULL, 0);
-       if (threads == (void *) -1) {
+       seg->threads = shmat(seg->shm_id, NULL, 0);
+       if (seg->threads == (void *) -1) {
                perror("shmat");
                return 1;
        }
        if (shm_attach_to_open_removed())
-               shmctl(shm_id, IPC_RMID, NULL);
+               shmctl(seg->shm_id, IPC_RMID, NULL);
 #endif
 
-       memset(threads, 0, max_jobs * sizeof(struct thread_data));
+       memset(seg->threads, 0, max_jobs * sizeof(struct thread_data));
        for (i = 0; i < max_jobs; i++)
-               DRD_IGNORE_VAR(threads[i]);
-       fio_debug_jobp = (unsigned int *)(threads + max_jobs);
+               DRD_IGNORE_VAR(seg->threads[i]);
+       fio_debug_jobp = (unsigned int *)(seg->threads + max_jobs);
        *fio_debug_jobp = -1;
        fio_warned = fio_debug_jobp + 1;
        *fio_warned = 0;
@@ -484,7 +485,7 @@ static struct thread_data *get_new_job(bool global, struct thread_data *parent,
                return NULL;
        }
 
-       td = &threads[thread_number++];
+       td = &segments[0].threads[thread_number++];
        *td = *parent;
 
        INIT_FLIST_HEAD(&td->opt_list);
@@ -534,7 +535,7 @@ static void put_job(struct thread_data *td)
        if (td->o.name)
                free(td->o.name);
 
-       memset(&threads[td->thread_number - 1], 0, sizeof(*td));
+       memset(td, 0, sizeof(*td));
        thread_number--;
 }
 
index 248a2d44899c5c6191f83248209057e1980f01e2..c9b5c2856a80295d529d47e98cab93176149c09e 100644 (file)
--- a/server.c
+++ b/server.c
@@ -950,7 +950,7 @@ static int handle_update_job_cmd(struct fio_net_cmd *cmd)
                return 0;
        }
 
-       td = &threads[tnumber - 1];
+       td = &segments[0].threads[tnumber - 1];
        convert_thread_options_to_cpu(&td->o, &pdu->top);
        send_update_job_reply(cmd->tag, 0);
        return 0;