From d41647e6fa08ba1359844db8be57474e7edb05f9 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Fri, 13 Nov 2020 08:33:50 -0700 Subject: [PATCH] Wrap thread_data in thread_segment 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 --- backend.c | 3 +-- fio.h | 16 +++++++++++----- gettime-thread.c | 2 +- init.c | 45 +++++++++++++++++++++++---------------------- server.c | 2 +- 5 files changed, 37 insertions(+), 31 deletions(-) diff --git a/backend.c b/backend.c index f91f3caf..d2b97db0 100644 --- 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 9d189eb8..691976a3 100644 --- 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]; \ diff --git a/gettime-thread.c b/gettime-thread.c index 953e4e67..9b82e537 100644 --- a/gettime-thread.c +++ b/gettime-thread.c @@ -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 7f64ce21..36b10eaa 100644 --- 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--; } diff --git a/server.c b/server.c index 248a2d44..c9b5c285 100644 --- 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; -- 2.25.1