[DTrace-devel] [PATCH] Action clear() should clear only one aggregation
Eugene Loh
eugene.loh at oracle.com
Wed Aug 14 23:05:44 UTC 2024
On 8/14/24 18:28, Kris Van Hees wrote:
> On Wed, Aug 14, 2024 at 05:50:27PM -0400, Eugene Loh wrote:
>> On 8/14/24 11:57, Kris Van Hees wrote:
>>
>>> On Tue, Aug 13, 2024 at 10:59:25PM -0400, eugene.loh at oracle.com wrote:
>>>> From: Eugene Loh <eugene.loh at oracle.com>
>>>>
>>>> FIXME: Is libdtrace/libdtrace.ver correctly updated?
>> Incidentally, what has to be done in this file?
>>
>>> I think that keeping dtrace_aggregate_walk() as-is would be better, along with
>>> adding a function dtrace_aggregate_clear_one(dtp, aid) that performs the
>>> lookup from aid to dtrae_aggdata_t *agd, and then calls
>>> dt__aggregate_clear_one(agd, dtp) to do the actual clearing. There is no need
>>> to go through a walker function when we already know we need to operate on
>>> just one aggregation.
>> I'm not convinced.
>>
>> "Just one aggregation"? Yes, just one aggid, but possibly many keys. To
>> narrow down to which agd we want, we need to know the key -- and clear()
>> doesn't give us the key, plus there will generally be more than one key
>> anyhow.
> Ah true. I blanked on the fact that clear(@a) clears that aggregation, and
> any indexed aggregations with the same name (and thus same aid).
>
> Anyway, given that dtrace_aggregate_walk() is an API function that is exported
> by libdtrace, we should not change it.
>
> So, I'd propose that instead of introducing a new function, we can make use
> of the existing dtrace_aggregate_walk() by passing both dtp and the aid as an
> arg struct. E.g.
>
> typedef struct dt_clear_arg {
> dtrace_hdl_t *dtp;
> dtrace_aggid_t aid;
> } dt_clear_arg_t;
Hmm. Then both dt_consume.c and dt_aggregate.c need to know about this
new struct. So, copy it to both files? Introduce a new
dt_aggregate.h? Ick.
Maybe the thing to do is use dtrace_aggregate_walk() with a callback in
dt_consume.c. The callback can filter on the agg id and call
dt_aggregate_clear_one() accordingly... I *think* that works. Let me
know if you're on board with this approach.
> void
> dtrace_aggregate_clear(dtrace_hdl_t *dtp)
> {
> dt_clear_arg_t arg = { dtp, aid };
>
> dtrace_aggregate_walk(dtp, dt_aggregate_clear_one, &arg);
> }
>
> nd then dt_aggregate_clear_one() can check the aid and return if the aid
> is not IDNOE and does not match the one for the aggregation it is called for.
> That means you also need to change dt_aggregate_snap_one() but there you can
> also define that arg and set aid as IDNONE in that because we know that if we
> call dt_aggregate_clear_one() from here weknow it is for an aggregation that
> needs to be cleared.
>
>> Now, one can argue that in the current implementation and its current hash
>> function, the aggid tells us at least which hash bucket to search. So we
>> could write a special, reduced loop. Maybe so, but that would be wed to
>> this particular choice of hash function, and I'd argue the current choice is
>> a bad one. E.g., consider:
>>
>> tick-10 { @pc[uregs[R_PC]] = count() }
>> syscall::write:entry { @writeentry = count() }
>>
>> Lots of agd's will be sharing one bucket and another agd is sitting all by
>> itself. We ought to change the hash function, and then we'd have to undo
>> the "search just one bucket" optimization.
>>
>> PS Here is an oddity:
>>
>> # /usr/sbin/dtrace -n 'BEGIN { @a[1] = count(); @a[2] = count();
>> clear(@a[1]); exit(0); }'
>> dtrace: description 'BEGIN ' matched 1 probe
>> CPU ID FUNCTION:NAME
>> 34 1 :BEGIN
>>
>> 1 0
>> 2 0
>>
>> You *can* specify the key in the clear()! But dtrace ignores the key.
>> Silently. Same behavior in Solaris.
More information about the DTrace-devel
mailing list