pcp
[Top] [All Lists]

Re: PCP papi PMDA

To: Lukas Berk <lberk@xxxxxxxxxx>
Subject: Re: PCP papi PMDA
From: fche@xxxxxxxxxx (Frank Ch. Eigler)
Date: Thu, 03 Jul 2014 11:35:13 -0400
Cc: pcp@xxxxxxxxxxx
Delivered-to: pcp@xxxxxxxxxxx
In-reply-to: <20140702135330.GD12723@xxxxxxxxxx> (Lukas Berk's message of "Wed, 2 Jul 2014 09:53:31 -0400")
References: <20140625024307.GA9275@xxxxxxxxxx> <53B1AF59.9080506@xxxxxxxxxx> <20140702135330.GD12723@xxxxxxxxxx>
User-agent: Gnus/5.1008 (Gnus v5.10.8) Emacs/21.4 (gnu/linux)
Hi, Lukas -

Here's a more worked-out non-pmstore-proposal for automatic
activation of papi counters.

- as each client arrives to the pmda (papi_contextAttributeCallBack),
  simply store its uid/gid credentials; drop the wildcard/trackers[]
  bits from uid_gid_tuple; do not worry about getgrname() anything; do
  not perform access control calculations at this time

- as each client leaves the pmda (papi_end_contextCallBack), drop its
  ctxtab[] entry; do not change papi state at this time

- instead of a per-client trackers[], have a single global table to
  represent the kernel papi-eventset state, containing rows:
       - pmid
       - papi eventcode
       - a boolean enabled-flag
       - the unique eventset-index for the eventcode within the eventset
       - a long_long counter-base value (see below)
       - time_t of last fetch of that 

- a single kernel papi-eventset object, representing those papi events
  whose enabled-flags are currently set, and a counter for how many are
  currently in there

  (in the near future, when per-process counters are built out,
  generalize the above as appropriate)

- when receiving a fetch for the kernel papi pmns leaf:
       - check ACL for this client; reject with EPERM if uid/gid != 0
       - find corresponding entry in trackers[] table
       - update its last_fetch tiemstamp
       - if event is already enabled:
         - PAPI_read() the eventset into a temporary long_long
           array of suitable size
         - find the slot# that corresponds to the pcp metric being
           sought (the trackers[].eventset-index value)
         - extract the counter value
         - add it to the trackers[].counter_base value
         - return the result as the metric counter value

       - if the event was not already enabled:
         - we need to update the eventset, but must counting first
         - if this is the first event (eventset size = 0):
           - create the eventset
           - put it into multiplexing mode

         - else this is not the first event:
           - PAPI_stop() the eventset, collecting the then-values of
             the counters into a temporary long_long array of suitable size
           - copy all the counter values into the corresponding
             trackers[].counter_base, so we don't forget in-progress values

         - add the newly requested eventcode into the eventset, set its
           enabled flag, compute its new eventset-index, clear its counter_base
           - prepare to return an error upon failure

         - PAPI_reset() (just to be clear that previous papi counter
           values are lost when we restart)
         - PAPI_start() the eventset -- even if the new event wasn't cool

- in the pmda main loop, periodically (suggested default 5 minutes) go
  through the trackers[] list
  - if any last-fetched value is too long ago, it's time to stop monitoring them
    - call PAPI_stop on the eventset, collecting the then-values of the 
      counters into the trackers[].counter_base just as before
    - clear the eventset completely
    - add the surviving eventcodes back into the eventset, computing new correct
      eventset-indexes as we go
    - clear the dead eventcodes' trackers[] fields
    - PAPI_reset() # redundantly, as before
    - PAPI_start()


... and that should apprx. do it.  

For bonus points, consider adding some control metrics:

- a setting for the counter-disuse-timeout

- a setting for immediate release (ie timeout=0 then cleanup then restore)

- a setting for activation of one or more counters (for old schoolers,
  treat it identically to a fetch)


- FChE

<Prev in Thread] Current Thread [Next in Thread>