Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright (C) 2020 Intel Corporation.
3 : : * All rights reserved.
4 : : */
5 : :
6 : : #include "spdk/stdinc.h"
7 : : #include "spdk/env.h"
8 : : #include "spdk/log.h"
9 : :
10 : : struct sigbus_handler {
11 : : spdk_pci_error_handler func;
12 : : void *ctx;
13 : :
14 : : TAILQ_ENTRY(sigbus_handler) tailq;
15 : : };
16 : :
17 : : static pthread_mutex_t g_sighandler_mutex = PTHREAD_MUTEX_INITIALIZER;
18 : : static TAILQ_HEAD(, sigbus_handler) g_sigbus_handler =
19 : : TAILQ_HEAD_INITIALIZER(g_sigbus_handler);
20 : :
21 : : static void
22 : 0 : sigbus_fault_sighandler(int signum, siginfo_t *info, void *ctx)
23 : : {
24 : : struct sigbus_handler *sigbus_handler;
25 : :
26 [ # # ]: 0 : pthread_mutex_lock(&g_sighandler_mutex);
27 [ # # # # : 0 : TAILQ_FOREACH(sigbus_handler, &g_sigbus_handler, tailq) {
# # # # ]
28 [ # # # # : 0 : sigbus_handler->func(info->si_addr, sigbus_handler->ctx);
# # # # #
# # # # #
# # # # #
# ]
29 : 0 : }
30 [ # # ]: 0 : pthread_mutex_unlock(&g_sighandler_mutex);
31 : 0 : }
32 : :
33 : : __attribute__((constructor)) static void
34 : 2823 : device_set_signal(void)
35 : : {
36 : 1045 : struct sigaction sa;
37 : :
38 : 2823 : sa.sa_sigaction = sigbus_fault_sighandler;
39 [ + + ]: 2823 : sigemptyset(&sa.sa_mask);
40 [ + - ]: 2823 : sa.sa_flags = SA_SIGINFO;
41 : 2823 : sigaction(SIGBUS, &sa, NULL);
42 : 2823 : }
43 : :
44 : : __attribute__((destructor)) static void
45 : 2825 : device_destroy_signal(void)
46 : : {
47 : : struct sigbus_handler *sigbus_handler, *tmp;
48 : :
49 [ + + + + : 3325 : TAILQ_FOREACH_SAFE(sigbus_handler, &g_sigbus_handler, tailq, tmp) {
+ - + - +
+ ]
50 : 500 : free(sigbus_handler);
51 : 30 : }
52 : 2825 : }
53 : :
54 : : int
55 : 500 : spdk_pci_register_error_handler(spdk_pci_error_handler sighandler, void *ctx)
56 : : {
57 : : struct sigbus_handler *sigbus_handler;
58 : :
59 [ + + ]: 500 : if (!sighandler) {
60 : 0 : SPDK_ERRLOG("Error handler is NULL\n");
61 : 0 : return -EINVAL;
62 : : }
63 : :
64 [ + + ]: 500 : pthread_mutex_lock(&g_sighandler_mutex);
65 [ - + # # : 500 : TAILQ_FOREACH(sigbus_handler, &g_sigbus_handler, tailq) {
# # # # ]
66 [ # # # # : 0 : if (sigbus_handler->func == sighandler) {
# # ]
67 [ # # ]: 0 : pthread_mutex_unlock(&g_sighandler_mutex);
68 : 0 : SPDK_ERRLOG("Error handler has been registered\n");
69 : 0 : return -EINVAL;
70 : : }
71 : 0 : }
72 [ + + ]: 500 : pthread_mutex_unlock(&g_sighandler_mutex);
73 : :
74 : 500 : sigbus_handler = calloc(1, sizeof(*sigbus_handler));
75 [ + + ]: 500 : if (!sigbus_handler) {
76 : 0 : SPDK_ERRLOG("Failed to allocate sigbus handler\n");
77 : 0 : return -ENOMEM;
78 : : }
79 : :
80 [ - + - + ]: 500 : sigbus_handler->func = sighandler;
81 [ - + - + ]: 500 : sigbus_handler->ctx = ctx;
82 : :
83 [ - + ]: 500 : pthread_mutex_lock(&g_sighandler_mutex);
84 [ - + - + : 500 : TAILQ_INSERT_TAIL(&g_sigbus_handler, sigbus_handler, tailq);
- + - + -
+ - + - +
- + - + -
+ - + -
+ ]
85 [ - + ]: 500 : pthread_mutex_unlock(&g_sighandler_mutex);
86 : :
87 : 500 : return 0;
88 : 30 : }
89 : :
90 : : void
91 : 0 : spdk_pci_unregister_error_handler(spdk_pci_error_handler sighandler)
92 : : {
93 : : struct sigbus_handler *sigbus_handler;
94 : :
95 [ # # ]: 0 : if (!sighandler) {
96 : 0 : return;
97 : : }
98 : :
99 [ # # ]: 0 : pthread_mutex_lock(&g_sighandler_mutex);
100 [ # # # # : 0 : TAILQ_FOREACH(sigbus_handler, &g_sigbus_handler, tailq) {
# # # # ]
101 [ # # # # : 0 : if (sigbus_handler->func == sighandler) {
# # ]
102 [ # # # # : 0 : TAILQ_REMOVE(&g_sigbus_handler, sigbus_handler, tailq);
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # ]
103 : 0 : free(sigbus_handler);
104 [ # # ]: 0 : pthread_mutex_unlock(&g_sighandler_mutex);
105 : 0 : return;
106 : : }
107 : 0 : }
108 [ # # ]: 0 : pthread_mutex_unlock(&g_sighandler_mutex);
109 : 0 : }
|