0297-vchiq_arm-Add-completion-records-under-the-mutex.patch 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. From 249ccc9a345b7641aaf276867a375cd50f41627d Mon Sep 17 00:00:00 2001
  2. From: Phil Elwell <phil@raspberrypi.org>
  3. Date: Thu, 21 Apr 2016 13:49:32 +0100
  4. Subject: [PATCH] vchiq_arm: Add completion records under the mutex
  5. An issue was observed when flushing openmax components
  6. which generate a large number of messages returning
  7. buffers to host.
  8. We occasionally found a duplicate message from 16
  9. messages prior, resulting in a buffer returned twice.
  10. While only one thread adds completions, without the
  11. mutex you don't get the protection of the automatic
  12. memory barrier you get with synchronisation objects.
  13. Signed-off-by: Phil Elwell <phil@raspberrypi.org>
  14. ---
  15. drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c | 13 ++++++++++++-
  16. 1 file changed, 12 insertions(+), 1 deletion(-)
  17. --- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c
  18. +++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c
  19. @@ -210,6 +210,8 @@ add_completion(VCHIQ_INSTANCE_T instance
  20. VCHIQ_COMPLETION_DATA_T *completion;
  21. DEBUG_INITIALISE(g_state.local)
  22. + mutex_lock(&instance->completion_mutex);
  23. +
  24. while (instance->completion_insert ==
  25. (instance->completion_remove + MAX_COMPLETIONS)) {
  26. /* Out of space - wait for the client */
  27. @@ -217,11 +219,17 @@ add_completion(VCHIQ_INSTANCE_T instance
  28. vchiq_log_trace(vchiq_arm_log_level,
  29. "add_completion - completion queue full");
  30. DEBUG_COUNT(COMPLETION_QUEUE_FULL_COUNT);
  31. +
  32. + mutex_unlock(&instance->completion_mutex);
  33. if (down_interruptible(&instance->remove_event) != 0) {
  34. vchiq_log_info(vchiq_arm_log_level,
  35. "service_callback interrupted");
  36. return VCHIQ_RETRY;
  37. - } else if (instance->closing) {
  38. + }
  39. +
  40. + mutex_lock(&instance->completion_mutex);
  41. + if (instance->closing) {
  42. + mutex_unlock(&instance->completion_mutex);
  43. vchiq_log_info(vchiq_arm_log_level,
  44. "service_callback closing");
  45. return VCHIQ_SUCCESS;
  46. @@ -254,8 +262,11 @@ add_completion(VCHIQ_INSTANCE_T instance
  47. if (reason == VCHIQ_MESSAGE_AVAILABLE)
  48. user_service->message_available_pos =
  49. instance->completion_insert;
  50. +
  51. instance->completion_insert++;
  52. + mutex_unlock(&instance->completion_mutex);
  53. +
  54. up(&instance->insert_event);
  55. return VCHIQ_SUCCESS;