diff --git a/NEWS b/NEWS index 3d5b6268a8b5589aa3074e90a7eed31b53b02e1f..0f46e44bb0ae5dcf8ce562b6400aea4263a09066 100644 --- a/NEWS +++ b/NEWS @@ -182,6 +182,12 @@ documents those changes that are of interest to users and administrators. -- cgroup plugins - fix two minor memory leaks. -- If a node is booting for some job, don't allocate additional jobs to the node until the boot completes. + -- testsuite - fix job id output in test17.39. + -- Modify backfill algorithm to improve performance with large numbers of + running jobs. Group running jobs that end in a "similar" time frame using a + time window that grows exponentially rather than linearly. After one second + of wall time, simulate the termination of all remaining running jobs in + order to respond in a reasonable time frame. * Changes in Slurm 16.05.6 ========================== diff --git a/src/plugins/select/cons_res/select_cons_res.c b/src/plugins/select/cons_res/select_cons_res.c index bc08e2eea5a0c723db873287d4acbce96d096291..6874698c404bd3fbbdb38efe9373399dcef74d9e 100644 --- a/src/plugins/select/cons_res/select_cons_res.c +++ b/src/plugins/select/cons_res/select_cons_res.c @@ -1881,15 +1881,20 @@ static int _will_run_test(struct job_record *job_ptr, bitstr_t *bitmap, * pending job after each one (or a few jobs that end close in time). */ if ((rc != SLURM_SUCCESS) && ((job_ptr->bit_flags & TEST_NOW_ONLY) == 0)) { - int time_window = 0; + int time_window = 30; bool more_jobs = true; + bool timed_out = false; + DEF_TIMERS; + list_sort(cr_job_list, _cr_job_list_sort); + START_TIMER; job_iterator = list_iterator_create(cr_job_list); while (more_jobs) { struct job_record *first_job_ptr = NULL; struct job_record *last_job_ptr = NULL; struct job_record *next_job_ptr = NULL; int overlap, rm_job_cnt = 0; + while (true) { tmp_job_ptr = list_next(job_iterator); if (!tmp_job_ptr) { @@ -1908,21 +1913,23 @@ static int _will_run_test(struct job_record *job_ptr, bitstr_t *bitmap, last_job_ptr = tmp_job_ptr; _rm_job_from_res(future_part, future_usage, tmp_job_ptr, 0); - if (rm_job_cnt++ > 20) + if ((rm_job_cnt++ > 200) && !timed_out) break; next_job_ptr = list_peek_next(job_iterator); if (!next_job_ptr) { more_jobs = false; break; + } else if (timed_out) { + continue; } else if (next_job_ptr->end_time > (first_job_ptr->end_time + time_window)) { break; } } - if (!last_job_ptr) + if (!last_job_ptr) /* Should never happen */ break; - time_window += 60; + time_window *= 2; rc = cr_job_test(job_ptr, bitmap, min_nodes, max_nodes, req_nodes, SELECT_MODE_WILL_RUN, tmp_cr_type, @@ -1941,6 +1948,12 @@ static int _will_run_test(struct job_record *job_ptr, bitstr_t *bitmap, } break; } + /* After 1 second of iterating over groups of running + * jobs, simulate the termination of all remaining jobs + * in order to determine if pending job can ever run */ + END_TIMER; + if (DELTA_TIMER >= 1000000) + timed_out = true; } list_iterator_destroy(job_iterator); } diff --git a/testsuite/expect/test17.39 b/testsuite/expect/test17.39 index b612fcb136a4a7839c4da59371936d7d19d6b222..29ecde943ebf5326c0f3fa2d2f87302d36525954 100755 --- a/testsuite/expect/test17.39 +++ b/testsuite/expect/test17.39 @@ -182,7 +182,7 @@ wait_for_job $fast_id DONE # Wait for dependency job to start once the fast job is complete if {[wait_for_job $dep_id RUNNING]} { - send_user "\nFAILURE: job $dep_job should be running\n" + send_user "\nFAILURE: job $dep_id should be running\n" set exit_code 1 }