From 5154fa1e6ae490f26049847b13c105f74fab3e4f Mon Sep 17 00:00:00 2001 From: Kris Van Hees Date: Thu, 12 Jan 2012 16:36:54 -0500 Subject: [PATCH] Fix for incorrect handling of BUFSIZE = 0. The handling of aggregations was flawed in that even without any ECBs with aggregation, the code logic was assuming there was at least one aggregation (the sentinel in the IDR). The handling of the aggregations IDR in the DTrace state has been updated to use an explicit counter because the IDR functionality does not provide us with an API function to determine the amount of elements in the IDR. Signed-off-by: Kris Van Hees --- dtrace/dtrace_ecb.c | 2 ++ dtrace/dtrace_state.c | 11 +++++------ 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/dtrace/dtrace_ecb.c b/dtrace/dtrace_ecb.c index 96463cccd2b2..8f91dae89f99 100644 --- a/dtrace/dtrace_ecb.c +++ b/dtrace/dtrace_ecb.c @@ -147,6 +147,7 @@ again: goto again; } + state->dts_naggs++; agg->dtag_id = aggid; frec = &agg->dtag_first->dta_rec; @@ -170,6 +171,7 @@ void dtrace_ecb_aggregation_destroy(dtrace_ecb_t *ecb, dtrace_action_t *act) ASSERT(DTRACEACT_ISAGG(act->dta_kind)); idr_remove(&state->dts_agg_idr, agg->dtag_id); + state->dts_naggs--; kfree(agg); } diff --git a/dtrace/dtrace_state.c b/dtrace/dtrace_state.c index 35e186a4209b..91ba3fbe2b8a 100644 --- a/dtrace/dtrace_state.c +++ b/dtrace/dtrace_state.c @@ -339,6 +339,7 @@ dtrace_state_t *dtrace_state_create(struct file *file) state->dts_buffer = kzalloc(bufsize, GFP_KERNEL); state->dts_aggbuffer = kzalloc(bufsize, GFP_KERNEL); idr_init(&state->dts_agg_idr); + state->dts_naggs = 0; state->dts_cleaner = 0; state->dts_deadman = 0; state->dts_vstate.dtvs_state = state; @@ -682,7 +683,7 @@ int dtrace_state_go(dtrace_state_t *state, processorid_t *cpu) if (opt[DTRACEOPT_AGGSIZE] != DTRACEOPT_UNSET && opt[DTRACEOPT_AGGSIZE] != 0) { - if (idr_empty(&state->dts_agg_idr)) { + if (state->dts_naggs == 0) { /* * We're not going to create an aggregation buffer * because we don't have any ECBs that contain @@ -718,7 +719,7 @@ int dtrace_state_go(dtrace_state_t *state, processorid_t *cpu) if ((state->dts_needed != 0 && opt[DTRACEOPT_BUFSIZE] < sz) || (state->dts_speculates && opt[DTRACEOPT_SPECSIZE] < sz) || - (!idr_empty(&state->dts_agg_idr) && opt[DTRACEOPT_AGGSIZE] < sz)) { + (state->dts_naggs != 0 && opt[DTRACEOPT_AGGSIZE] < sz)) { /* * A buffer size has been explicitly set to 0 (or to a size * that will be adjusted to 0) and we need the space -- we @@ -1050,10 +1051,8 @@ void dtrace_state_destroy(dtrace_state_t *state) * If there were aggregations allocated, they should have been cleaned * up by now, so we can get rid of the idr. */ - if (!idr_empty(&state->dts_agg_idr)) { - idr_remove_all(&state->dts_agg_idr); - idr_destroy(&state->dts_agg_idr); - } + idr_remove_all(&state->dts_agg_idr); + idr_destroy(&state->dts_agg_idr); kfree(state->dts_buffer); kfree(state->dts_aggbuffer); -- 2.50.1