watchdog_pretimeout.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * Copyright (C) 2015-2016 Mentor Graphics
  4. */
  5. #include <linux/list.h>
  6. #include <linux/slab.h>
  7. #include <linux/spinlock.h>
  8. #include <linux/string.h>
  9. #include <linux/watchdog.h>
  10. #include "watchdog_core.h"
  11. #include "watchdog_pretimeout.h"
  12. /* Default watchdog pretimeout governor */
  13. static struct watchdog_governor *default_gov;
  14. /* The spinlock protects default_gov, wdd->gov and pretimeout_list */
  15. static DEFINE_SPINLOCK(pretimeout_lock);
  16. /* List of watchdog devices, which can generate a pretimeout event */
  17. static LIST_HEAD(pretimeout_list);
  18. struct watchdog_pretimeout {
  19. struct watchdog_device *wdd;
  20. struct list_head entry;
  21. };
  22. /* The mutex protects governor list and serializes external interfaces */
  23. static DEFINE_MUTEX(governor_lock);
  24. /* List of the registered watchdog pretimeout governors */
  25. static LIST_HEAD(governor_list);
  26. struct governor_priv {
  27. struct watchdog_governor *gov;
  28. struct list_head entry;
  29. };
  30. static struct governor_priv *find_governor_by_name(const char *gov_name)
  31. {
  32. struct governor_priv *priv;
  33. list_for_each_entry(priv, &governor_list, entry)
  34. if (sysfs_streq(gov_name, priv->gov->name))
  35. return priv;
  36. return NULL;
  37. }
  38. int watchdog_pretimeout_available_governors_get(char *buf)
  39. {
  40. struct governor_priv *priv;
  41. int count = 0;
  42. mutex_lock(&governor_lock);
  43. list_for_each_entry(priv, &governor_list, entry)
  44. count += sysfs_emit_at(buf, count, "%s\n", priv->gov->name);
  45. mutex_unlock(&governor_lock);
  46. return count;
  47. }
  48. int watchdog_pretimeout_governor_get(struct watchdog_device *wdd, char *buf)
  49. {
  50. int count = 0;
  51. spin_lock_irq(&pretimeout_lock);
  52. if (wdd->gov)
  53. count = sysfs_emit(buf, "%s\n", wdd->gov->name);
  54. spin_unlock_irq(&pretimeout_lock);
  55. return count;
  56. }
  57. int watchdog_pretimeout_governor_set(struct watchdog_device *wdd,
  58. const char *buf)
  59. {
  60. struct governor_priv *priv;
  61. mutex_lock(&governor_lock);
  62. priv = find_governor_by_name(buf);
  63. if (!priv) {
  64. mutex_unlock(&governor_lock);
  65. return -EINVAL;
  66. }
  67. spin_lock_irq(&pretimeout_lock);
  68. wdd->gov = priv->gov;
  69. spin_unlock_irq(&pretimeout_lock);
  70. mutex_unlock(&governor_lock);
  71. return 0;
  72. }
  73. void watchdog_notify_pretimeout(struct watchdog_device *wdd)
  74. {
  75. unsigned long flags;
  76. spin_lock_irqsave(&pretimeout_lock, flags);
  77. if (!wdd->gov) {
  78. spin_unlock_irqrestore(&pretimeout_lock, flags);
  79. return;
  80. }
  81. wdd->gov->pretimeout(wdd);
  82. spin_unlock_irqrestore(&pretimeout_lock, flags);
  83. }
  84. EXPORT_SYMBOL_GPL(watchdog_notify_pretimeout);
  85. int watchdog_register_governor(struct watchdog_governor *gov)
  86. {
  87. struct watchdog_pretimeout *p;
  88. struct governor_priv *priv;
  89. priv = kzalloc(sizeof(*priv), GFP_KERNEL);
  90. if (!priv)
  91. return -ENOMEM;
  92. mutex_lock(&governor_lock);
  93. if (find_governor_by_name(gov->name)) {
  94. mutex_unlock(&governor_lock);
  95. kfree(priv);
  96. return -EBUSY;
  97. }
  98. priv->gov = gov;
  99. list_add(&priv->entry, &governor_list);
  100. if (!strncmp(gov->name, WATCHDOG_PRETIMEOUT_DEFAULT_GOV,
  101. WATCHDOG_GOV_NAME_MAXLEN)) {
  102. spin_lock_irq(&pretimeout_lock);
  103. default_gov = gov;
  104. list_for_each_entry(p, &pretimeout_list, entry)
  105. if (!p->wdd->gov)
  106. p->wdd->gov = default_gov;
  107. spin_unlock_irq(&pretimeout_lock);
  108. }
  109. mutex_unlock(&governor_lock);
  110. return 0;
  111. }
  112. EXPORT_SYMBOL(watchdog_register_governor);
  113. void watchdog_unregister_governor(struct watchdog_governor *gov)
  114. {
  115. struct watchdog_pretimeout *p;
  116. struct governor_priv *priv, *t;
  117. mutex_lock(&governor_lock);
  118. list_for_each_entry_safe(priv, t, &governor_list, entry) {
  119. if (priv->gov == gov) {
  120. list_del(&priv->entry);
  121. kfree(priv);
  122. break;
  123. }
  124. }
  125. spin_lock_irq(&pretimeout_lock);
  126. list_for_each_entry(p, &pretimeout_list, entry)
  127. if (p->wdd->gov == gov)
  128. p->wdd->gov = default_gov;
  129. spin_unlock_irq(&pretimeout_lock);
  130. mutex_unlock(&governor_lock);
  131. }
  132. EXPORT_SYMBOL(watchdog_unregister_governor);
  133. int watchdog_register_pretimeout(struct watchdog_device *wdd)
  134. {
  135. struct watchdog_pretimeout *p;
  136. if (!watchdog_have_pretimeout(wdd))
  137. return 0;
  138. p = kzalloc(sizeof(*p), GFP_KERNEL);
  139. if (!p)
  140. return -ENOMEM;
  141. spin_lock_irq(&pretimeout_lock);
  142. list_add(&p->entry, &pretimeout_list);
  143. p->wdd = wdd;
  144. wdd->gov = default_gov;
  145. spin_unlock_irq(&pretimeout_lock);
  146. return 0;
  147. }
  148. void watchdog_unregister_pretimeout(struct watchdog_device *wdd)
  149. {
  150. struct watchdog_pretimeout *p, *t;
  151. if (!watchdog_have_pretimeout(wdd))
  152. return;
  153. spin_lock_irq(&pretimeout_lock);
  154. wdd->gov = NULL;
  155. list_for_each_entry_safe(p, t, &pretimeout_list, entry) {
  156. if (p->wdd == wdd) {
  157. list_del(&p->entry);
  158. break;
  159. }
  160. }
  161. spin_unlock_irq(&pretimeout_lock);
  162. kfree(p);
  163. }