title: Using PMU to count ticks on ARM
body: <p>I'm trying to use the PMU (specifically use <code>PMCCNTR</code> to determine ticks per usec) from userspace in ARM.  I have an arm64 kernel running an arm32 bit userspace app.   </p>
  
  <p>I created an LKM to force the <code>PMUSERENR.EN</code> bit to be on, which works.  I then I ran a test program from userspace:  </p>
  
  <pre><code>asm volatile ("mrc p15, 0, %[en], c9, c14, 0" 
        : [en] "=r" (pmuserenr));
  printf(" -- %08x\n", pmuserenr);
  </code></pre>
  
  <p>The first few times I ran this, the bit was correctly marked as turned on.  But every third or fourth time I run it, the bit shows up as off.   After puzzling over this, I came across <a href="https://lists.linaro.org/pipermail/lng-odp/2014-October/004001.html" rel="nofollow noreferrer">this link</a>, where the user is enabling this bit for each cpu.   Does each core have it's own instance of a PMU, or is there only one per SoC?   If there are multiple per SoC, are the <code>PMUCCNTR</code> registers synced up?  (That is, if I read the <code>PMUCCNTR</code>, then do a context switch to another core, and read <code>PMUCCNTR</code> again, can I safely compare the two to see how many ticks have elapsed?).</p>
  
  <p>Even if I modify my LKM to initialize on every online-cpu (and register a notifier to enable it on all new cpu's coming up), I'm still seeing the same behavior, where every nth read from userspace shows the bit not set.</p>
  
  <p>My other issue is that the <code>PMCCNTR</code> is not incrementing.   I set the <code>PMCR.E</code> bit but it's still not incrementing.   I found one website that says I need to set the <code>PMCR.C</code> bit -- but this has a side effect of clearing the counter, which I don't want to do in fear of creating a race condition (where someone else is using the counter as I clear it).    Any help or insights would be very welcome.</p>