diff --git a/src/plugins/select/bluegene/bgl_job_run.c b/src/plugins/select/bluegene/bgl_job_run.c index 95015fec8a535a1adf662f88d3951eeec12a997f..27c7806c733fa2bde8fc154ca46f76dc0e1ee6cd 100644 --- a/src/plugins/select/bluegene/bgl_job_run.c +++ b/src/plugins/select/bluegene/bgl_job_run.c @@ -68,10 +68,13 @@ typedef struct bgl_update { pm_partition_id_t bgl_part_id; } bgl_update_t; -List bgl_update_list = NULL; +static List bgl_update_list = NULL; static pthread_mutex_t agent_cnt_mutex = PTHREAD_MUTEX_INITIALIZER; +static pthread_mutex_t freed_cnt_mutex = PTHREAD_MUTEX_INITIALIZER; static int agent_cnt = 0; +static int num_part_to_free = 0; +static int num_part_freed = 0; static void _bgl_list_del(void *x); static int _excise_block(List block_list, @@ -79,6 +82,7 @@ static int _excise_block(List block_list, char *nodes); static List _get_all_blocks(void); static void * _part_agent(void *args); +static void * _mult_free_part(void *args); static void _part_op(bgl_update_t *bgl_update_ptr); static int _remove_job(db_job_id_t job_id); static void _start_agent(bgl_update_t *bgl_update_ptr); @@ -219,9 +223,12 @@ static void _start_agent(bgl_update_t *bgl_update_ptr) bgl_record_t *found_record = NULL; char *user_name = uid_to_string(bgl_update_ptr->uid); ListIterator itr; + pthread_attr_t attr_agent; + pthread_t thread_agent; + int retries; bgl_record = find_bgl_record(bgl_update_ptr->bgl_part_id); - + if(!bgl_record) { error("partition %s not found in bgl_list", bgl_update_ptr->bgl_part_id); @@ -235,20 +242,37 @@ static void _start_agent(bgl_update_t *bgl_update_ptr) } if(bgl_record->state == RM_PARTITION_FREE) { + num_part_to_free = 0; + num_part_freed = 0; itr = list_iterator_create(bgl_list); if(bgl_record->full_partition) { debug("Using full partition freeing all others"); while ((found_record = (bgl_record_t*) list_next(itr)) != NULL) { if(found_record->state != RM_PARTITION_FREE) { - if (!found_record->full_partition) { - debug("destroying the " - "partition %s.", - found_record-> - bgl_part_id); - bgl_free_partition( - found_record); + slurm_attr_init(&attr_agent); + if (pthread_attr_setdetachstate( + &attr_agent, + PTHREAD_CREATE_JOINABLE)) + error("pthread_attr_setdetach" + "state error %m"); + + retries = 0; + while (pthread_create(&thread_agent, + &attr_agent, + _mult_free_part, + (void *) + found_record)) { + error("pthread_create " + "error %m"); + if (++retries + > MAX_PTHREAD_RETRIES) + fatal("Can't create " + "pthread"); + /* sleep and retry */ + usleep(1000); } + num_part_to_free++; } } } else { @@ -269,7 +293,9 @@ static void _start_agent(bgl_update_t *bgl_update_ptr) } } list_iterator_destroy(itr); - + + while(num_part_to_free != num_part_freed) + usleep(1000); if((rc = boot_part(bgl_record, bgl_update_ptr->node_use)) != SLURM_SUCCESS) { @@ -438,6 +464,21 @@ static void *_part_agent(void *args) return NULL; } +/* Free multiple partitions in parallel */ +static void *_mult_free_part(void *args) +{ + bgl_record_t *bgl_record = (bgl_record_t*) args; + + debug("destroying the partition %s.", bgl_record->bgl_part_id); + bgl_free_partition(bgl_record); + + slurm_mutex_lock(&freed_cnt_mutex); + num_part_freed++; + slurm_mutex_unlock(&freed_cnt_mutex); + + return NULL; +} + /* Perform an operation upon a BGL partition (block) for starting or * terminating a job */ static void _part_op(bgl_update_t *bgl_update_ptr) diff --git a/src/plugins/select/bluegene/sfree.c b/src/plugins/select/bluegene/sfree.c index f8aa355a3b8704d70486ccf81d84ac78a875fc05..82a771586bfa758c76dd23b94df53ee6a7c6ee26 100644 --- a/src/plugins/select/bluegene/sfree.c +++ b/src/plugins/select/bluegene/sfree.c @@ -29,16 +29,24 @@ #define MAX_POLL_RETRIES 110 #define POLL_INTERVAL 3 +#define MAX_PTHREAD_RETRIES 1 /* Globals */ + char *bgl_part_id = NULL; int all_parts = 0; +#ifdef HAVE_BGL_FILES + +static int num_part_to_free = 0; +static int num_part_freed = 0; +static pthread_mutex_t freed_cnt_mutex = PTHREAD_MUTEX_INITIALIZER; + + /************ * Functions * ************/ -#ifdef HAVE_BGL_FILES static int _free_partition(char *bgl_part_id); @@ -47,6 +55,21 @@ static void _term_jobs_on_part(char *bgl_part_id); static char *_bgl_err_str(status_t inx); static int _remove_job(db_job_id_t job_id); +/* Free multiple partitions in parallel */ +static void *_mult_free_part(void *args) +{ + char *bgl_part_id = (char *) args; + + debug("destroying the partition %s.", bgl_part_id); + _free_partition(bgl_part_id); + + slurm_mutex_lock(&freed_cnt_mutex); + num_part_freed++; + slurm_mutex_unlock(&freed_cnt_mutex); + + return NULL; +} + int main(int argc, char *argv[]) { log_options_t opts = LOG_OPTS_STDERR_ONLY; @@ -55,7 +78,10 @@ int main(int argc, char *argv[]) int j, num_parts = 0; rm_partition_t *part_ptr = NULL; int rc; - + pthread_attr_t attr_agent; + pthread_t thread_agent; + int retries; + log_init(xbasename(argv[0]), opts, SYSLOG_FACILITY_DAEMON, NULL); parse_command_line(argc, argv); if(!all_parts) { @@ -67,7 +93,8 @@ int main(int argc, char *argv[]) } else { if ((rc = rm_get_partitions_info(part_state, &part_list)) != STATUS_OK) { - error("rm_get_partitions_info(): %s", _bgl_err_str(rc)); + error("rm_get_partitions_info(): %s", + _bgl_err_str(rc)); return -1; } @@ -113,13 +140,40 @@ int main(int argc, char *argv[]) } if(strncmp("RMP", bgl_part_id, 3)) continue; - _free_partition(bgl_part_id); + slurm_attr_init(&attr_agent); + if (pthread_attr_setdetachstate( + &attr_agent, + PTHREAD_CREATE_JOINABLE)) + error("pthread_attr_setdetach" + "state error %m"); + + retries = 0; + while (pthread_create(&thread_agent, + &attr_agent, + _mult_free_part, + (void *) + bgl_part_id)) { + error("pthread_create " + "error %m"); + if (++retries + > MAX_PTHREAD_RETRIES) + fatal("Can't create " + "pthread"); + /* sleep and retry */ + usleep(1000); + } + num_part_to_free++; } if ((rc = rm_free_partition_list(part_list)) != STATUS_OK) { error("rm_free_partition_list(): %s", _bgl_err_str(rc)); } } + while(num_part_to_free != num_part_freed) { + info("waiting for all partitions to free..."); + sleep(1); + } + return 0; } @@ -132,7 +186,7 @@ static int _free_partition(char *bgl_part_id) _term_jobs_on_part(bgl_part_id); while (1) { if((state = _update_bgl_record_state(bgl_part_id)) - == SLURM_ERROR) + == -1) break; if (state != RM_PARTITION_FREE && state != RM_PARTITION_DEALLOCATING) { @@ -164,7 +218,7 @@ static int _update_bgl_record_state(char *bgl_part_id) char *name = NULL; rm_partition_list_t *part_list = NULL; int j, rc, num_parts = 0; - rm_partition_state_t state = -1; + rm_partition_state_t state = -2; rm_partition_t *part_ptr = NULL; if ((rc = rm_get_partitions_info(part_state, &part_list)) @@ -179,7 +233,7 @@ static int _update_bgl_record_state(char *bgl_part_id) state = -1; num_parts = 0; } - + for (j=0; j<num_parts; j++) { if (j) { if ((rc = rm_get_data(part_list,