health.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400
  1. /*
  2. * Copyright (c) 2013-2015, Mellanox Technologies. All rights reserved.
  3. *
  4. * This software is available to you under a choice of one of two
  5. * licenses. You may choose to be licensed under the terms of the GNU
  6. * General Public License (GPL) Version 2, available from the file
  7. * COPYING in the main directory of this source tree, or the
  8. * OpenIB.org BSD license below:
  9. *
  10. * Redistribution and use in source and binary forms, with or
  11. * without modification, are permitted provided that the following
  12. * conditions are met:
  13. *
  14. * - Redistributions of source code must retain the above
  15. * copyright notice, this list of conditions and the following
  16. * disclaimer.
  17. *
  18. * - Redistributions in binary form must reproduce the above
  19. * copyright notice, this list of conditions and the following
  20. * disclaimer in the documentation and/or other materials
  21. * provided with the distribution.
  22. *
  23. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  24. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  25. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  26. * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
  27. * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  28. * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  29. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  30. * SOFTWARE.
  31. */
  32. #include <linux/kernel.h>
  33. #include <linux/module.h>
  34. #include <linux/random.h>
  35. #include <linux/vmalloc.h>
  36. #include <linux/hardirq.h>
  37. #include <linux/mlx5/driver.h>
  38. #include <linux/mlx5/cmd.h>
  39. #include "mlx5_core.h"
  40. enum {
  41. MLX5_HEALTH_POLL_INTERVAL = 2 * HZ,
  42. MAX_MISSES = 3,
  43. };
  44. enum {
  45. MLX5_HEALTH_SYNDR_FW_ERR = 0x1,
  46. MLX5_HEALTH_SYNDR_IRISC_ERR = 0x7,
  47. MLX5_HEALTH_SYNDR_HW_UNRECOVERABLE_ERR = 0x8,
  48. MLX5_HEALTH_SYNDR_CRC_ERR = 0x9,
  49. MLX5_HEALTH_SYNDR_FETCH_PCI_ERR = 0xa,
  50. MLX5_HEALTH_SYNDR_HW_FTL_ERR = 0xb,
  51. MLX5_HEALTH_SYNDR_ASYNC_EQ_OVERRUN_ERR = 0xc,
  52. MLX5_HEALTH_SYNDR_EQ_ERR = 0xd,
  53. MLX5_HEALTH_SYNDR_EQ_INV = 0xe,
  54. MLX5_HEALTH_SYNDR_FFSER_ERR = 0xf,
  55. MLX5_HEALTH_SYNDR_HIGH_TEMP = 0x10
  56. };
  57. enum {
  58. MLX5_NIC_IFC_FULL = 0,
  59. MLX5_NIC_IFC_DISABLED = 1,
  60. MLX5_NIC_IFC_NO_DRAM_NIC = 2,
  61. MLX5_NIC_IFC_INVALID = 3
  62. };
  63. enum {
  64. MLX5_DROP_NEW_HEALTH_WORK,
  65. MLX5_DROP_NEW_RECOVERY_WORK,
  66. };
  67. static u8 get_nic_state(struct mlx5_core_dev *dev)
  68. {
  69. return (ioread32be(&dev->iseg->cmdq_addr_l_sz) >> 8) & 3;
  70. }
  71. static void trigger_cmd_completions(struct mlx5_core_dev *dev)
  72. {
  73. unsigned long flags;
  74. u64 vector;
  75. /* wait for pending handlers to complete */
  76. synchronize_irq(dev->priv.msix_arr[MLX5_EQ_VEC_CMD].vector);
  77. spin_lock_irqsave(&dev->cmd.alloc_lock, flags);
  78. vector = ~dev->cmd.bitmask & ((1ul << (1 << dev->cmd.log_sz)) - 1);
  79. if (!vector)
  80. goto no_trig;
  81. vector |= MLX5_TRIGGERED_CMD_COMP;
  82. spin_unlock_irqrestore(&dev->cmd.alloc_lock, flags);
  83. mlx5_core_dbg(dev, "vector 0x%llx\n", vector);
  84. mlx5_cmd_comp_handler(dev, vector, true);
  85. return;
  86. no_trig:
  87. spin_unlock_irqrestore(&dev->cmd.alloc_lock, flags);
  88. }
  89. static int in_fatal(struct mlx5_core_dev *dev)
  90. {
  91. struct mlx5_core_health *health = &dev->priv.health;
  92. struct health_buffer __iomem *h = health->health;
  93. if (get_nic_state(dev) == MLX5_NIC_IFC_DISABLED)
  94. return 1;
  95. if (ioread32be(&h->fw_ver) == 0xffffffff)
  96. return 1;
  97. return 0;
  98. }
  99. void mlx5_enter_error_state(struct mlx5_core_dev *dev)
  100. {
  101. mutex_lock(&dev->intf_state_mutex);
  102. if (dev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR)
  103. goto unlock;
  104. mlx5_core_err(dev, "start\n");
  105. if (pci_channel_offline(dev->pdev) || in_fatal(dev)) {
  106. dev->state = MLX5_DEVICE_STATE_INTERNAL_ERROR;
  107. trigger_cmd_completions(dev);
  108. }
  109. mlx5_core_event(dev, MLX5_DEV_EVENT_SYS_ERROR, 0);
  110. mlx5_core_err(dev, "end\n");
  111. unlock:
  112. mutex_unlock(&dev->intf_state_mutex);
  113. }
  114. static void mlx5_handle_bad_state(struct mlx5_core_dev *dev)
  115. {
  116. u8 nic_interface = get_nic_state(dev);
  117. switch (nic_interface) {
  118. case MLX5_NIC_IFC_FULL:
  119. mlx5_core_warn(dev, "Expected to see disabled NIC but it is full driver\n");
  120. break;
  121. case MLX5_NIC_IFC_DISABLED:
  122. mlx5_core_warn(dev, "starting teardown\n");
  123. break;
  124. case MLX5_NIC_IFC_NO_DRAM_NIC:
  125. mlx5_core_warn(dev, "Expected to see disabled NIC but it is no dram nic\n");
  126. break;
  127. default:
  128. mlx5_core_warn(dev, "Expected to see disabled NIC but it is has invalid value %d\n",
  129. nic_interface);
  130. }
  131. mlx5_disable_device(dev);
  132. }
  133. static void health_recover(struct work_struct *work)
  134. {
  135. struct mlx5_core_health *health;
  136. struct delayed_work *dwork;
  137. struct mlx5_core_dev *dev;
  138. struct mlx5_priv *priv;
  139. u8 nic_state;
  140. dwork = container_of(work, struct delayed_work, work);
  141. health = container_of(dwork, struct mlx5_core_health, recover_work);
  142. priv = container_of(health, struct mlx5_priv, health);
  143. dev = container_of(priv, struct mlx5_core_dev, priv);
  144. nic_state = get_nic_state(dev);
  145. if (nic_state == MLX5_NIC_IFC_INVALID) {
  146. dev_err(&dev->pdev->dev, "health recovery flow aborted since the nic state is invalid\n");
  147. return;
  148. }
  149. dev_err(&dev->pdev->dev, "starting health recovery flow\n");
  150. mlx5_recover_device(dev);
  151. }
  152. /* How much time to wait until health resetting the driver (in msecs) */
  153. #define MLX5_RECOVERY_DELAY_MSECS 60000
  154. static void health_care(struct work_struct *work)
  155. {
  156. unsigned long recover_delay = msecs_to_jiffies(MLX5_RECOVERY_DELAY_MSECS);
  157. struct mlx5_core_health *health;
  158. struct mlx5_core_dev *dev;
  159. struct mlx5_priv *priv;
  160. health = container_of(work, struct mlx5_core_health, work);
  161. priv = container_of(health, struct mlx5_priv, health);
  162. dev = container_of(priv, struct mlx5_core_dev, priv);
  163. mlx5_core_warn(dev, "handling bad device here\n");
  164. mlx5_handle_bad_state(dev);
  165. spin_lock(&health->wq_lock);
  166. if (!test_bit(MLX5_DROP_NEW_RECOVERY_WORK, &health->flags))
  167. schedule_delayed_work(&health->recover_work, recover_delay);
  168. else
  169. dev_err(&dev->pdev->dev,
  170. "new health works are not permitted at this stage\n");
  171. spin_unlock(&health->wq_lock);
  172. }
  173. static const char *hsynd_str(u8 synd)
  174. {
  175. switch (synd) {
  176. case MLX5_HEALTH_SYNDR_FW_ERR:
  177. return "firmware internal error";
  178. case MLX5_HEALTH_SYNDR_IRISC_ERR:
  179. return "irisc not responding";
  180. case MLX5_HEALTH_SYNDR_HW_UNRECOVERABLE_ERR:
  181. return "unrecoverable hardware error";
  182. case MLX5_HEALTH_SYNDR_CRC_ERR:
  183. return "firmware CRC error";
  184. case MLX5_HEALTH_SYNDR_FETCH_PCI_ERR:
  185. return "ICM fetch PCI error";
  186. case MLX5_HEALTH_SYNDR_HW_FTL_ERR:
  187. return "HW fatal error\n";
  188. case MLX5_HEALTH_SYNDR_ASYNC_EQ_OVERRUN_ERR:
  189. return "async EQ buffer overrun";
  190. case MLX5_HEALTH_SYNDR_EQ_ERR:
  191. return "EQ error";
  192. case MLX5_HEALTH_SYNDR_EQ_INV:
  193. return "Invalid EQ referenced";
  194. case MLX5_HEALTH_SYNDR_FFSER_ERR:
  195. return "FFSER error";
  196. case MLX5_HEALTH_SYNDR_HIGH_TEMP:
  197. return "High temperature";
  198. default:
  199. return "unrecognized error";
  200. }
  201. }
  202. static u16 get_maj(u32 fw)
  203. {
  204. return fw >> 28;
  205. }
  206. static u16 get_min(u32 fw)
  207. {
  208. return fw >> 16 & 0xfff;
  209. }
  210. static u16 get_sub(u32 fw)
  211. {
  212. return fw & 0xffff;
  213. }
  214. static void print_health_info(struct mlx5_core_dev *dev)
  215. {
  216. struct mlx5_core_health *health = &dev->priv.health;
  217. struct health_buffer __iomem *h = health->health;
  218. char fw_str[18];
  219. u32 fw;
  220. int i;
  221. /* If the syndrom is 0, the device is OK and no need to print buffer */
  222. if (!ioread8(&h->synd))
  223. return;
  224. for (i = 0; i < ARRAY_SIZE(h->assert_var); i++)
  225. dev_err(&dev->pdev->dev, "assert_var[%d] 0x%08x\n", i, ioread32be(h->assert_var + i));
  226. dev_err(&dev->pdev->dev, "assert_exit_ptr 0x%08x\n", ioread32be(&h->assert_exit_ptr));
  227. dev_err(&dev->pdev->dev, "assert_callra 0x%08x\n", ioread32be(&h->assert_callra));
  228. fw = ioread32be(&h->fw_ver);
  229. sprintf(fw_str, "%d.%d.%d", get_maj(fw), get_min(fw), get_sub(fw));
  230. dev_err(&dev->pdev->dev, "fw_ver %s\n", fw_str);
  231. dev_err(&dev->pdev->dev, "hw_id 0x%08x\n", ioread32be(&h->hw_id));
  232. dev_err(&dev->pdev->dev, "irisc_index %d\n", ioread8(&h->irisc_index));
  233. dev_err(&dev->pdev->dev, "synd 0x%x: %s\n", ioread8(&h->synd), hsynd_str(ioread8(&h->synd)));
  234. dev_err(&dev->pdev->dev, "ext_synd 0x%04x\n", ioread16be(&h->ext_synd));
  235. }
  236. static unsigned long get_next_poll_jiffies(void)
  237. {
  238. unsigned long next;
  239. get_random_bytes(&next, sizeof(next));
  240. next %= HZ;
  241. next += jiffies + MLX5_HEALTH_POLL_INTERVAL;
  242. return next;
  243. }
  244. static void poll_health(unsigned long data)
  245. {
  246. struct mlx5_core_dev *dev = (struct mlx5_core_dev *)data;
  247. struct mlx5_core_health *health = &dev->priv.health;
  248. u32 count;
  249. if (dev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR) {
  250. mod_timer(&health->timer, get_next_poll_jiffies());
  251. return;
  252. }
  253. count = ioread32be(health->health_counter);
  254. if (count == health->prev)
  255. ++health->miss_counter;
  256. else
  257. health->miss_counter = 0;
  258. health->prev = count;
  259. if (health->miss_counter == MAX_MISSES) {
  260. dev_err(&dev->pdev->dev, "device's health compromised - reached miss count\n");
  261. print_health_info(dev);
  262. } else {
  263. mod_timer(&health->timer, get_next_poll_jiffies());
  264. }
  265. if (in_fatal(dev) && !health->sick) {
  266. health->sick = true;
  267. print_health_info(dev);
  268. spin_lock(&health->wq_lock);
  269. if (!test_bit(MLX5_DROP_NEW_HEALTH_WORK, &health->flags))
  270. queue_work(health->wq, &health->work);
  271. else
  272. dev_err(&dev->pdev->dev,
  273. "new health works are not permitted at this stage\n");
  274. spin_unlock(&health->wq_lock);
  275. }
  276. }
  277. void mlx5_start_health_poll(struct mlx5_core_dev *dev)
  278. {
  279. struct mlx5_core_health *health = &dev->priv.health;
  280. init_timer(&health->timer);
  281. health->sick = 0;
  282. clear_bit(MLX5_DROP_NEW_HEALTH_WORK, &health->flags);
  283. clear_bit(MLX5_DROP_NEW_RECOVERY_WORK, &health->flags);
  284. health->health = &dev->iseg->health;
  285. health->health_counter = &dev->iseg->health_counter;
  286. health->timer.data = (unsigned long)dev;
  287. health->timer.function = poll_health;
  288. health->timer.expires = round_jiffies(jiffies + MLX5_HEALTH_POLL_INTERVAL);
  289. add_timer(&health->timer);
  290. }
  291. void mlx5_stop_health_poll(struct mlx5_core_dev *dev)
  292. {
  293. struct mlx5_core_health *health = &dev->priv.health;
  294. del_timer_sync(&health->timer);
  295. }
  296. void mlx5_drain_health_wq(struct mlx5_core_dev *dev)
  297. {
  298. struct mlx5_core_health *health = &dev->priv.health;
  299. spin_lock(&health->wq_lock);
  300. set_bit(MLX5_DROP_NEW_HEALTH_WORK, &health->flags);
  301. set_bit(MLX5_DROP_NEW_RECOVERY_WORK, &health->flags);
  302. spin_unlock(&health->wq_lock);
  303. cancel_delayed_work_sync(&health->recover_work);
  304. cancel_work_sync(&health->work);
  305. }
  306. void mlx5_drain_health_recovery(struct mlx5_core_dev *dev)
  307. {
  308. struct mlx5_core_health *health = &dev->priv.health;
  309. spin_lock(&health->wq_lock);
  310. set_bit(MLX5_DROP_NEW_RECOVERY_WORK, &health->flags);
  311. spin_unlock(&health->wq_lock);
  312. cancel_delayed_work_sync(&dev->priv.health.recover_work);
  313. }
  314. void mlx5_health_cleanup(struct mlx5_core_dev *dev)
  315. {
  316. struct mlx5_core_health *health = &dev->priv.health;
  317. destroy_workqueue(health->wq);
  318. }
  319. int mlx5_health_init(struct mlx5_core_dev *dev)
  320. {
  321. struct mlx5_core_health *health;
  322. char *name;
  323. health = &dev->priv.health;
  324. name = kmalloc(64, GFP_KERNEL);
  325. if (!name)
  326. return -ENOMEM;
  327. strcpy(name, "mlx5_health");
  328. strcat(name, dev_name(&dev->pdev->dev));
  329. health->wq = create_singlethread_workqueue(name);
  330. kfree(name);
  331. if (!health->wq)
  332. return -ENOMEM;
  333. spin_lock_init(&health->wq_lock);
  334. INIT_WORK(&health->work, health_care);
  335. INIT_DELAYED_WORK(&health->recover_work, health_recover);
  336. return 0;
  337. }