kgsl_sync.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412
  1. /* Copyright (c) 2012-2014, 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/err.h>
  14. #include <linux/file.h>
  15. #include <linux/sched.h>
  16. #include <linux/slab.h>
  17. #include <linux/uaccess.h>
  18. #include <asm/current.h>
  19. #include "kgsl_sync.h"
  20. struct sync_pt *kgsl_sync_pt_create(struct sync_timeline *timeline,
  21. struct kgsl_context *context, unsigned int timestamp)
  22. {
  23. struct sync_pt *pt;
  24. pt = sync_pt_create(timeline, (int) sizeof(struct kgsl_sync_pt));
  25. if (pt) {
  26. struct kgsl_sync_pt *kpt = (struct kgsl_sync_pt *) pt;
  27. kpt->context = context;
  28. kpt->timestamp = timestamp;
  29. }
  30. return pt;
  31. }
  32. /*
  33. * This should only be called on sync_pts which have been created but
  34. * not added to a fence.
  35. */
  36. void kgsl_sync_pt_destroy(struct sync_pt *pt)
  37. {
  38. sync_pt_free(pt);
  39. }
  40. static struct sync_pt *kgsl_sync_pt_dup(struct sync_pt *pt)
  41. {
  42. struct kgsl_sync_pt *kpt = (struct kgsl_sync_pt *) pt;
  43. return kgsl_sync_pt_create(pt->parent, kpt->context, kpt->timestamp);
  44. }
  45. static int kgsl_sync_pt_has_signaled(struct sync_pt *pt)
  46. {
  47. struct kgsl_sync_pt *kpt = (struct kgsl_sync_pt *) pt;
  48. struct kgsl_sync_timeline *ktimeline =
  49. (struct kgsl_sync_timeline *) pt->parent;
  50. unsigned int ts = kpt->timestamp;
  51. unsigned int last_ts = ktimeline->last_timestamp;
  52. if (timestamp_cmp(last_ts, ts) >= 0) {
  53. /* signaled */
  54. return 1;
  55. }
  56. return 0;
  57. }
  58. static int kgsl_sync_pt_compare(struct sync_pt *a, struct sync_pt *b)
  59. {
  60. struct kgsl_sync_pt *kpt_a = (struct kgsl_sync_pt *) a;
  61. struct kgsl_sync_pt *kpt_b = (struct kgsl_sync_pt *) b;
  62. unsigned int ts_a = kpt_a->timestamp;
  63. unsigned int ts_b = kpt_b->timestamp;
  64. return timestamp_cmp(ts_a, ts_b);
  65. }
  66. struct kgsl_fence_event_priv {
  67. struct kgsl_context *context;
  68. unsigned int timestamp;
  69. };
  70. /**
  71. * kgsl_fence_event_cb - Event callback for a fence timestamp event
  72. * @device - The KGSL device that expired the timestamp
  73. * @context- Pointer to the context that owns the event
  74. * @priv: Private data for the callback
  75. * @result - Result of the event (retired or canceled)
  76. *
  77. * Signal a fence following the expiration of a timestamp
  78. */
  79. static void kgsl_fence_event_cb(struct kgsl_device *device,
  80. struct kgsl_context *context, void *priv, int result)
  81. {
  82. struct kgsl_fence_event_priv *ev = priv;
  83. kgsl_sync_timeline_signal(ev->context->timeline, ev->timestamp);
  84. kgsl_context_put(ev->context);
  85. kfree(ev);
  86. }
  87. static int _add_fence_event(struct kgsl_device *device,
  88. struct kgsl_context *context, unsigned int timestamp)
  89. {
  90. struct kgsl_fence_event_priv *event;
  91. int ret;
  92. event = kmalloc(sizeof(*event), GFP_KERNEL);
  93. if (event == NULL)
  94. return -ENOMEM;
  95. /*
  96. * Increase the refcount for the context to keep it through the
  97. * callback
  98. */
  99. _kgsl_context_get(context);
  100. event->context = context;
  101. event->timestamp = timestamp;
  102. event->context = context;
  103. ret = kgsl_add_event(device, &context->events, timestamp,
  104. kgsl_fence_event_cb, event);
  105. if (ret) {
  106. kgsl_context_put(context);
  107. kfree(event);
  108. }
  109. return ret;
  110. }
  111. /**
  112. * kgsl_add_fence_event - Create a new fence event
  113. * @device - KGSL device to create the event on
  114. * @timestamp - Timestamp to trigger the event
  115. * @data - Return fence fd stored in struct kgsl_timestamp_event_fence
  116. * @len - length of the fence event
  117. * @owner - driver instance that owns this event
  118. * @returns 0 on success or error code on error
  119. *
  120. * Create a fence and register an event to signal the fence when
  121. * the timestamp expires
  122. */
  123. int kgsl_add_fence_event(struct kgsl_device *device,
  124. u32 context_id, u32 timestamp, void __user *data, int len,
  125. struct kgsl_device_private *owner)
  126. {
  127. struct kgsl_timestamp_event_fence priv;
  128. struct kgsl_context *context;
  129. struct sync_pt *pt;
  130. struct sync_fence *fence = NULL;
  131. int ret = -EINVAL;
  132. char fence_name[sizeof(fence->name)] = {};
  133. unsigned int cur;
  134. priv.fence_fd = -1;
  135. if (len != sizeof(priv))
  136. return -EINVAL;
  137. kgsl_mutex_lock(&device->mutex, &device->mutex_owner);
  138. context = kgsl_context_get_owner(owner, context_id);
  139. if (context == NULL)
  140. goto unlock;
  141. pt = kgsl_sync_pt_create(context->timeline, context, timestamp);
  142. if (pt == NULL) {
  143. KGSL_DRV_ERR(device, "kgsl_sync_pt_create failed\n");
  144. ret = -ENOMEM;
  145. goto unlock;
  146. }
  147. snprintf(fence_name, sizeof(fence_name),
  148. "%s-pid-%d-ctx-%d-ts-%d",
  149. device->name, current->group_leader->pid,
  150. context_id, timestamp);
  151. fence = sync_fence_create(fence_name, pt);
  152. if (fence == NULL) {
  153. /* only destroy pt when not added to fence */
  154. kgsl_sync_pt_destroy(pt);
  155. KGSL_DRV_ERR(device, "sync_fence_create failed\n");
  156. ret = -ENOMEM;
  157. goto unlock;
  158. }
  159. priv.fence_fd = get_unused_fd_flags(0);
  160. if (priv.fence_fd < 0) {
  161. KGSL_DRV_ERR(device, "Unable to get a file descriptor: %d\n",
  162. priv.fence_fd);
  163. ret = priv.fence_fd;
  164. goto unlock;
  165. }
  166. /*
  167. * If the timestamp hasn't expired yet create an event to trigger it.
  168. * Otherwise, just signal the fence - there is no reason to go through
  169. * the effort of creating a fence we don't need.
  170. */
  171. cur = kgsl_readtimestamp(device, context, KGSL_TIMESTAMP_RETIRED);
  172. if (timestamp_cmp(cur, timestamp) >= 0)
  173. kgsl_sync_timeline_signal(context->timeline, cur);
  174. else {
  175. ret = _add_fence_event(device, context, timestamp);
  176. if (ret)
  177. goto unlock;
  178. }
  179. kgsl_context_put(context);
  180. /* We released the context, so we must not use it again. */
  181. context = NULL;
  182. /* Unlock the mutex before copying to user */
  183. kgsl_mutex_unlock(&device->mutex, &device->mutex_owner);
  184. if (copy_to_user(data, &priv, sizeof(priv))) {
  185. ret = -EFAULT;
  186. goto out;
  187. }
  188. sync_fence_install(fence, priv.fence_fd);
  189. return 0;
  190. unlock:
  191. kgsl_mutex_unlock(&device->mutex, &device->mutex_owner);
  192. out:
  193. if (priv.fence_fd >= 0)
  194. put_unused_fd(priv.fence_fd);
  195. if (fence)
  196. sync_fence_put(fence);
  197. kgsl_context_put(context);
  198. return ret;
  199. }
  200. static unsigned int kgsl_sync_get_timestamp(
  201. struct kgsl_sync_timeline *ktimeline, enum kgsl_timestamp_type type)
  202. {
  203. unsigned int ret = 0;
  204. struct kgsl_context *context = kgsl_context_get(ktimeline->device,
  205. ktimeline->context_id);
  206. if (context)
  207. ret = kgsl_readtimestamp(ktimeline->device, context, type);
  208. kgsl_context_put(context);
  209. return ret;
  210. }
  211. static void kgsl_sync_timeline_value_str(struct sync_timeline *sync_timeline,
  212. char *str, int size)
  213. {
  214. struct kgsl_sync_timeline *ktimeline =
  215. (struct kgsl_sync_timeline *) sync_timeline;
  216. unsigned int timestamp_retired = kgsl_sync_get_timestamp(ktimeline,
  217. KGSL_TIMESTAMP_RETIRED);
  218. snprintf(str, size, "%u retired:%u", ktimeline->last_timestamp,
  219. timestamp_retired);
  220. }
  221. static void kgsl_sync_pt_value_str(struct sync_pt *sync_pt,
  222. char *str, int size)
  223. {
  224. struct kgsl_sync_pt *kpt = (struct kgsl_sync_pt *) sync_pt;
  225. snprintf(str, size, "%u", kpt->timestamp);
  226. }
  227. static void kgsl_sync_pt_log(struct sync_pt *sync_pt)
  228. {
  229. struct kgsl_sync_pt *kpt = (struct kgsl_sync_pt *) sync_pt;
  230. pr_info("-----\n");
  231. kgsl_context_dump(kpt->context);
  232. pr_info("-----\n");
  233. }
  234. static void kgsl_sync_timeline_release_obj(struct sync_timeline *sync_timeline)
  235. {
  236. /*
  237. * Make sure to free the timeline only after destroy flag is set.
  238. * This is to avoid further accessing to the timeline from KGSL and
  239. * also to catch any unbalanced kref of timeline.
  240. */
  241. BUG_ON(sync_timeline && (sync_timeline->destroyed != true));
  242. }
  243. static const struct sync_timeline_ops kgsl_sync_timeline_ops = {
  244. .driver_name = "kgsl-timeline",
  245. .dup = kgsl_sync_pt_dup,
  246. .has_signaled = kgsl_sync_pt_has_signaled,
  247. .compare = kgsl_sync_pt_compare,
  248. .timeline_value_str = kgsl_sync_timeline_value_str,
  249. .pt_value_str = kgsl_sync_pt_value_str,
  250. .release_obj = kgsl_sync_timeline_release_obj,
  251. .pt_log = kgsl_sync_pt_log,
  252. };
  253. int kgsl_sync_timeline_create(struct kgsl_context *context)
  254. {
  255. struct kgsl_sync_timeline *ktimeline;
  256. /* Generate a name which includes the thread name, thread id, process
  257. * name, process id, and context id. This makes it possible to
  258. * identify the context of a timeline in the sync dump. */
  259. char ktimeline_name[sizeof(context->timeline->name)] = {};
  260. snprintf(ktimeline_name, sizeof(ktimeline_name),
  261. "%s_%.15s(%d)-%.15s(%d)-%d",
  262. context->device->name,
  263. current->group_leader->comm, current->group_leader->pid,
  264. current->comm, current->pid, context->id);
  265. context->timeline = sync_timeline_create(&kgsl_sync_timeline_ops,
  266. (int) sizeof(struct kgsl_sync_timeline), ktimeline_name);
  267. if (context->timeline == NULL)
  268. return -EINVAL;
  269. ktimeline = (struct kgsl_sync_timeline *) context->timeline;
  270. ktimeline->last_timestamp = 0;
  271. ktimeline->device = context->device;
  272. ktimeline->context_id = context->id;
  273. return 0;
  274. }
  275. void kgsl_sync_timeline_signal(struct sync_timeline *timeline,
  276. unsigned int timestamp)
  277. {
  278. struct kgsl_sync_timeline *ktimeline =
  279. (struct kgsl_sync_timeline *) timeline;
  280. if (timestamp_cmp(timestamp, ktimeline->last_timestamp) > 0)
  281. ktimeline->last_timestamp = timestamp;
  282. sync_timeline_signal(timeline);
  283. }
  284. void kgsl_sync_timeline_destroy(struct kgsl_context *context)
  285. {
  286. sync_timeline_destroy(context->timeline);
  287. }
  288. static void kgsl_sync_callback(struct sync_fence *fence,
  289. struct sync_fence_waiter *waiter)
  290. {
  291. struct kgsl_sync_fence_waiter *kwaiter =
  292. (struct kgsl_sync_fence_waiter *) waiter;
  293. kwaiter->func(kwaiter->priv);
  294. sync_fence_put(kwaiter->fence);
  295. kfree(kwaiter);
  296. }
  297. struct kgsl_sync_fence_waiter *kgsl_sync_fence_async_wait(int fd,
  298. void (*func)(void *priv), void *priv)
  299. {
  300. struct kgsl_sync_fence_waiter *kwaiter;
  301. struct sync_fence *fence;
  302. int status;
  303. fence = sync_fence_fdget(fd);
  304. if (fence == NULL)
  305. return ERR_PTR(-EINVAL);
  306. /* create the waiter */
  307. kwaiter = kzalloc(sizeof(*kwaiter), GFP_ATOMIC);
  308. if (kwaiter == NULL) {
  309. sync_fence_put(fence);
  310. return ERR_PTR(-ENOMEM);
  311. }
  312. kwaiter->fence = fence;
  313. kwaiter->priv = priv;
  314. kwaiter->func = func;
  315. strlcpy(kwaiter->name, fence->name, sizeof(kwaiter->name));
  316. sync_fence_waiter_init((struct sync_fence_waiter *) kwaiter,
  317. kgsl_sync_callback);
  318. /* if status then error or signaled */
  319. status = sync_fence_wait_async(fence,
  320. (struct sync_fence_waiter *) kwaiter);
  321. if (status) {
  322. kfree(kwaiter);
  323. sync_fence_put(fence);
  324. if (status < 0)
  325. kwaiter = ERR_PTR(status);
  326. else
  327. kwaiter = NULL;
  328. }
  329. return kwaiter;
  330. }
  331. int kgsl_sync_fence_async_cancel(struct kgsl_sync_fence_waiter *kwaiter)
  332. {
  333. if (kwaiter == NULL)
  334. return 0;
  335. if (sync_fence_cancel_async(kwaiter->fence,
  336. (struct sync_fence_waiter *) kwaiter) == 0) {
  337. sync_fence_put(kwaiter->fence);
  338. kfree(kwaiter);
  339. return 1;
  340. }
  341. return 0;
  342. }