per-process-perf.c 30 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252
  1. /* Copyright (c) 2010, The Linux Foundation. All rights reserved.
  2. *
  3. * This program is free software; you can redistribute it and/or modify
  4. * it under the terms of the GNU General Public License version 2 and
  5. * only version 2 as published by the Free Software Foundation.
  6. *
  7. * This program is distributed in the hope that it will be useful,
  8. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. * GNU General Public License for more details.
  11. */
  12. /*
  13. per-process_perf
  14. DESCRIPTION
  15. Capture the processor performances registers when the process context
  16. switches. The /proc file system is used to control and access the results
  17. of the performance counters.
  18. Each time a process is context switched, the performance counters for
  19. the Snoop Control Unit and the standard ARM counters are set according
  20. to the values stored for that process.
  21. The events to capture per process are set in the /proc/ppPerf/settings
  22. directory.
  23. EXTERNALIZED FUNCTIONS
  24. INITIALIZATION AND SEQUENCING REQUIREMENTS
  25. Detail how to initialize and use this service. The sequencing aspect
  26. is only needed if the order of operations is important.
  27. */
  28. /*
  29. INCLUDE FILES FOR MODULE
  30. */
  31. #include <linux/module.h>
  32. #include <linux/init.h>
  33. #include <linux/sched.h>
  34. #include <linux/sysrq.h>
  35. #include <linux/time.h>
  36. #include "linux/proc_fs.h"
  37. #include "linux/kernel_stat.h"
  38. #include <asm/thread_notify.h>
  39. #include "asm/uaccess.h"
  40. #include "cp15_registers.h"
  41. #include "l2_cp15_registers.h"
  42. #include <asm/perftypes.h>
  43. #include "per-axi.h"
  44. #include "perf.h"
  45. #define DEBUG_SWAPIO
  46. #ifdef DEBUG_SWAPIO
  47. #define MR_SIZE 1024
  48. #define PM_PP_ERR -1
  49. struct mark_data_s {
  50. long c;
  51. long cpu;
  52. unsigned long pid_old;
  53. unsigned long pid_new;
  54. };
  55. struct mark_data_s markRay[MR_SIZE] __attribute__((aligned(16)));
  56. int mrcnt;
  57. DEFINE_SPINLOCK(_mark_lock);
  58. static inline void MARKPIDS(char a, int opid, int npid)
  59. {
  60. int cpu = smp_processor_id();
  61. if (opid == 0)
  62. return;
  63. spin_lock(&_mark_lock);
  64. if (++mrcnt >= MR_SIZE)
  65. mrcnt = 0;
  66. spin_unlock(&_mark_lock);
  67. markRay[mrcnt].pid_old = opid;
  68. markRay[mrcnt].pid_new = npid;
  69. markRay[mrcnt].cpu = cpu;
  70. markRay[mrcnt].c = a;
  71. }
  72. static inline void MARK(char a) { MARKPIDS(a, 0xFFFF, 0xFFFF); }
  73. static inline void MARKPID(char a, int pid) { MARKPIDS(a, pid, 0xFFFF); }
  74. #else
  75. #define MARK(a)
  76. #define MARKPID(a, b)
  77. #define MARKPIDS(a, b, c)
  78. #endif /* DEBUG_SWAPIO */
  79. /*
  80. DEFINITIONS AND DECLARATIONS FOR MODULE
  81. This section contains definitions for constants, macros, types, variables
  82. and other items needed by this module.
  83. */
  84. /*
  85. Constant / Define Declarations
  86. */
  87. #define PERF_MON_PROCESS_NUM 0x400
  88. #define PERF_MON_PROCESS_MASK (PERF_MON_PROCESS_NUM-1)
  89. #define PP_MAX_PROC_ENTRIES 32
  90. /*
  91. * The entry is locked and is not to be replaced.
  92. */
  93. #define PERF_ENTRY_LOCKED (1<<0)
  94. #define PERF_NOT_FIRST_TIME (1<<1)
  95. #define PERF_EXITED (1<<2)
  96. #define PERF_AUTOLOCK (1<<3)
  97. #define IS_LOCKED(p) (p->flags & PERF_ENTRY_LOCKED)
  98. #define PERF_NUM_MONITORS 4
  99. #define L1_EVENTS_0 0
  100. #define L1_EVENTS_1 1
  101. #define L2_EVENTS_0 2
  102. #define L2_EVENTS_1 3
  103. #define PM_CYCLE_OVERFLOW_MASK 0x80000000
  104. #define L2_PM_CYCLE_OVERFLOW_MASK 0x80000000
  105. #define PM_START_ALL() do {\
  106. if (pm_global) \
  107. pmStartAll();\
  108. } while (0);
  109. #define PM_STOP_ALL() do {\
  110. if (pm_global)\
  111. pmStopAll();\
  112. } while (0);
  113. #define PM_RESET_ALL() do {\
  114. if (pm_global)\
  115. pmResetAll();\
  116. } while (0);
  117. /*
  118. * Accessors for SMP based variables.
  119. */
  120. #define _SWAPS(p) ((p)->cnts[smp_processor_id()].swaps)
  121. #define _CYCLES(p) ((p)->cnts[smp_processor_id()].cycles)
  122. #define _COUNTS(p, i) ((p)->cnts[smp_processor_id()].counts[i])
  123. #define _L2COUNTS(p, i) ((p)->cnts[smp_processor_id()].l2_counts[i])
  124. #define _L2CYCLES(p) ((p)->cnts[smp_processor_id()].l2_cycles)
  125. /*
  126. Type Declarations
  127. */
  128. /*
  129. * Counts are on a per core basis.
  130. */
  131. struct pm_counters_s {
  132. unsigned long long cycles;
  133. unsigned long long l2_cycles;
  134. unsigned long long counts[PERF_NUM_MONITORS];
  135. unsigned long long l2_counts[PERF_NUM_MONITORS];
  136. unsigned long swaps;
  137. };
  138. struct per_process_perf_mon_type{
  139. struct pm_counters_s cnts[NR_CPUS];
  140. unsigned long control;
  141. unsigned long index[PERF_NUM_MONITORS];
  142. unsigned long l2_index[PERF_NUM_MONITORS];
  143. unsigned long pid;
  144. struct proc_dir_entry *proc;
  145. struct proc_dir_entry *l2_proc;
  146. unsigned short flags;
  147. unsigned short running_cpu;
  148. char *pidName;
  149. unsigned long lpm0evtyper;
  150. unsigned long lpm1evtyper;
  151. unsigned long lpm2evtyper;
  152. unsigned long l2lpmevtyper;
  153. unsigned long vlpmevtyper;
  154. unsigned long l2pmevtyper0;
  155. unsigned long l2pmevtyper1;
  156. unsigned long l2pmevtyper2;
  157. unsigned long l2pmevtyper3;
  158. unsigned long l2pmevtyper4;
  159. };
  160. unsigned long last_in_pid[NR_CPUS];
  161. unsigned long fake_swap_out[NR_CPUS] = {0};
  162. /*
  163. Local Object Definitions
  164. */
  165. struct per_process_perf_mon_type perf_mons[PERF_MON_PROCESS_NUM];
  166. struct proc_dir_entry *proc_dir;
  167. struct proc_dir_entry *settings_dir;
  168. struct proc_dir_entry *values_dir;
  169. struct proc_dir_entry *axi_dir;
  170. struct proc_dir_entry *l2_dir;
  171. struct proc_dir_entry *axi_settings_dir;
  172. struct proc_dir_entry *axi_results_dir;
  173. struct proc_dir_entry *l2_results_dir;
  174. unsigned long pp_enabled;
  175. unsigned long pp_settings_valid = -1;
  176. unsigned long pp_auto_lock;
  177. unsigned long pp_set_pid;
  178. signed long pp_clear_pid = -1;
  179. unsigned long per_proc_event[PERF_NUM_MONITORS];
  180. unsigned long l2_per_proc_event[PERF_NUM_MONITORS];
  181. unsigned long dbg_flags;
  182. unsigned long pp_lpm0evtyper;
  183. unsigned long pp_lpm1evtyper;
  184. unsigned long pp_lpm2evtyper;
  185. unsigned long pp_l2lpmevtyper;
  186. unsigned long pp_vlpmevtyper;
  187. unsigned long pm_stop_for_interrupts;
  188. unsigned long pm_global; /* track all, not process based */
  189. unsigned long pm_global_enable;
  190. unsigned long pm_remove_pid;
  191. unsigned long pp_l2pmevtyper0;
  192. unsigned long pp_l2pmevtyper1;
  193. unsigned long pp_l2pmevtyper2;
  194. unsigned long pp_l2pmevtyper3;
  195. unsigned long pp_l2pmevtyper4;
  196. unsigned long pp_proc_entry_index;
  197. char *per_process_proc_names[PP_MAX_PROC_ENTRIES];
  198. unsigned int axi_swaps;
  199. #define MAX_AXI_SWAPS 10
  200. int first_switch = 1;
  201. /*
  202. Forward Declarations
  203. */
  204. /*
  205. Function Definitions
  206. */
  207. /*
  208. FUNCTION per_process_find
  209. DESCRIPTION
  210. Find the per process information based on the process id (pid) passed.
  211. This is a simple mask based on the number of entries stored in the
  212. static array
  213. DEPENDENCIES
  214. RETURN VALUE
  215. Pointer to the per process data
  216. SIDE EFFECTS
  217. */
  218. struct per_process_perf_mon_type *per_process_find(unsigned long pid)
  219. {
  220. return &perf_mons[pid & PERF_MON_PROCESS_MASK];
  221. }
  222. /*
  223. FUNCTION per_process_get_name
  224. DESCRIPTION
  225. Retreive the name of the performance counter based on the table and
  226. index passed. We have two different sets of performance counters so
  227. different table need to be used.
  228. DEPENDENCIES
  229. RETURN VALUE
  230. Pointer to char string with the name of the event or "BAD"
  231. Never returns NULL or a bad pointer.
  232. SIDE EFFECTS
  233. */
  234. char *per_process_get_name(unsigned long index)
  235. {
  236. return pm_find_event_name(index);
  237. }
  238. /*
  239. FUNCTION per_process_results_read
  240. DESCRIPTION
  241. Print out the formatted results from the process id read. Event names
  242. and counts are printed.
  243. DEPENDENCIES
  244. RETURN VALUE
  245. SIDE EFFECTS
  246. */
  247. int per_process_results_read(char *page, char **start, off_t off, int count,
  248. int *eof, void *data)
  249. {
  250. struct per_process_perf_mon_type *p =
  251. (struct per_process_perf_mon_type *)data;
  252. struct pm_counters_s cnts;
  253. int i, j;
  254. /*
  255. * Total across all CPUS
  256. */
  257. memset(&cnts, 0, sizeof(cnts));
  258. for (i = 0; i < num_possible_cpus(); i++) {
  259. cnts.swaps += p->cnts[i].swaps;
  260. cnts.cycles += p->cnts[i].cycles;
  261. for (j = 0; j < PERF_NUM_MONITORS; j++)
  262. cnts.counts[j] += p->cnts[i].counts[j];
  263. }
  264. /*
  265. * Display as single results of the totals calculated above.
  266. * Do we want to display or have option to display individula cores?
  267. */
  268. return sprintf(page, "pid:%lu one:%s:%llu two:%s:%llu three:%s:%llu \
  269. four:%s:%llu cycles:%llu swaps:%lu\n",
  270. p->pid,
  271. per_process_get_name(p->index[0]), cnts.counts[0],
  272. per_process_get_name(p->index[1]), cnts.counts[1],
  273. per_process_get_name(p->index[2]), cnts.counts[2],
  274. per_process_get_name(p->index[3]), cnts.counts[3],
  275. cnts.cycles, cnts.swaps);
  276. }
  277. int per_process_l2_results_read(char *page, char **start, off_t off, int count,
  278. int *eof, void *data)
  279. {
  280. struct per_process_perf_mon_type *p =
  281. (struct per_process_perf_mon_type *)data;
  282. struct pm_counters_s cnts;
  283. int i, j;
  284. /*
  285. * Total across all CPUS
  286. */
  287. memset(&cnts, 0, sizeof(cnts));
  288. for (i = 0; i < num_possible_cpus(); i++) {
  289. cnts.l2_cycles += p->cnts[i].l2_cycles;
  290. for (j = 0; j < PERF_NUM_MONITORS; j++)
  291. cnts.l2_counts[j] += p->cnts[i].l2_counts[j];
  292. }
  293. /*
  294. * Display as single results of the totals calculated above.
  295. * Do we want to display or have option to display individula cores?
  296. */
  297. return sprintf(page, "pid:%lu l2_one:%s:%llu l2_two:%s:%llu \
  298. l2_three:%s:%llu \
  299. l2_four:%s:%llu l2_cycles:%llu\n",
  300. p->pid,
  301. per_process_get_name(p->l2_index[0]), cnts.l2_counts[0],
  302. per_process_get_name(p->l2_index[1]), cnts.l2_counts[1],
  303. per_process_get_name(p->l2_index[2]), cnts.l2_counts[2],
  304. per_process_get_name(p->l2_index[3]), cnts.l2_counts[3],
  305. cnts.l2_cycles);
  306. }
  307. /*
  308. FUNCTION per_process_results_write
  309. DESCRIPTION
  310. Allow some control over the results. If the user forgets to autolock or
  311. wants to unlock the results so they will be deleted, then this is
  312. where it is processed.
  313. For example, to unlock process 23
  314. echo "unlock" > 23
  315. DEPENDENCIES
  316. RETURN VALUE
  317. Number of characters used (all of them!)
  318. SIDE EFFECTS
  319. */
  320. int per_process_results_write(struct file *file, const char *buff,
  321. unsigned long cnt, void *data)
  322. {
  323. char *newbuf;
  324. struct per_process_perf_mon_type *p =
  325. (struct per_process_perf_mon_type *)data;
  326. if (p == 0)
  327. return cnt;
  328. /*
  329. * Alloc the user data in kernel space. and then copy user to kernel
  330. */
  331. newbuf = kmalloc(cnt + 1, GFP_KERNEL);
  332. if (0 == newbuf)
  333. return cnt;
  334. if (copy_from_user(newbuf, buff, cnt) != 0) {
  335. printk(KERN_INFO "%s copy_from_user failed\n", __func__);
  336. return cnt;
  337. }
  338. if (0 == strcmp("lock", newbuf))
  339. p->flags |= PERF_ENTRY_LOCKED;
  340. else if (0 == strcmp("unlock", newbuf))
  341. p->flags &= ~PERF_ENTRY_LOCKED;
  342. else if (0 == strcmp("auto", newbuf))
  343. p->flags |= PERF_AUTOLOCK;
  344. else if (0 == strcmp("autoun", newbuf))
  345. p->flags &= ~PERF_AUTOLOCK;
  346. return cnt;
  347. }
  348. /*
  349. FUNCTION perProcessCreateResults
  350. DESCRIPTION
  351. Create the results /proc file if the system parameters allow it...
  352. DEPENDENCIES
  353. RETURN VALUE
  354. SIDE EFFECTS
  355. */
  356. void per_process_create_results_proc(struct per_process_perf_mon_type *p)
  357. {
  358. if (0 == p->pidName)
  359. p->pidName = kmalloc(12, GFP_KERNEL);
  360. if (0 == p->pidName)
  361. return;
  362. sprintf(p->pidName, "%ld", p->pid);
  363. if (0 == p->proc) {
  364. p->proc = create_proc_entry(p->pidName, 0777, values_dir);
  365. if (0 == p->proc)
  366. return;
  367. } else {
  368. p->proc->name = p->pidName;
  369. }
  370. p->proc->read_proc = per_process_results_read;
  371. p->proc->write_proc = per_process_results_write;
  372. p->proc->data = (void *)p;
  373. }
  374. void per_process_create_l2_results_proc(struct per_process_perf_mon_type *p)
  375. {
  376. if (0 == p->pidName)
  377. p->pidName = kmalloc(12, GFP_KERNEL);
  378. if (0 == p->pidName)
  379. return;
  380. sprintf(p->pidName, "%ld", p->pid);
  381. if (0 == p->l2_proc) {
  382. p->l2_proc = create_proc_entry(p->pidName, 0777,
  383. l2_results_dir);
  384. if (0 == p->l2_proc)
  385. return;
  386. } else {
  387. p->l2_proc->name = p->pidName;
  388. }
  389. p->l2_proc->read_proc = per_process_l2_results_read;
  390. p->l2_proc->write_proc = per_process_results_write;
  391. p->l2_proc->data = (void *)p;
  392. }
  393. /*
  394. FUNCTION per_process_swap_out
  395. DESCRIPTION
  396. Store the counters from the process that is about to swap out. We take
  397. the old counts and add them to the current counts in the perf registers.
  398. Before the new process is swapped in, the counters are reset.
  399. DEPENDENCIES
  400. RETURN VALUE
  401. SIDE EFFECTS
  402. */
  403. typedef void (*vfun)(void *);
  404. void per_process_swap_out(struct per_process_perf_mon_type *data)
  405. {
  406. int i;
  407. unsigned long overflow;
  408. #ifdef CONFIG_ARCH_MSM8X60
  409. unsigned long l2_overflow;
  410. #endif
  411. struct per_process_perf_mon_type *p = data;
  412. MARKPIDS('O', p->pid, 0);
  413. RCP15_PMOVSR(overflow);
  414. #ifdef CONFIG_ARCH_MSM8X60
  415. RCP15_L2PMOVSR(l2_overflow);
  416. #endif
  417. if (!pp_enabled)
  418. return;
  419. /*
  420. * The kernel for some reason (2.6.32.9) starts a process context on
  421. * one core and ends on another. So the swap in and swap out can be
  422. * on different cores. If this happens, we need to stop the
  423. * counters and collect the data on the core that started the counters
  424. * ....otherwise we receive invalid data. So we mark the the core with
  425. * the process as deferred. The next time a process is swapped on
  426. * the core that the process was running on, the counters will be
  427. * updated.
  428. */
  429. if ((smp_processor_id() != p->running_cpu) && (p->pid != 0)) {
  430. fake_swap_out[p->running_cpu] = 1;
  431. return;
  432. }
  433. _SWAPS(p)++;
  434. _CYCLES(p) += pm_get_cycle_count();
  435. if (overflow & PM_CYCLE_OVERFLOW_MASK)
  436. _CYCLES(p) += 0xFFFFFFFF;
  437. for (i = 0; i < PERF_NUM_MONITORS; i++) {
  438. _COUNTS(p, i) += pm_get_count(i);
  439. if (overflow & (1 << i))
  440. _COUNTS(p, i) += 0xFFFFFFFF;
  441. }
  442. #ifdef CONFIG_ARCH_MSM8X60
  443. _L2CYCLES(p) += l2_pm_get_cycle_count();
  444. if (l2_overflow & L2_PM_CYCLE_OVERFLOW_MASK)
  445. _L2CYCLES(p) += 0xFFFFFFFF;
  446. for (i = 0; i < PERF_NUM_MONITORS; i++) {
  447. _L2COUNTS(p, i) += l2_pm_get_count(i);
  448. if (l2_overflow & (1 << i))
  449. _L2COUNTS(p, i) += 0xFFFFFFFF;
  450. }
  451. #endif
  452. }
  453. /*
  454. FUNCTION per_process_remove_manual
  455. DESCRIPTION
  456. Remove an entry from the results directory if the flags allow this.
  457. When not enbled or the entry is locked, the values/results will
  458. not be removed.
  459. DEPENDENCIES
  460. RETURN VALUE
  461. SIDE EFFECTS
  462. */
  463. void per_process_remove_manual(unsigned long pid)
  464. {
  465. struct per_process_perf_mon_type *p = per_process_find(pid);
  466. /*
  467. * Check all of the flags to see if we can remove this one
  468. * Then mark as not used
  469. */
  470. if (0 == p)
  471. return;
  472. p->pid = (0xFFFFFFFF);
  473. /*
  474. * Remove the proc entry.
  475. */
  476. if (p->proc)
  477. remove_proc_entry(p->pidName, values_dir);
  478. if (p->l2_proc)
  479. remove_proc_entry(p->pidName, l2_results_dir);
  480. kfree(p->pidName);
  481. /*
  482. * Clear them out...and ensure the pid is invalid
  483. */
  484. memset(p, 0, sizeof *p);
  485. p->pid = 0xFFFFFFFF;
  486. pm_remove_pid = -1;
  487. }
  488. /*
  489. * Remove called when a process exits...
  490. */
  491. void _per_process_remove(unsigned long pid) {}
  492. /*
  493. FUNCTION per_process_initialize
  494. DESCRIPTION
  495. Initialize performance collection information for a new process.
  496. DEPENDENCIES
  497. RETURN VALUE
  498. SIDE EFFECTS
  499. May create a new proc entry
  500. */
  501. void per_process_initialize(struct per_process_perf_mon_type *p,
  502. unsigned long pid)
  503. {
  504. int i;
  505. /*
  506. * See if this is the pid we are interested in...
  507. */
  508. if (pp_settings_valid == -1)
  509. return;
  510. if ((pp_set_pid != pid) && (pp_set_pid != 0))
  511. return;
  512. /*
  513. * Clear out the statistics table then insert this pid
  514. * We want to keep the proc entry and the name
  515. */
  516. p->pid = pid;
  517. /*
  518. * Create a proc entry for this pid, then get the current event types and
  519. * store in data struct so when the process is switched in we can track
  520. * it.
  521. */
  522. if (p->proc == 0) {
  523. per_process_create_results_proc(p);
  524. #ifdef CONFIG_ARCH_MSM8X60
  525. per_process_create_l2_results_proc(p);
  526. #endif
  527. }
  528. _CYCLES(p) = 0;
  529. _L2CYCLES(p) = 0;
  530. _SWAPS(p) = 0;
  531. /*
  532. * Set the per process data struct, but not the monitors until later...
  533. * Init only happens with the user sets the SetPID variable to this pid
  534. * so we can load new values.
  535. */
  536. for (i = 0; i < PERF_NUM_MONITORS; i++) {
  537. p->index[i] = per_proc_event[i];
  538. #ifdef CONFIG_ARCH_MSM8X60
  539. p->l2_index[i] = l2_per_proc_event[i];
  540. #endif
  541. _COUNTS(p, i) = 0;
  542. _L2COUNTS(p, i) = 0;
  543. }
  544. p->lpm0evtyper = pp_lpm0evtyper;
  545. p->lpm1evtyper = pp_lpm1evtyper;
  546. p->lpm2evtyper = pp_lpm2evtyper;
  547. p->l2lpmevtyper = pp_l2lpmevtyper;
  548. p->vlpmevtyper = pp_vlpmevtyper;
  549. #ifdef CONFIG_ARCH_MSM8X60
  550. p->l2pmevtyper0 = pp_l2pmevtyper0;
  551. p->l2pmevtyper1 = pp_l2pmevtyper1;
  552. p->l2pmevtyper2 = pp_l2pmevtyper2;
  553. p->l2pmevtyper3 = pp_l2pmevtyper3;
  554. p->l2pmevtyper4 = pp_l2pmevtyper4;
  555. #endif
  556. /*
  557. * Reset pid and settings value
  558. */
  559. pp_set_pid = -1;
  560. pp_settings_valid = -1;
  561. }
  562. /*
  563. FUNCTION per_process_swap_in
  564. DESCRIPTION
  565. Called when a context switch is about to start this PID.
  566. We check to see if this process has an entry or not and create one
  567. if not locked...
  568. DEPENDENCIES
  569. RETURN VALUE
  570. SIDE EFFECTS
  571. */
  572. void per_process_swap_in(struct per_process_perf_mon_type *p_new,
  573. unsigned long pid)
  574. {
  575. int i;
  576. MARKPIDS('I', p_new->pid, 0);
  577. /*
  578. * If the set proc variable == the current pid then init a new
  579. * entry...
  580. */
  581. if (pp_set_pid == pid)
  582. per_process_initialize(p_new, pid);
  583. p_new->running_cpu = smp_processor_id();
  584. last_in_pid[smp_processor_id()] = pid;
  585. /*
  586. * setup the monitors for this process.
  587. */
  588. for (i = 0; i < PERF_NUM_MONITORS; i++) {
  589. pm_set_event(i, p_new->index[i]);
  590. #ifdef CONFIG_ARCH_MSM8X60
  591. l2_pm_set_event(i, p_new->l2_index[i]);
  592. #endif
  593. }
  594. pm_set_local_iu(p_new->lpm0evtyper);
  595. pm_set_local_xu(p_new->lpm1evtyper);
  596. pm_set_local_su(p_new->lpm2evtyper);
  597. pm_set_local_l2(p_new->l2lpmevtyper);
  598. #ifdef CONFIG_ARCH_MSM8X60
  599. pm_set_local_bu(p_new->l2pmevtyper0);
  600. pm_set_local_cb(p_new->l2pmevtyper1);
  601. pm_set_local_mp(p_new->l2pmevtyper2);
  602. pm_set_local_sp(p_new->l2pmevtyper3);
  603. pm_set_local_scu(p_new->l2pmevtyper4);
  604. #endif
  605. }
  606. /*
  607. FUNCTION perProcessSwitch
  608. DESCRIPTION
  609. Called during context switch. Updates the counts on the process about to
  610. be swapped out and brings in the counters for the process about to be
  611. swapped in.
  612. All is dependant on the enabled and lock flags.
  613. DEPENDENCIES
  614. RETURN VALUE
  615. SIDE EFFECTS
  616. */
  617. DEFINE_SPINLOCK(pm_lock);
  618. void _per_process_switch(unsigned long old_pid, unsigned long new_pid)
  619. {
  620. struct per_process_perf_mon_type *p_old, *p_new;
  621. if (pm_global_enable == 0)
  622. return;
  623. spin_lock(&pm_lock);
  624. pm_stop_all();
  625. #ifdef CONFIG_ARCH_MSM8X60
  626. l2_pm_stop_all();
  627. #endif
  628. /*
  629. * We detected that the process was swapped in on one core and out on
  630. * a different core. This does not allow us to stop and stop counters
  631. * properly so we need to defer processing. This checks to see if there
  632. * is any defered processing necessary. And does it... */
  633. if (fake_swap_out[smp_processor_id()] != 0) {
  634. fake_swap_out[smp_processor_id()] = 0;
  635. p_old = per_process_find(last_in_pid[smp_processor_id()]);
  636. last_in_pid[smp_processor_id()] = 0;
  637. if (p_old != 0)
  638. per_process_swap_out(p_old);
  639. }
  640. /*
  641. * Clear the data collected so far for this process?
  642. */
  643. if (pp_clear_pid != -1) {
  644. struct per_process_perf_mon_type *p_clear =
  645. per_process_find(pp_clear_pid);
  646. if (p_clear) {
  647. memset(p_clear->cnts, 0,
  648. sizeof(struct pm_counters_s)*num_possible_cpus());
  649. printk(KERN_INFO "Clear Per Processor Stats for \
  650. PID:%ld\n", pp_clear_pid);
  651. pp_clear_pid = -1;
  652. }
  653. }
  654. /*
  655. * Always collect for 0, it collects for all.
  656. */
  657. if (pp_enabled) {
  658. if (first_switch == 1) {
  659. per_process_initialize(&perf_mons[0], 0);
  660. first_switch = 0;
  661. }
  662. if (pm_global) {
  663. per_process_swap_out(&perf_mons[0]);
  664. per_process_swap_in(&perf_mons[0], 0);
  665. } else {
  666. p_old = per_process_find(old_pid);
  667. p_new = per_process_find(new_pid);
  668. /*
  669. * save the old counts to the old data struct, if the
  670. * returned ptr is NULL or the process id passed is not
  671. * the same as the process id in the data struct then
  672. * don't update the data.
  673. */
  674. if ((p_old) && (p_old->pid == old_pid) &&
  675. (p_old->pid != 0)) {
  676. per_process_swap_out(p_old);
  677. }
  678. /*
  679. * Setup the counters for the new process
  680. */
  681. if (pp_set_pid == new_pid)
  682. per_process_initialize(p_new, new_pid);
  683. if ((p_new->pid == new_pid) && (new_pid != 0))
  684. per_process_swap_in(p_new, new_pid);
  685. }
  686. pm_reset_all();
  687. #ifdef CONFIG_ARCH_MSM8X60
  688. l2_pm_reset_all();
  689. #endif
  690. #ifdef CONFIG_ARCH_QSD8X50
  691. axi_swaps++;
  692. if (axi_swaps%pm_axi_info.refresh == 0) {
  693. if (pm_axi_info.clear == 1) {
  694. pm_axi_clear_cnts();
  695. pm_axi_info.clear = 0;
  696. }
  697. if (pm_axi_info.enable == 0)
  698. pm_axi_disable();
  699. else
  700. pm_axi_update_cnts();
  701. axi_swaps = 0;
  702. }
  703. #endif
  704. }
  705. pm_start_all();
  706. #ifdef CONFIG_ARCH_MSM8X60
  707. l2_pm_start_all();
  708. #endif
  709. spin_unlock(&pm_lock);
  710. }
  711. /*
  712. FUNCTION pmInterruptIn
  713. DESCRIPTION
  714. Called when an interrupt is being processed. If the pmStopForInterrutps
  715. flag is non zero then we disable the counting of performance monitors.
  716. DEPENDENCIES
  717. RETURN VALUE
  718. SIDE EFFECTS
  719. */
  720. static int pm_interrupt_nesting_count;
  721. static unsigned long pm_cycle_in, pm_cycle_out;
  722. void _perf_mon_interrupt_in(void)
  723. {
  724. if (pm_global_enable == 0)
  725. return;
  726. if (pm_stop_for_interrupts == 0)
  727. return;
  728. pm_interrupt_nesting_count++; /* Atomic */
  729. pm_stop_all();
  730. pm_cycle_in = pm_get_cycle_count();
  731. }
  732. /*
  733. FUNCTION perfMonInterruptOut
  734. DESCRIPTION
  735. Reenable performance monitor counting whn the nest count goes to zero
  736. provided the counting has been stoped
  737. DEPENDENCIES
  738. RETURN VALUE
  739. SIDE EFFECTS
  740. */
  741. void _perf_mon_interrupt_out(void)
  742. {
  743. if (pm_global_enable == 0)
  744. return;
  745. if (pm_stop_for_interrupts == 0)
  746. return;
  747. --pm_interrupt_nesting_count; /* Atomic?? */
  748. if (pm_interrupt_nesting_count <= 0) {
  749. pm_cycle_out = pm_get_cycle_count();
  750. if (pm_cycle_in != pm_cycle_out)
  751. printk(KERN_INFO "pmIn!=pmOut in:%lx out:%lx\n",
  752. pm_cycle_in, pm_cycle_out);
  753. if (pp_enabled) {
  754. pm_start_all();
  755. #ifdef CONFIG_ARCH_MSM8X60
  756. l2_pm_start_all();
  757. #endif
  758. }
  759. pm_interrupt_nesting_count = 0;
  760. }
  761. }
  762. void per_process_do_global(unsigned long g)
  763. {
  764. pm_global = g;
  765. if (pm_global == 1) {
  766. pm_stop_all();
  767. #ifdef CONFIG_ARCH_MSM8X60
  768. l2_pm_stop_all();
  769. #endif
  770. pm_reset_all();
  771. #ifdef CONFIG_ARCH_MSM8X60
  772. l2_pm_reset_all();
  773. #endif
  774. pp_set_pid = 0;
  775. per_process_swap_in(&perf_mons[0], 0);
  776. pm_start_all();
  777. #ifdef CONFIG_ARCH_MSM8X60
  778. l2_pm_start_all();
  779. #endif
  780. } else {
  781. pm_stop_all();
  782. #ifdef CONFIG_ARCH_MSM8X60
  783. l2_pm_stop_all();
  784. #endif
  785. }
  786. }
  787. /*
  788. FUNCTION per_process_write
  789. DESCRIPTION
  790. Generic routine to handle any of the settings /proc directory writes.
  791. DEPENDENCIES
  792. RETURN VALUE
  793. SIDE EFFECTS
  794. */
  795. int per_process_write(struct file *file, const char *buff,
  796. unsigned long cnt, void *data, const char *fmt)
  797. {
  798. char *newbuf;
  799. unsigned long *d = (unsigned long *)data;
  800. /*
  801. * Alloc the user data in kernel space. and then copy user to kernel
  802. */
  803. newbuf = kmalloc(cnt + 1, GFP_KERNEL);
  804. if (0 == newbuf)
  805. return PM_PP_ERR;
  806. if (copy_from_user(newbuf, buff, cnt) != 0) {
  807. printk(KERN_INFO "%s copy_from_user failed\n", __func__);
  808. return cnt;
  809. }
  810. sscanf(newbuf, fmt, d);
  811. kfree(newbuf);
  812. /*
  813. * If this is a remove command then do it now...
  814. */
  815. if (d == &pm_remove_pid)
  816. per_process_remove_manual(*d);
  817. if (d == &pm_global)
  818. per_process_do_global(*d);
  819. return cnt;
  820. }
  821. int per_process_write_dec(struct file *file, const char *buff,
  822. unsigned long cnt, void *data)
  823. {
  824. return per_process_write(file, buff, cnt, data, "%ld");
  825. }
  826. int per_process_write_hex(struct file *file, const char *buff,
  827. unsigned long cnt, void *data)
  828. {
  829. return per_process_write(file, buff, cnt, data, "%lx");
  830. }
  831. /*
  832. FUNCTION per_process_read
  833. DESCRIPTION
  834. Generic read handler for the /proc settings directory.
  835. DEPENDENCIES
  836. RETURN VALUE
  837. Number of characters to output.
  838. SIDE EFFECTS
  839. */
  840. int per_process_read(char *page, char **start, off_t off, int count,
  841. int *eof, void *data)
  842. {
  843. unsigned long *d = (unsigned long *)data;
  844. return sprintf(page, "%lx", *d);
  845. }
  846. int per_process_read_decimal(char *page, char **start, off_t off, int count,
  847. int *eof, void *data)
  848. {
  849. unsigned long *d = (unsigned long *)data;
  850. return sprintf(page, "%ld", *d);
  851. }
  852. /*
  853. FUNCTION per_process_proc_entry
  854. DESCRIPTION
  855. Create a generic entry for the /proc settings directory.
  856. DEPENDENCIES
  857. RETURN VALUE
  858. SIDE EFFECTS
  859. */
  860. void per_process_proc_entry(char *name, unsigned long *var,
  861. struct proc_dir_entry *d, int hex)
  862. {
  863. struct proc_dir_entry *pe;
  864. pe = create_proc_entry(name, 0777, d);
  865. if (0 == pe)
  866. return;
  867. if (hex) {
  868. pe->read_proc = per_process_read;
  869. pe->write_proc = per_process_write_hex;
  870. } else {
  871. pe->read_proc = per_process_read_decimal;
  872. pe->write_proc = per_process_write_dec;
  873. }
  874. pe->data = (void *)var;
  875. if (pp_proc_entry_index >= PP_MAX_PROC_ENTRIES) {
  876. printk(KERN_INFO "PERF: proc entry overflow,\
  877. memleak on module unload occured");
  878. return;
  879. }
  880. per_process_proc_names[pp_proc_entry_index++] = name;
  881. }
  882. static int perfmon_notifier(struct notifier_block *self, unsigned long cmd,
  883. void *v)
  884. {
  885. static int old_pid = -1;
  886. struct thread_info *thread = v;
  887. int current_pid;
  888. if (cmd != THREAD_NOTIFY_SWITCH)
  889. return old_pid;
  890. current_pid = thread->task->pid;
  891. if (old_pid != -1)
  892. _per_process_switch(old_pid, current_pid);
  893. old_pid = current_pid;
  894. return old_pid;
  895. }
  896. static struct notifier_block perfmon_notifier_block = {
  897. .notifier_call = perfmon_notifier,
  898. };
  899. /*
  900. FUNCTION per_process_perf_init
  901. DESCRIPTION
  902. Initialze the per process performance monitor variables and /proc space.
  903. DEPENDENCIES
  904. RETURN VALUE
  905. SIDE EFFECTS
  906. */
  907. int per_process_perf_init(void)
  908. {
  909. #ifdef CONFIG_ARCH_MSM8X60
  910. smp_call_function_single(0, (void *)pm_initialize, (void *)NULL, 1);
  911. smp_call_function_single(1, (void *)pm_initialize, (void *)NULL, 1);
  912. l2_pm_initialize();
  913. #else
  914. pm_initialize();
  915. #endif
  916. pm_axi_init();
  917. pm_axi_clear_cnts();
  918. proc_dir = proc_mkdir("ppPerf", NULL);
  919. values_dir = proc_mkdir("results", proc_dir);
  920. settings_dir = proc_mkdir("settings", proc_dir);
  921. per_process_proc_entry("enable", &pp_enabled, settings_dir, 1);
  922. per_process_proc_entry("valid", &pp_settings_valid, settings_dir, 1);
  923. per_process_proc_entry("setPID", &pp_set_pid, settings_dir, 0);
  924. per_process_proc_entry("clearPID", &pp_clear_pid, settings_dir, 0);
  925. per_process_proc_entry("event0", &per_proc_event[0], settings_dir, 1);
  926. per_process_proc_entry("event1", &per_proc_event[1], settings_dir, 1);
  927. per_process_proc_entry("event2", &per_proc_event[2], settings_dir, 1);
  928. per_process_proc_entry("event3", &per_proc_event[3], settings_dir, 1);
  929. per_process_proc_entry("l2_event0", &l2_per_proc_event[0], settings_dir,
  930. 1);
  931. per_process_proc_entry("l2_event1", &l2_per_proc_event[1], settings_dir,
  932. 1);
  933. per_process_proc_entry("l2_event2", &l2_per_proc_event[2], settings_dir,
  934. 1);
  935. per_process_proc_entry("l2_event3", &l2_per_proc_event[3], settings_dir,
  936. 1);
  937. per_process_proc_entry("debug", &dbg_flags, settings_dir, 1);
  938. per_process_proc_entry("autolock", &pp_auto_lock, settings_dir, 1);
  939. per_process_proc_entry("lpm0evtyper", &pp_lpm0evtyper, settings_dir, 1);
  940. per_process_proc_entry("lpm1evtyper", &pp_lpm1evtyper, settings_dir, 1);
  941. per_process_proc_entry("lpm2evtyper", &pp_lpm2evtyper, settings_dir, 1);
  942. per_process_proc_entry("l2lpmevtyper", &pp_l2lpmevtyper, settings_dir,
  943. 1);
  944. per_process_proc_entry("vlpmevtyper", &pp_vlpmevtyper, settings_dir, 1);
  945. per_process_proc_entry("l2pmevtyper0", &pp_l2pmevtyper0, settings_dir,
  946. 1);
  947. per_process_proc_entry("l2pmevtyper1", &pp_l2pmevtyper1, settings_dir,
  948. 1);
  949. per_process_proc_entry("l2pmevtyper2", &pp_l2pmevtyper2, settings_dir,
  950. 1);
  951. per_process_proc_entry("l2pmevtyper3", &pp_l2pmevtyper3, settings_dir,
  952. 1);
  953. per_process_proc_entry("l2pmevtyper4", &pp_l2pmevtyper4, settings_dir,
  954. 1);
  955. per_process_proc_entry("stopForInterrupts", &pm_stop_for_interrupts,
  956. settings_dir, 1);
  957. per_process_proc_entry("global", &pm_global, settings_dir, 1);
  958. per_process_proc_entry("globalEnable", &pm_global_enable, settings_dir,
  959. 1);
  960. per_process_proc_entry("removePID", &pm_remove_pid, settings_dir, 0);
  961. axi_dir = proc_mkdir("axi", proc_dir);
  962. axi_settings_dir = proc_mkdir("settings", axi_dir);
  963. axi_results_dir = proc_mkdir("results", axi_dir);
  964. pm_axi_set_proc_entry("axi_enable", &pm_axi_info.enable,
  965. axi_settings_dir, 1);
  966. pm_axi_set_proc_entry("axi_clear", &pm_axi_info.clear, axi_settings_dir,
  967. 0);
  968. pm_axi_set_proc_entry("axi_valid", &pm_axi_info.valid, axi_settings_dir,
  969. 1);
  970. pm_axi_set_proc_entry("axi_sel_reg0", &pm_axi_info.sel_reg0,
  971. axi_settings_dir, 1);
  972. pm_axi_set_proc_entry("axi_sel_reg1", &pm_axi_info.sel_reg1,
  973. axi_settings_dir, 1);
  974. pm_axi_set_proc_entry("axi_ten_sel", &pm_axi_info.ten_sel_reg,
  975. axi_settings_dir, 1);
  976. pm_axi_set_proc_entry("axi_refresh", &pm_axi_info.refresh,
  977. axi_settings_dir, 1);
  978. pm_axi_get_cnt_proc_entry("axi_cnts", &axi_cnts, axi_results_dir, 0);
  979. l2_dir = proc_mkdir("l2", proc_dir);
  980. l2_results_dir = proc_mkdir("results", l2_dir);
  981. memset(perf_mons, 0, sizeof(perf_mons));
  982. per_process_create_results_proc(&perf_mons[0]);
  983. per_process_create_l2_results_proc(&perf_mons[0]);
  984. thread_register_notifier(&perfmon_notifier_block);
  985. /*
  986. * Set the function pointers so the module can be activated.
  987. */
  988. pp_interrupt_out_ptr = _perf_mon_interrupt_out;
  989. pp_interrupt_in_ptr = _perf_mon_interrupt_in;
  990. pp_process_remove_ptr = _per_process_remove;
  991. pp_loaded = 1;
  992. pm_axi_info.refresh = 1;
  993. #ifdef CONFIG_ARCH_MSM8X60
  994. smp_call_function_single(0, (void *)pm_reset_all, (void *)NULL, 1);
  995. smp_call_function_single(1, (void *)pm_reset_all, (void *)NULL, 1);
  996. smp_call_function_single(0, (void *)l2_pm_reset_all, (void *)NULL, 1);
  997. smp_call_function_single(1, (void *)l2_pm_reset_all, (void *)NULL, 1);
  998. #else
  999. pm_reset_all();
  1000. #endif
  1001. return 0;
  1002. }
  1003. /*
  1004. FUNCTION per_process_perf_exit
  1005. DESCRIPTION
  1006. Module exit functionm, clean up, renmove proc entries
  1007. DEPENDENCIES
  1008. RETURN VALUE
  1009. SIDE EFFECTS
  1010. No more per process
  1011. */
  1012. void per_process_perf_exit(void)
  1013. {
  1014. unsigned long i;
  1015. /*
  1016. * Sert the function pointers to 0 so the functions will no longer
  1017. * be invoked
  1018. */
  1019. pp_loaded = 0;
  1020. pp_interrupt_out_ptr = 0;
  1021. pp_interrupt_in_ptr = 0;
  1022. pp_process_remove_ptr = 0;
  1023. /*
  1024. * Remove the results
  1025. */
  1026. for (i = 0; i < PERF_MON_PROCESS_NUM; i++)
  1027. per_process_remove_manual(perf_mons[i].pid);
  1028. /*
  1029. * Remove the proc entries in the settings dir
  1030. */
  1031. i = 0;
  1032. for (i = 0; i < pp_proc_entry_index; i++)
  1033. remove_proc_entry(per_process_proc_names[i], settings_dir);
  1034. /*remove proc axi files*/
  1035. remove_proc_entry("axi_enable", axi_settings_dir);
  1036. remove_proc_entry("axi_valid", axi_settings_dir);
  1037. remove_proc_entry("axi_refresh", axi_settings_dir);
  1038. remove_proc_entry("axi_clear", axi_settings_dir);
  1039. remove_proc_entry("axi_sel_reg0", axi_settings_dir);
  1040. remove_proc_entry("axi_sel_reg1", axi_settings_dir);
  1041. remove_proc_entry("axi_ten_sel", axi_settings_dir);
  1042. remove_proc_entry("axi_cnts", axi_results_dir);
  1043. /*
  1044. * Remove the directories
  1045. */
  1046. remove_proc_entry("results", l2_dir);
  1047. remove_proc_entry("l2", proc_dir);
  1048. remove_proc_entry("results", proc_dir);
  1049. remove_proc_entry("settings", proc_dir);
  1050. remove_proc_entry("results", axi_dir);
  1051. remove_proc_entry("settings", axi_dir);
  1052. remove_proc_entry("axi", proc_dir);
  1053. remove_proc_entry("ppPerf", NULL);
  1054. pm_free_irq();
  1055. #ifdef CONFIG_ARCH_MSM8X60
  1056. l2_pm_free_irq();
  1057. #endif
  1058. thread_unregister_notifier(&perfmon_notifier_block);
  1059. #ifdef CONFIG_ARCH_MSM8X60
  1060. smp_call_function_single(0, (void *)pm_deinitialize, (void *)NULL, 1);
  1061. smp_call_function_single(1, (void *)pm_deinitialize, (void *)NULL, 1);
  1062. l2_pm_deinitialize();
  1063. #else
  1064. pm_deinitialize();
  1065. #endif
  1066. }