From d5826dd6002f23940458860701ce22fba9df2614 Mon Sep 17 00:00:00 2001 From: Jack Steiner Date: Wed, 17 Jun 2009 16:28:28 -0700 Subject: gru: add user request to explicitly unload a gru context Add user function to explicitly unload GRU kernel contexts from the GRU. Only contexts that are not in-use will be unloaded. This function is primarily for testing. It is not expected that this will be used in normal production systems. Signed-off-by: Jack Steiner Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/misc/sgi-gru/grukservices.c | 55 +++++++++++++++++++++++-------------- 1 file changed, 35 insertions(+), 20 deletions(-) (limited to 'drivers/misc/sgi-gru/grukservices.c') diff --git a/drivers/misc/sgi-gru/grukservices.c b/drivers/misc/sgi-gru/grukservices.c index 7586b89fd0d3..5078f57da882 100644 --- a/drivers/misc/sgi-gru/grukservices.c +++ b/drivers/misc/sgi-gru/grukservices.c @@ -187,6 +187,34 @@ static void gru_load_kernel_context(struct gru_blade_state *bs, int blade_id) downgrade_write(&bs->bs_kgts_sema); } +/* + * Free all kernel contexts that are not currently in use. + * Returns 0 if all freed, else number of inuse context. + */ +static int gru_free_kernel_contexts(void) +{ + struct gru_blade_state *bs; + struct gru_thread_state *kgts; + int bid, ret = 0; + + for (bid = 0; bid < GRU_MAX_BLADES; bid++) { + bs = gru_base[bid]; + if (!bs) + continue; + if (down_write_trylock(&bs->bs_kgts_sema)) { + kgts = bs->bs_kgts; + if (kgts && kgts->ts_gru) + gru_unload_context(kgts, 0); + kfree(kgts); + bs->bs_kgts = NULL; + up_write(&bs->bs_kgts_sema); + } else { + ret++; + } + } + return ret; +} + /* * Lock & load the kernel context for the specified blade. */ @@ -1009,35 +1037,22 @@ int gru_ktest(unsigned long arg) case 2: ret = quicktest2(arg); break; + case 99: + ret = gru_free_kernel_contexts(); + break; } return ret; } -int gru_kservices_init(struct gru_state *gru) +int gru_kservices_init(void) { - struct gru_blade_state *bs; - - bs = gru->gs_blade; - if (gru != &bs->bs_grus[0]) - return 0; - - init_rwsem(&bs->bs_kgts_sema); return 0; } -void gru_kservices_exit(struct gru_state *gru) +void gru_kservices_exit(void) { - struct gru_blade_state *bs; - struct gru_thread_state *kgts; - - bs = gru->gs_blade; - if (gru != &bs->bs_grus[0]) - return; - - kgts = bs->bs_kgts; - if (kgts && kgts->ts_gru) - gru_unload_context(kgts, 0); - kfree(kgts); + if (gru_free_kernel_contexts()) + BUG(); } -- cgit v1.2.3