adreno_profile.c 31 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175
  1. /* Copyright (c) 2013-2015, 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. #include <linux/fs.h>
  14. #include <linux/kernel.h>
  15. #include <linux/ctype.h>
  16. #include <linux/slab.h>
  17. #include <linux/delay.h>
  18. #include <linux/uaccess.h>
  19. #include <linux/vmalloc.h>
  20. #include <linux/debugfs.h>
  21. #include "adreno.h"
  22. #include "adreno_profile.h"
  23. #include "kgsl_sharedmem.h"
  24. #include "kgsl_cffdump.h"
  25. #define ASSIGNS_STR_FORMAT "%.8s:%u "
  26. /*
  27. * Raw Data for processing later:
  28. * : 3 - timestamp, count, context id
  29. * [per counter] - data for each counter
  30. * : 1 - Register offset
  31. * : 2 - Pre IB register hi/lo value
  32. * : 2 - Post IB register hi/lo value
  33. * [per counter end]
  34. */
  35. #define SIZE_DATA(cnt) (3 + (cnt) * 5)
  36. /*
  37. * Pre-IB command size (in dwords):
  38. * : 2 - NOP start identifier
  39. * : 3 - timestamp
  40. * : 3 - count
  41. * : 3 - context id
  42. * [loop count start] - for each counter to watch
  43. * : 3 - Register offset
  44. * : 3 - Register read lo
  45. * : 3 - Register read high
  46. * [loop end]
  47. * : 2 - NOP end identifier
  48. */
  49. #define SIZE_PREIB(cnt) (13 + (cnt) * 9)
  50. /*
  51. * Post-IB command size (in dwords):
  52. * : 2 - NOP start identifier
  53. * [loop count start] - for each counter to watch
  54. * : 3 - Register read lo
  55. * : 3 - Register read high
  56. * [loop end]
  57. * : 2 - NOP end identifier
  58. */
  59. #define SIZE_POSTIB(cnt) (4 + (cnt) * 6)
  60. /* Counter data + Pre size + post size = total size */
  61. #define SIZE_SHARED_ENTRY(cnt) (SIZE_DATA(cnt) + SIZE_PREIB(cnt) \
  62. + SIZE_POSTIB(cnt))
  63. /*
  64. * Space for following string :"%u %u %u %.5s %u "
  65. * [count iterations]: "%.8s:%u %llu %llu%c"
  66. */
  67. #define SIZE_PIPE_ENTRY(cnt) (50 + (cnt) * 62)
  68. #define SIZE_LOG_ENTRY(cnt) (5 + (cnt) * 5)
  69. static struct adreno_context_type ctxt_type_table[] = {ADRENO_DRAWCTXT_TYPES};
  70. static const char *get_api_type_str(unsigned int type)
  71. {
  72. int i;
  73. for (i = 0; i < ARRAY_SIZE(ctxt_type_table) - 1; i++) {
  74. if (ctxt_type_table[i].type == type)
  75. break;
  76. }
  77. return ctxt_type_table[i].str;
  78. }
  79. static inline void _create_ib_ref(struct kgsl_memdesc *memdesc,
  80. unsigned int *cmd, unsigned int cnt, unsigned int off)
  81. {
  82. cmd[0] = CP_HDR_INDIRECT_BUFFER_PFD;
  83. cmd[1] = memdesc->gpuaddr + off;
  84. cmd[2] = cnt;
  85. }
  86. #define IB_START(cmd) do { \
  87. *cmd++ = cp_nop_packet(1); \
  88. *cmd++ = KGSL_START_OF_PROFILE_IDENTIFIER; \
  89. } while (0);
  90. #define IB_END(cmd) do { \
  91. *cmd++ = cp_nop_packet(1); \
  92. *cmd++ = KGSL_END_OF_PROFILE_IDENTIFIER; \
  93. } while (0);
  94. #define IB_CMD(cmd, type, val1, val2, off) do { \
  95. *cmd++ = cp_type3_packet(type, 2); \
  96. *cmd++ = val1; \
  97. *cmd++ = val2; \
  98. off += sizeof(unsigned int); \
  99. } while (0);
  100. static void _build_pre_ib_cmds(struct adreno_profile *profile,
  101. unsigned int *rbcmds, unsigned int head,
  102. unsigned int timestamp, unsigned int ctxt_id)
  103. {
  104. struct adreno_profile_assigns_list *entry;
  105. unsigned int *start, *ibcmds;
  106. unsigned int count = profile->assignment_count;
  107. unsigned int gpuaddr = profile->shared_buffer.gpuaddr;
  108. unsigned int ib_offset = head + SIZE_DATA(count);
  109. unsigned int data_offset = head * sizeof(unsigned int);
  110. ibcmds = ib_offset + ((unsigned int *) profile->shared_buffer.hostptr);
  111. start = ibcmds;
  112. /* start of profile identifier */
  113. IB_START(ibcmds);
  114. /* timestamp */
  115. IB_CMD(ibcmds, CP_MEM_WRITE, gpuaddr + data_offset,
  116. timestamp, data_offset);
  117. /* count: number of perf counters pairs GPU will write */
  118. IB_CMD(ibcmds, CP_MEM_WRITE, gpuaddr + data_offset,
  119. profile->assignment_count, data_offset);
  120. /* context id */
  121. IB_CMD(ibcmds, CP_MEM_WRITE, gpuaddr + data_offset,
  122. ctxt_id, data_offset);
  123. /* loop for each countable assigned */
  124. list_for_each_entry(entry, &profile->assignments_list, list) {
  125. IB_CMD(ibcmds, CP_MEM_WRITE, gpuaddr + data_offset,
  126. entry->offset, data_offset);
  127. IB_CMD(ibcmds, CP_REG_TO_MEM, entry->offset,
  128. gpuaddr + data_offset, data_offset);
  129. IB_CMD(ibcmds, CP_REG_TO_MEM, entry->offset_hi,
  130. gpuaddr + data_offset, data_offset);
  131. /* skip over post_ib counter data */
  132. data_offset += sizeof(unsigned int) * 2;
  133. }
  134. /* end of profile identifier */
  135. IB_END(ibcmds);
  136. _create_ib_ref(&profile->shared_buffer, rbcmds,
  137. ibcmds - start, ib_offset * sizeof(unsigned int));
  138. }
  139. static void _build_post_ib_cmds(struct adreno_profile *profile,
  140. unsigned int *rbcmds, unsigned int head)
  141. {
  142. struct adreno_profile_assigns_list *entry;
  143. unsigned int *start, *ibcmds;
  144. unsigned int count = profile->assignment_count;
  145. unsigned int gpuaddr = profile->shared_buffer.gpuaddr;
  146. unsigned int ib_offset = head + SIZE_DATA(count) + SIZE_PREIB(count);
  147. unsigned int data_offset = head * sizeof(unsigned int);
  148. ibcmds = ib_offset + ((unsigned int *) profile->shared_buffer.hostptr);
  149. start = ibcmds;
  150. /* end of profile identifier */
  151. IB_END(ibcmds);
  152. /* skip over pre_ib preamble */
  153. data_offset += sizeof(unsigned int) * 3;
  154. /* loop for each countable assigned */
  155. list_for_each_entry(entry, &profile->assignments_list, list) {
  156. /* skip over pre_ib counter data */
  157. data_offset += sizeof(unsigned int) * 3;
  158. IB_CMD(ibcmds, CP_REG_TO_MEM, entry->offset,
  159. gpuaddr + data_offset, data_offset);
  160. IB_CMD(ibcmds, CP_REG_TO_MEM, entry->offset_hi,
  161. gpuaddr + data_offset, data_offset);
  162. }
  163. /* end of profile identifier */
  164. IB_END(ibcmds);
  165. _create_ib_ref(&profile->shared_buffer, rbcmds,
  166. ibcmds - start, ib_offset * sizeof(unsigned int));
  167. }
  168. static bool shared_buf_empty(struct adreno_profile *profile)
  169. {
  170. if (profile->shared_buffer.hostptr == NULL ||
  171. profile->shared_buffer.size == 0)
  172. return true;
  173. if (profile->shared_head == profile->shared_tail)
  174. return true;
  175. return false;
  176. }
  177. static inline void shared_buf_inc(unsigned int max_size,
  178. unsigned int *offset, size_t inc)
  179. {
  180. *offset = (*offset + inc) % max_size;
  181. }
  182. static inline void log_buf_wrapcnt(unsigned int cnt, unsigned int *off)
  183. {
  184. *off = (*off + cnt) % ADRENO_PROFILE_LOG_BUF_SIZE_DWORDS;
  185. }
  186. static inline void log_buf_wrapinc(unsigned int *profile_log_buffer,
  187. unsigned int **ptr)
  188. {
  189. *ptr += 1;
  190. if (*ptr >= (profile_log_buffer +
  191. ADRENO_PROFILE_LOG_BUF_SIZE_DWORDS))
  192. *ptr -= ADRENO_PROFILE_LOG_BUF_SIZE_DWORDS;
  193. }
  194. static inline unsigned int log_buf_available(struct adreno_profile *profile,
  195. unsigned int *head_ptr)
  196. {
  197. unsigned int tail, head;
  198. tail = (unsigned int) profile->log_tail -
  199. (unsigned int) profile->log_buffer;
  200. head = (unsigned int) head_ptr - (unsigned int) profile->log_buffer;
  201. if (tail > head)
  202. return (tail - head) / sizeof(unsigned int);
  203. else
  204. return ADRENO_PROFILE_LOG_BUF_SIZE_DWORDS - ((head - tail) /
  205. sizeof(unsigned int));
  206. }
  207. static inline unsigned int shared_buf_available(struct adreno_profile *profile)
  208. {
  209. if (profile->shared_tail > profile->shared_head)
  210. return profile->shared_tail - profile->shared_head;
  211. else
  212. return profile->shared_size -
  213. (profile->shared_head - profile->shared_tail);
  214. }
  215. static struct adreno_profile_assigns_list *_find_assignment_by_offset(
  216. struct adreno_profile *profile, unsigned int offset)
  217. {
  218. struct adreno_profile_assigns_list *entry;
  219. list_for_each_entry(entry, &profile->assignments_list, list) {
  220. if (entry->offset == offset)
  221. return entry;
  222. }
  223. return NULL;
  224. }
  225. static bool _in_assignments_list(struct adreno_profile *profile,
  226. unsigned int groupid, unsigned int countable)
  227. {
  228. struct adreno_profile_assigns_list *entry;
  229. list_for_each_entry(entry, &profile->assignments_list, list) {
  230. if (entry->groupid == groupid && entry->countable ==
  231. countable)
  232. return true;
  233. }
  234. return false;
  235. }
  236. static bool _add_to_assignments_list(struct adreno_profile *profile,
  237. const char *str, unsigned int groupid, unsigned int countable,
  238. unsigned int offset, unsigned int offset_hi)
  239. {
  240. struct adreno_profile_assigns_list *entry;
  241. /* first make sure we can alloc memory */
  242. entry = kmalloc(sizeof(struct adreno_profile_assigns_list), GFP_KERNEL);
  243. if (!entry)
  244. return false;
  245. list_add_tail(&entry->list, &profile->assignments_list);
  246. entry->countable = countable;
  247. entry->groupid = groupid;
  248. entry->offset = offset;
  249. entry->offset_hi = offset_hi;
  250. strlcpy(entry->name, str, sizeof(entry->name));
  251. profile->assignment_count++;
  252. return true;
  253. }
  254. static void check_close_profile(struct adreno_profile *profile)
  255. {
  256. if (profile == NULL || profile->log_buffer == NULL)
  257. return;
  258. if (!adreno_profile_enabled(profile) && shared_buf_empty(profile)) {
  259. if (profile->log_head == profile->log_tail) {
  260. vfree(profile->log_buffer);
  261. profile->log_buffer = NULL;
  262. profile->log_head = NULL;
  263. profile->log_tail = NULL;
  264. }
  265. }
  266. }
  267. static bool results_available(struct kgsl_device *device,
  268. unsigned int *shared_buf_tail)
  269. {
  270. unsigned int global_eop;
  271. struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
  272. struct adreno_profile *profile = &adreno_dev->profile;
  273. unsigned int off = profile->shared_tail;
  274. unsigned int *shared_ptr = (unsigned int *)
  275. profile->shared_buffer.hostptr;
  276. unsigned int ts, cnt;
  277. int ts_cmp;
  278. /*
  279. * If shared_buffer empty or Memstore EOP timestamp is less than
  280. * outstanding counter buffer timestamps then no results available
  281. */
  282. if (shared_buf_empty(profile))
  283. return false;
  284. global_eop = kgsl_readtimestamp(device, NULL, KGSL_TIMESTAMP_RETIRED);
  285. do {
  286. cnt = *(shared_ptr + off + 1);
  287. if (cnt == 0)
  288. return false;
  289. ts = *(shared_ptr + off);
  290. ts_cmp = timestamp_cmp(ts, global_eop);
  291. if (ts_cmp >= 0) {
  292. *shared_buf_tail = off;
  293. if (off == profile->shared_tail)
  294. return false;
  295. else
  296. return true;
  297. }
  298. shared_buf_inc(profile->shared_size, &off,
  299. SIZE_SHARED_ENTRY(cnt));
  300. } while (off != profile->shared_head);
  301. *shared_buf_tail = profile->shared_head;
  302. return true;
  303. }
  304. static void transfer_results(struct kgsl_device *device,
  305. unsigned int shared_buf_tail)
  306. {
  307. struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
  308. struct adreno_profile *profile = &adreno_dev->profile;
  309. unsigned int buf_off;
  310. unsigned int ts, cnt, ctxt_id, pid, tid, client_type;
  311. unsigned int *ptr = (unsigned int *) profile->shared_buffer.hostptr;
  312. struct kgsl_context *k_ctxt;
  313. unsigned int *log_ptr, *log_base;
  314. struct adreno_profile_assigns_list *assigns_list;
  315. int i;
  316. log_ptr = profile->log_head;
  317. log_base = profile->log_buffer;
  318. if (log_ptr == NULL)
  319. return;
  320. /*
  321. * go through counter buffers and format for write into log_buffer
  322. * if log buffer doesn't have space just overwrite it circularly
  323. * shared_buf is guaranteed to not wrap within an entry so can use
  324. * ptr increment
  325. */
  326. while (profile->shared_tail != shared_buf_tail) {
  327. buf_off = profile->shared_tail;
  328. /*
  329. * format: timestamp, count, context_id
  330. * count entries: pc_off, pc_start, pc_end
  331. */
  332. ts = *(ptr + buf_off);
  333. cnt = *(ptr + buf_off + 1);
  334. ctxt_id = *(ptr + buf_off + 2);
  335. /*
  336. * if entry overwrites the tail of log_buffer then adjust tail
  337. * ptr to make room for the new entry, discarding old entry
  338. */
  339. while (log_buf_available(profile, log_ptr) <=
  340. SIZE_LOG_ENTRY(cnt)) {
  341. unsigned int size_tail, boff;
  342. size_tail = SIZE_LOG_ENTRY(0xffff &
  343. *(profile->log_tail));
  344. boff = ((unsigned int) profile->log_tail -
  345. (unsigned int) log_base) / sizeof(unsigned int);
  346. log_buf_wrapcnt(size_tail, &boff);
  347. profile->log_tail = log_base + boff;
  348. }
  349. /* find Adreno ctxt struct */
  350. k_ctxt = idr_find(&device->context_idr, ctxt_id);
  351. if (k_ctxt == NULL) {
  352. shared_buf_inc(profile->shared_size,
  353. &profile->shared_tail,
  354. SIZE_SHARED_ENTRY(cnt));
  355. continue;
  356. } else {
  357. struct adreno_context *adreno_ctxt =
  358. ADRENO_CONTEXT(k_ctxt);
  359. pid = pid_nr(k_ctxt->proc_priv->pid); /* pid */
  360. tid = k_ctxt->tid; /* tid creator */
  361. client_type = adreno_ctxt->type << 16;
  362. }
  363. buf_off += 3;
  364. *log_ptr = client_type | cnt;
  365. log_buf_wrapinc(log_base, &log_ptr);
  366. *log_ptr = pid;
  367. log_buf_wrapinc(log_base, &log_ptr);
  368. *log_ptr = tid;
  369. log_buf_wrapinc(log_base, &log_ptr);
  370. *log_ptr = ctxt_id;
  371. log_buf_wrapinc(log_base, &log_ptr);
  372. *log_ptr = ts;
  373. log_buf_wrapinc(log_base, &log_ptr);
  374. for (i = 0; i < cnt; i++) {
  375. assigns_list = _find_assignment_by_offset(
  376. profile, *(ptr + buf_off++));
  377. if (assigns_list == NULL) {
  378. *log_ptr = (unsigned int) -1;
  379. shared_buf_inc(profile->shared_size,
  380. &profile->shared_tail,
  381. SIZE_SHARED_ENTRY(cnt));
  382. goto err;
  383. } else {
  384. *log_ptr = assigns_list->groupid << 16 |
  385. (assigns_list->countable & 0xffff);
  386. }
  387. log_buf_wrapinc(log_base, &log_ptr);
  388. *log_ptr = *(ptr + buf_off++); /* perf cntr start hi */
  389. log_buf_wrapinc(log_base, &log_ptr);
  390. *log_ptr = *(ptr + buf_off++); /* perf cntr start lo */
  391. log_buf_wrapinc(log_base, &log_ptr);
  392. *log_ptr = *(ptr + buf_off++); /* perf cntr end hi */
  393. log_buf_wrapinc(log_base, &log_ptr);
  394. *log_ptr = *(ptr + buf_off++); /* perf cntr end lo */
  395. log_buf_wrapinc(log_base, &log_ptr);
  396. }
  397. shared_buf_inc(profile->shared_size,
  398. &profile->shared_tail,
  399. SIZE_SHARED_ENTRY(cnt));
  400. }
  401. profile->log_head = log_ptr;
  402. return;
  403. err:
  404. /* reset head/tail to same on error in hopes we work correctly later */
  405. profile->log_head = profile->log_tail;
  406. }
  407. static int profile_enable_get(void *data, u64 *val)
  408. {
  409. struct kgsl_device *device = data;
  410. struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
  411. kgsl_mutex_lock(&device->mutex, &device->mutex_owner);
  412. *val = adreno_profile_enabled(&adreno_dev->profile);
  413. kgsl_mutex_unlock(&device->mutex, &device->mutex_owner);
  414. return 0;
  415. }
  416. static int profile_enable_set(void *data, u64 val)
  417. {
  418. struct kgsl_device *device = data;
  419. struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
  420. struct adreno_profile *profile = &adreno_dev->profile;
  421. kgsl_mutex_lock(&device->mutex, &device->mutex_owner);
  422. if (adreno_is_a2xx(adreno_dev)) {
  423. kgsl_mutex_unlock(&device->mutex, &device->mutex_owner);
  424. return 0;
  425. }
  426. profile->enabled = val;
  427. check_close_profile(profile);
  428. kgsl_mutex_unlock(&device->mutex, &device->mutex_owner);
  429. return 0;
  430. }
  431. static ssize_t profile_assignments_read(struct file *filep,
  432. char __user *ubuf, size_t max, loff_t *ppos)
  433. {
  434. struct kgsl_device *device = (struct kgsl_device *) filep->private_data;
  435. struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
  436. struct adreno_profile *profile = &adreno_dev->profile;
  437. struct adreno_profile_assigns_list *entry;
  438. int len = 0, max_size = PAGE_SIZE;
  439. char *buf, *pos;
  440. ssize_t size = 0;
  441. if (adreno_is_a2xx(adreno_dev))
  442. return -EINVAL;
  443. kgsl_mutex_lock(&device->mutex, &device->mutex_owner);
  444. buf = kmalloc(max_size, GFP_KERNEL);
  445. if (!buf) {
  446. kgsl_mutex_unlock(&device->mutex, &device->mutex_owner);
  447. return -ENOMEM;
  448. }
  449. pos = buf;
  450. /* copy all assingments from list to str */
  451. list_for_each_entry(entry, &profile->assignments_list, list) {
  452. len = snprintf(pos, max_size, ASSIGNS_STR_FORMAT,
  453. entry->name, entry->countable);
  454. max_size -= len;
  455. pos += len;
  456. }
  457. size = simple_read_from_buffer(ubuf, max, ppos, buf,
  458. strlen(buf));
  459. kfree(buf);
  460. kgsl_mutex_unlock(&device->mutex, &device->mutex_owner);
  461. return size;
  462. }
  463. static void _remove_assignment(struct adreno_device *adreno_dev,
  464. unsigned int groupid, unsigned int countable)
  465. {
  466. struct adreno_profile *profile = &adreno_dev->profile;
  467. struct adreno_profile_assigns_list *entry, *tmp;
  468. list_for_each_entry_safe(entry, tmp, &profile->assignments_list, list) {
  469. if (entry->groupid == groupid &&
  470. entry->countable == countable) {
  471. list_del(&entry->list);
  472. profile->assignment_count--;
  473. kfree(entry);
  474. /* remove from perf counter allocation */
  475. adreno_perfcounter_put(adreno_dev, groupid, countable,
  476. PERFCOUNTER_FLAG_KERNEL);
  477. }
  478. }
  479. }
  480. static void _add_assignment(struct adreno_device *adreno_dev,
  481. unsigned int groupid, unsigned int countable)
  482. {
  483. struct adreno_profile *profile = &adreno_dev->profile;
  484. unsigned int offset, offset_hi;
  485. const char *name = NULL;
  486. name = adreno_perfcounter_get_name(adreno_dev, groupid);
  487. if (!name)
  488. return;
  489. /* if already in assigned list skip it */
  490. if (_in_assignments_list(profile, groupid, countable))
  491. return;
  492. /* add to perf counter allocation, if fail skip it */
  493. if (adreno_perfcounter_get(adreno_dev, groupid, countable,
  494. &offset, &offset_hi, PERFCOUNTER_FLAG_NONE))
  495. return;
  496. /* add to assignments list, put counter back if error */
  497. if (!_add_to_assignments_list(profile, name, groupid,
  498. countable, offset, offset_hi))
  499. adreno_perfcounter_put(adreno_dev, groupid,
  500. countable, PERFCOUNTER_FLAG_KERNEL);
  501. }
  502. static char *_parse_next_assignment(struct adreno_device *adreno_dev,
  503. char *str, int *groupid, int *countable, bool *remove)
  504. {
  505. char *groupid_str, *countable_str, *next_str = NULL;
  506. int ret;
  507. *groupid = -EINVAL;
  508. *countable = -EINVAL;
  509. *remove = false;
  510. /* remove spaces */
  511. while (*str == ' ')
  512. str++;
  513. /* check if it's a remove assignment */
  514. if (*str == '-') {
  515. *remove = true;
  516. str++;
  517. }
  518. /* get the groupid string */
  519. groupid_str = str;
  520. while (*str != ':') {
  521. if (*str == '\0')
  522. return NULL;
  523. *str = tolower(*str);
  524. str++;
  525. }
  526. if (groupid_str == str)
  527. return NULL;
  528. *str = '\0';
  529. str++;
  530. /* get the countable string */
  531. countable_str = str;
  532. while (*str != ' ' && *str != '\0')
  533. str++;
  534. if (countable_str == str)
  535. return NULL;
  536. /*
  537. * If we have reached the end of the original string then make sure we
  538. * return NULL from this function or we could accidently overrun
  539. */
  540. if (*str != '\0') {
  541. *str = '\0';
  542. next_str = str + 1;
  543. }
  544. /* set results */
  545. *groupid = adreno_perfcounter_get_groupid(adreno_dev,
  546. groupid_str);
  547. if (*groupid < 0)
  548. return NULL;
  549. ret = kstrtou32(countable_str, 10, countable);
  550. if (ret)
  551. return NULL;
  552. return next_str;
  553. }
  554. static ssize_t profile_assignments_write(struct file *filep,
  555. const char __user *user_buf, size_t len, loff_t *off)
  556. {
  557. struct kgsl_device *device = (struct kgsl_device *) filep->private_data;
  558. struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
  559. struct adreno_profile *profile = &adreno_dev->profile;
  560. size_t size = 0;
  561. char *buf, *pbuf;
  562. bool remove_assignment = false;
  563. int groupid, countable, ret;
  564. if (len >= PAGE_SIZE || len == 0)
  565. return -EINVAL;
  566. if (adreno_is_a2xx(adreno_dev))
  567. return -ENOSPC;
  568. buf = kmalloc(len + 1, GFP_KERNEL);
  569. if (buf == NULL)
  570. return -ENOMEM;
  571. if (copy_from_user(buf, user_buf, len)) {
  572. size = -EFAULT;
  573. goto error_free;
  574. }
  575. kgsl_mutex_lock(&device->mutex, &device->mutex_owner);
  576. if (adreno_profile_enabled(profile)) {
  577. size = -EINVAL;
  578. goto error_unlock;
  579. }
  580. ret = kgsl_active_count_get(device);
  581. if (ret) {
  582. size = ret;
  583. goto error_unlock;
  584. }
  585. /*
  586. * When adding/removing assignments, ensure that the GPU is done with
  587. * all it's work. This helps to syncronize the work flow to the
  588. * GPU and avoid racey conditions.
  589. */
  590. if (adreno_idle(device)) {
  591. size = -ETIMEDOUT;
  592. goto error_put;
  593. }
  594. /* clear all shared buffer results */
  595. adreno_profile_process_results(device);
  596. pbuf = buf;
  597. /* clear the log buffer */
  598. if (profile->log_buffer != NULL) {
  599. profile->log_head = profile->log_buffer;
  600. profile->log_tail = profile->log_buffer;
  601. }
  602. /* for sanity and parsing, ensure it is null terminated */
  603. buf[len] = '\0';
  604. /* parse file buf and add(remove) to(from) appropriate lists */
  605. while (1) {
  606. pbuf = _parse_next_assignment(adreno_dev, pbuf, &groupid,
  607. &countable, &remove_assignment);
  608. if (pbuf == NULL)
  609. break;
  610. if (remove_assignment)
  611. _remove_assignment(adreno_dev, groupid, countable);
  612. else
  613. _add_assignment(adreno_dev, groupid, countable);
  614. }
  615. size = len;
  616. error_put:
  617. kgsl_active_count_put(device);
  618. error_unlock:
  619. kgsl_mutex_unlock(&device->mutex, &device->mutex_owner);
  620. error_free:
  621. kfree(buf);
  622. return size;
  623. }
  624. static int _pipe_print_pending(char *ubuf, size_t max)
  625. {
  626. loff_t unused = 0;
  627. char str[] = "Operation Would Block!";
  628. return simple_read_from_buffer(ubuf, max,
  629. &unused, str, strlen(str));
  630. }
  631. static int _pipe_print_results(struct adreno_device *adreno_dev,
  632. char *ubuf, size_t max)
  633. {
  634. struct adreno_profile *profile = &adreno_dev->profile;
  635. const char *grp_name;
  636. char *usr_buf = ubuf;
  637. unsigned int *log_ptr = NULL;
  638. int len, i;
  639. int status = 0;
  640. ssize_t size, total_size = 0;
  641. unsigned int cnt, api_type, ctxt_id, pid, tid, ts, cnt_reg;
  642. unsigned long long pc_start, pc_end;
  643. const char *api_str;
  644. char format_space;
  645. loff_t unused = 0;
  646. char pipe_hdr_buf[51]; /* 4 uint32 + 5 space + 5 API type + '\0' */
  647. char pipe_cntr_buf[63]; /* 2 uint64 + 1 uint32 + 4 spaces + 8 group */
  648. /* convert unread entries to ASCII, copy to user-space */
  649. log_ptr = profile->log_tail;
  650. do {
  651. cnt = *log_ptr & 0xffff;
  652. if (SIZE_PIPE_ENTRY(cnt) > max) {
  653. status = 0;
  654. goto err;
  655. }
  656. if ((max - (usr_buf - ubuf)) < SIZE_PIPE_ENTRY(cnt))
  657. break;
  658. api_type = *log_ptr >> 16;
  659. api_str = get_api_type_str(api_type);
  660. log_buf_wrapinc(profile->log_buffer, &log_ptr);
  661. pid = *log_ptr;
  662. log_buf_wrapinc(profile->log_buffer, &log_ptr);
  663. tid = *log_ptr;
  664. log_buf_wrapinc(profile->log_buffer, &log_ptr);
  665. ctxt_id = *log_ptr;
  666. log_buf_wrapinc(profile->log_buffer, &log_ptr);
  667. ts = *log_ptr;
  668. log_buf_wrapinc(profile->log_buffer, &log_ptr);
  669. len = snprintf(pipe_hdr_buf, sizeof(pipe_hdr_buf) - 1,
  670. "%u %u %u %.5s %u ",
  671. pid, tid, ctxt_id, api_str, ts);
  672. size = simple_read_from_buffer(usr_buf,
  673. max - (usr_buf - ubuf),
  674. &unused, pipe_hdr_buf, len);
  675. if (size < 0) {
  676. status = -EINVAL;
  677. goto err;
  678. }
  679. unused = 0;
  680. usr_buf += size;
  681. total_size += size;
  682. for (i = 0; i < cnt; i++) {
  683. grp_name = adreno_perfcounter_get_name(
  684. adreno_dev, *log_ptr >> 16);
  685. if (grp_name == NULL) {
  686. status = -EFAULT;
  687. goto err;
  688. }
  689. if (i == cnt - 1)
  690. format_space = '\n';
  691. else
  692. format_space = ' ';
  693. cnt_reg = *log_ptr & 0xffff;
  694. log_buf_wrapinc(profile->log_buffer, &log_ptr);
  695. pc_start = *((unsigned long long *) log_ptr);
  696. log_buf_wrapinc(profile->log_buffer, &log_ptr);
  697. log_buf_wrapinc(profile->log_buffer, &log_ptr);
  698. pc_end = *((unsigned long long *) log_ptr);
  699. log_buf_wrapinc(profile->log_buffer, &log_ptr);
  700. log_buf_wrapinc(profile->log_buffer, &log_ptr);
  701. len = snprintf(pipe_cntr_buf,
  702. sizeof(pipe_cntr_buf) - 1,
  703. "%.8s:%u %llu %llu%c",
  704. grp_name, cnt_reg, pc_start,
  705. pc_end, format_space);
  706. size = simple_read_from_buffer(usr_buf,
  707. max - (usr_buf - ubuf),
  708. &unused, pipe_cntr_buf, len);
  709. if (size < 0) {
  710. status = size;
  711. goto err;
  712. }
  713. unused = 0;
  714. usr_buf += size;
  715. total_size += size;
  716. }
  717. } while (log_ptr != profile->log_head);
  718. status = total_size;
  719. err:
  720. profile->log_tail = log_ptr;
  721. return status;
  722. }
  723. static int profile_pipe_print(struct file *filep, char __user *ubuf,
  724. size_t max, loff_t *ppos)
  725. {
  726. struct kgsl_device *device = (struct kgsl_device *) filep->private_data;
  727. struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
  728. struct adreno_profile *profile = &adreno_dev->profile;
  729. char *usr_buf = ubuf;
  730. int status = 0;
  731. if (adreno_is_a2xx(adreno_dev))
  732. return 0;
  733. /*
  734. * this file not seekable since it only supports streaming, ignore
  735. * ppos <> 0
  736. */
  737. /*
  738. * format <pid> <tid> <context id> <cnt<<16 | client type> <timestamp>
  739. * for each perf counter <cntr_reg_off> <start hi & lo> <end hi & low>
  740. */
  741. kgsl_mutex_lock(&device->mutex, &device->mutex_owner);
  742. while (1) {
  743. /* process any results that are available into the log_buffer */
  744. status = adreno_profile_process_results(device);
  745. if (status > 0) {
  746. /* if we have results, print them and exit */
  747. status = _pipe_print_results(adreno_dev, usr_buf, max);
  748. break;
  749. }
  750. /* there are no unread results, act accordingly */
  751. if (filep->f_flags & O_NONBLOCK) {
  752. if (profile->shared_tail != profile->shared_head) {
  753. status = _pipe_print_pending(usr_buf, max);
  754. break;
  755. } else {
  756. status = 0;
  757. break;
  758. }
  759. }
  760. kgsl_mutex_unlock(&device->mutex, &device->mutex_owner);
  761. set_current_state(TASK_INTERRUPTIBLE);
  762. schedule_timeout(msecs_to_jiffies(100));
  763. kgsl_mutex_lock(&device->mutex, &device->mutex_owner);
  764. if (signal_pending(current)) {
  765. status = 0;
  766. break;
  767. }
  768. }
  769. check_close_profile(profile);
  770. kgsl_mutex_unlock(&device->mutex, &device->mutex_owner);
  771. return status;
  772. }
  773. static int profile_groups_print(struct seq_file *s, void *unused)
  774. {
  775. struct kgsl_device *device = (struct kgsl_device *) s->private;
  776. struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
  777. struct adreno_perfcounters *counters = adreno_dev->gpudev->perfcounters;
  778. struct adreno_perfcount_group *group;
  779. int i, j, used;
  780. /* perfcounter list not allowed on a2xx */
  781. if (adreno_is_a2xx(adreno_dev))
  782. return -EINVAL;
  783. kgsl_mutex_lock(&device->mutex, &device->mutex_owner);
  784. for (i = 0; i < counters->group_count; ++i) {
  785. group = &(counters->groups[i]);
  786. /* get number of counters used for this group */
  787. used = 0;
  788. for (j = 0; j < group->reg_count; j++) {
  789. if (group->regs[j].countable !=
  790. KGSL_PERFCOUNTER_NOT_USED)
  791. used++;
  792. }
  793. seq_printf(s, "%s %d %d\n", group->name,
  794. group->reg_count, used);
  795. }
  796. kgsl_mutex_unlock(&device->mutex, &device->mutex_owner);
  797. return 0;
  798. }
  799. static int profile_groups_open(struct inode *inode, struct file *file)
  800. {
  801. return single_open(file, profile_groups_print, inode->i_private);
  802. }
  803. static const struct file_operations profile_groups_fops = {
  804. .owner = THIS_MODULE,
  805. .open = profile_groups_open,
  806. .read = seq_read,
  807. .llseek = noop_llseek,
  808. .release = single_release,
  809. };
  810. static const struct file_operations profile_pipe_fops = {
  811. .owner = THIS_MODULE,
  812. .open = simple_open,
  813. .read = profile_pipe_print,
  814. .llseek = noop_llseek,
  815. };
  816. static const struct file_operations profile_assignments_fops = {
  817. .owner = THIS_MODULE,
  818. .open = simple_open,
  819. .read = profile_assignments_read,
  820. .write = profile_assignments_write,
  821. .llseek = noop_llseek,
  822. };
  823. DEFINE_SIMPLE_ATTRIBUTE(profile_enable_fops,
  824. profile_enable_get,
  825. profile_enable_set, "%llu\n");
  826. void adreno_profile_init(struct kgsl_device *device)
  827. {
  828. struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
  829. struct adreno_profile *profile = &adreno_dev->profile;
  830. struct dentry *profile_dir;
  831. int ret;
  832. profile->enabled = false;
  833. /* allocate shared_buffer, which includes pre_ib and post_ib */
  834. profile->shared_size = ADRENO_PROFILE_SHARED_BUF_SIZE_DWORDS;
  835. ret = kgsl_allocate_contiguous(&profile->shared_buffer,
  836. profile->shared_size * sizeof(unsigned int));
  837. if (ret) {
  838. profile->shared_buffer.hostptr = NULL;
  839. profile->shared_size = 0;
  840. }
  841. INIT_LIST_HEAD(&profile->assignments_list);
  842. /* Create perf counter debugfs */
  843. profile_dir = debugfs_create_dir("profiling", device->d_debugfs);
  844. if (IS_ERR(profile_dir))
  845. return;
  846. debugfs_create_file("enable", 0644, profile_dir, device,
  847. &profile_enable_fops);
  848. debugfs_create_file("blocks", 0444, profile_dir, device,
  849. &profile_groups_fops);
  850. debugfs_create_file("pipe", 0444, profile_dir, device,
  851. &profile_pipe_fops);
  852. debugfs_create_file("assignments", 0644, profile_dir, device,
  853. &profile_assignments_fops);
  854. }
  855. void adreno_profile_close(struct kgsl_device *device)
  856. {
  857. struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
  858. struct adreno_profile *profile = &adreno_dev->profile;
  859. struct adreno_profile_assigns_list *entry, *tmp;
  860. profile->enabled = false;
  861. vfree(profile->log_buffer);
  862. profile->log_buffer = NULL;
  863. profile->log_head = NULL;
  864. profile->log_tail = NULL;
  865. profile->shared_head = 0;
  866. profile->shared_tail = 0;
  867. kgsl_sharedmem_free(&profile->shared_buffer);
  868. profile->shared_buffer.hostptr = NULL;
  869. profile->shared_size = 0;
  870. profile->assignment_count = 0;
  871. list_for_each_entry_safe(entry, tmp, &profile->assignments_list, list) {
  872. list_del(&entry->list);
  873. kfree(entry);
  874. }
  875. }
  876. int adreno_profile_process_results(struct kgsl_device *device)
  877. {
  878. struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
  879. struct adreno_profile *profile = &adreno_dev->profile;
  880. unsigned int shared_buf_tail = profile->shared_tail;
  881. if (!results_available(device, &shared_buf_tail)) {
  882. check_close_profile(profile);
  883. return 0;
  884. }
  885. /* allocate profile_log_buffer if needed */
  886. if (profile->log_buffer == NULL) {
  887. profile->log_buffer = vmalloc(ADRENO_PROFILE_LOG_BUF_SIZE);
  888. if (profile->log_buffer == NULL)
  889. return -ENOMEM;
  890. profile->log_tail = profile->log_buffer;
  891. profile->log_head = profile->log_buffer;
  892. }
  893. /*
  894. * transfer retired results to log_buffer
  895. * update shared_buffer tail ptr
  896. */
  897. transfer_results(device, shared_buf_tail);
  898. return 1;
  899. }
  900. void adreno_profile_preib_processing(struct kgsl_device *device,
  901. unsigned int context_id, unsigned int *cmd_flags,
  902. unsigned int **rbptr, unsigned int *cmds_gpu)
  903. {
  904. struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
  905. struct adreno_profile *profile = &adreno_dev->profile;
  906. int count = profile->assignment_count;
  907. unsigned int entry_head = profile->shared_head;
  908. unsigned int *shared_ptr;
  909. struct adreno_ringbuffer *rb = &adreno_dev->ringbuffer;
  910. unsigned int rbcmds[3] = { cp_nop_packet(2),
  911. KGSL_NOP_IB_IDENTIFIER, KGSL_NOP_IB_IDENTIFIER };
  912. *cmd_flags &= ~KGSL_CMD_FLAGS_PROFILE;
  913. if (!adreno_profile_assignments_ready(profile))
  914. goto done;
  915. /*
  916. * check if space available, include the post_ib in space available
  917. * check so don't have to handle trying to undo the pre_ib insertion in
  918. * ringbuffer in the case where only the post_ib fails enough space
  919. */
  920. if (SIZE_SHARED_ENTRY(count) >= shared_buf_available(profile))
  921. goto done;
  922. if (entry_head + SIZE_SHARED_ENTRY(count) >= profile->shared_size) {
  923. /* entry_head would wrap, start entry_head at 0 in buffer */
  924. entry_head = 0;
  925. profile->shared_size = profile->shared_head;
  926. profile->shared_head = 0;
  927. if (profile->shared_tail == profile->shared_size)
  928. profile->shared_tail = 0;
  929. /* recheck space available */
  930. if (SIZE_SHARED_ENTRY(count) >= shared_buf_available(profile))
  931. goto done;
  932. }
  933. /* zero out the counter area of shared_buffer entry_head */
  934. shared_ptr = entry_head + ((unsigned int *)
  935. profile->shared_buffer.hostptr);
  936. memset(shared_ptr, 0, SIZE_SHARED_ENTRY(count) * sizeof(unsigned int));
  937. /* reserve space for the pre ib shared buffer */
  938. shared_buf_inc(profile->shared_size, &profile->shared_head,
  939. SIZE_SHARED_ENTRY(count));
  940. /* create the shared ibdesc */
  941. _build_pre_ib_cmds(profile, rbcmds, entry_head,
  942. rb->global_ts + 1, context_id);
  943. /* set flag to sync with post ib commands */
  944. *cmd_flags |= KGSL_CMD_FLAGS_PROFILE;
  945. done:
  946. /* write the ibdesc to the ringbuffer */
  947. GSL_RB_WRITE(device, (*rbptr), (*cmds_gpu), rbcmds[0]);
  948. GSL_RB_WRITE(device, (*rbptr), (*cmds_gpu), rbcmds[1]);
  949. GSL_RB_WRITE(device, (*rbptr), (*cmds_gpu), rbcmds[2]);
  950. }
  951. void adreno_profile_postib_processing(struct kgsl_device *device,
  952. unsigned int *cmd_flags, unsigned int **rbptr,
  953. unsigned int *cmds_gpu)
  954. {
  955. struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
  956. struct adreno_profile *profile = &adreno_dev->profile;
  957. int count = profile->assignment_count;
  958. unsigned int entry_head = profile->shared_head -
  959. SIZE_SHARED_ENTRY(count);
  960. unsigned int rbcmds[3] = { cp_nop_packet(2),
  961. KGSL_NOP_IB_IDENTIFIER, KGSL_NOP_IB_IDENTIFIER };
  962. if (!adreno_profile_assignments_ready(profile))
  963. goto done;
  964. if (!(*cmd_flags & KGSL_CMD_FLAGS_PROFILE))
  965. goto done;
  966. /* create the shared ibdesc */
  967. _build_post_ib_cmds(profile, rbcmds, entry_head);
  968. done:
  969. /* write the ibdesc to the ringbuffer */
  970. GSL_RB_WRITE(device, (*rbptr), (*cmds_gpu), rbcmds[0]);
  971. GSL_RB_WRITE(device, (*rbptr), (*cmds_gpu), rbcmds[1]);
  972. GSL_RB_WRITE(device, (*rbptr), (*cmds_gpu), rbcmds[2]);
  973. /* reset the sync flag */
  974. *cmd_flags &= ~KGSL_CMD_FLAGS_PROFILE;
  975. }