LCOV - code coverage report
Current view: top level - lib/eal/linux - eal_dev.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 0 195 0.0 %
Date: 2026-09-22 18:37:49 Functions: 0 13 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 112 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright(c) 2018 Intel Corporation
       3                 :            :  */
       4                 :            : 
       5                 :            : #include <stdlib.h>
       6                 :            : #include <string.h>
       7                 :            : #include <unistd.h>
       8                 :            : #include <signal.h>
       9                 :            : #include <sys/socket.h>
      10                 :            : #include <linux/netlink.h>
      11                 :            : 
      12                 :            : #include <rte_string_fns.h>
      13                 :            : #include <rte_log.h>
      14                 :            : #include <rte_dev.h>
      15                 :            : #include <rte_interrupts.h>
      16                 :            : #include <rte_alarm.h>
      17                 :            : #include <bus_driver.h>
      18                 :            : #include <rte_spinlock.h>
      19                 :            : #include <rte_errno.h>
      20                 :            : 
      21                 :            : #include <eal_export.h>
      22                 :            : #include "eal_private.h"
      23                 :            : 
      24                 :            : static struct rte_intr_handle *intr_handle;
      25                 :            : static rte_rwlock_t monitor_lock = RTE_RWLOCK_INITIALIZER;
      26                 :            : static uint32_t monitor_refcount;
      27                 :            : static bool hotplug_handle;
      28                 :            : 
      29                 :            : #define EAL_UEV_MSG_LEN 4096
      30                 :            : #define EAL_UEV_MSG_ELEM_LEN 128
      31                 :            : 
      32                 :            : /* Listen only to messages from kernel (not libudev) */
      33                 :            : #define EAL_UEV_GROUP_KERNEL 1
      34                 :            : 
      35                 :            : /* Large uevent buffer */
      36                 :            : #define EAL_UEV_MSG_RCVBUF (4 * 1024 * 1024)
      37                 :            : 
      38                 :            : /*
      39                 :            :  * spinlock for device hot-unplug failure handling. If it try to access bus or
      40                 :            :  * device, such as handle sigbus on bus or handle memory failure for device
      41                 :            :  * just need to use this lock. It could protect the bus and the device to avoid
      42                 :            :  * race condition.
      43                 :            :  */
      44                 :            : static rte_spinlock_t failure_handle_lock = RTE_SPINLOCK_INITIALIZER;
      45                 :            : 
      46                 :            : static struct sigaction sigbus_action_old;
      47                 :            : 
      48                 :            : static int sigbus_need_recover;
      49                 :            : 
      50                 :            : static void dev_uev_handler(__rte_unused void *param);
      51                 :            : 
      52                 :            : /* identify the system layer which reports this event. */
      53                 :            : enum eal_dev_event_subsystem {
      54                 :            :         EAL_DEV_EVENT_SUBSYSTEM_PCI, /* PCI bus device event */
      55                 :            :         EAL_DEV_EVENT_SUBSYSTEM_UIO, /* UIO driver device event */
      56                 :            :         EAL_DEV_EVENT_SUBSYSTEM_VFIO, /* VFIO driver device event */
      57                 :            :         EAL_DEV_EVENT_SUBSYSTEM_MAX
      58                 :            : };
      59                 :            : 
      60                 :            : static void
      61                 :            : sigbus_action_recover(void)
      62                 :            : {
      63                 :          0 :         if (sigbus_need_recover) {
      64                 :          0 :                 sigaction(SIGBUS, &sigbus_action_old, NULL);
      65                 :          0 :                 sigbus_need_recover = 0;
      66                 :            :         }
      67                 :            : }
      68                 :            : 
      69                 :          0 : static void sigbus_handler(int signum, siginfo_t *info,
      70                 :            :                                 void *ctx __rte_unused)
      71                 :            : {
      72                 :            :         int ret;
      73                 :            : 
      74                 :          0 :         EAL_LOG(DEBUG, "Thread catch SIGBUS, fault address:%p",
      75                 :            :                 info->si_addr);
      76                 :            : 
      77                 :            :         rte_spinlock_lock(&failure_handle_lock);
      78                 :          0 :         ret = rte_bus_sigbus_handler(info->si_addr);
      79                 :            :         rte_spinlock_unlock(&failure_handle_lock);
      80         [ #  # ]:          0 :         if (ret == -1) {
      81                 :          0 :                 rte_exit(EXIT_FAILURE,
      82                 :            :                          "Failed to handle SIGBUS for hot-unplug, "
      83                 :            :                          "(rte_errno: %s)!", strerror(rte_errno));
      84         [ #  # ]:          0 :         } else if (ret == 1) {
      85         [ #  # ]:          0 :                 if (sigbus_action_old.sa_flags == SA_SIGINFO
      86         [ #  # ]:          0 :                     && sigbus_action_old.sa_sigaction) {
      87                 :          0 :                         (*(sigbus_action_old.sa_sigaction))(signum,
      88                 :            :                                                             info, ctx);
      89         [ #  # ]:          0 :                 } else if (sigbus_action_old.sa_flags != SA_SIGINFO
      90         [ #  # ]:          0 :                            && sigbus_action_old.sa_handler) {
      91                 :          0 :                         (*(sigbus_action_old.sa_handler))(signum);
      92                 :            :                 } else {
      93                 :          0 :                         rte_exit(EXIT_FAILURE,
      94                 :            :                                  "Failed to handle generic SIGBUS!");
      95                 :            :                 }
      96                 :            :         }
      97                 :            : 
      98                 :          0 :         EAL_LOG(DEBUG, "Success to handle SIGBUS for hot-unplug!");
      99                 :          0 : }
     100                 :            : 
     101                 :          0 : static int cmp_dev_name(const struct rte_device *dev,
     102                 :            :         const void *_name)
     103                 :            : {
     104                 :            :         const char *name = _name;
     105                 :            : 
     106                 :          0 :         return strcmp(dev->name, name);
     107                 :            : }
     108                 :            : 
     109                 :            : /*
     110                 :            :  * To avoid losing uevents increase the netlink receive buffer size,
     111                 :            :  * and override the kernel clamp value if necessary.
     112                 :            :  */
     113                 :            : static int
     114                 :          0 : dev_uev_set_rcvbuf(int fd, int n)
     115                 :            : {
     116                 :            :         int ret, val;
     117                 :          0 :         socklen_t len = sizeof(val);
     118                 :            : 
     119                 :          0 :         ret = setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &n, sizeof(n));
     120         [ #  # ]:          0 :         if (ret < 0)
     121                 :            :                 return ret;
     122                 :            : 
     123                 :            :         /* kernel may have clamped our request */
     124                 :          0 :         ret = getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &val, &len);
     125   [ #  #  #  #  :          0 :         if (ret >= 0 && len == sizeof(val) && val == n * 2)
                   #  # ]
     126                 :            :                 return 0; /* request worked */
     127                 :            : 
     128                 :            :         /* try again to override kernel restriction */
     129                 :          0 :         return setsockopt(fd, SOL_SOCKET, SO_RCVBUFFORCE, &n, sizeof(n));
     130                 :            : }
     131                 :            : 
     132                 :            : static int
     133                 :          0 : dev_uev_socket_fd_create(void)
     134                 :            : {
     135                 :            :         struct sockaddr_nl addr;
     136                 :            :         int ret, fd;
     137                 :            : 
     138                 :          0 :         fd = socket(PF_NETLINK, SOCK_RAW | SOCK_CLOEXEC | SOCK_NONBLOCK,
     139                 :            :                     NETLINK_KOBJECT_UEVENT);
     140         [ #  # ]:          0 :         if (fd < 0) {
     141                 :          0 :                 EAL_LOG(ERR, "create uevent fd failed.");
     142                 :          0 :                 return -1;
     143                 :            :         }
     144                 :            : 
     145                 :            :         memset(&addr, 0, sizeof(addr));
     146                 :          0 :         addr.nl_family = AF_NETLINK;
     147                 :            :         addr.nl_pid = 0;
     148                 :          0 :         addr.nl_groups = EAL_UEV_GROUP_KERNEL;
     149                 :            : 
     150                 :          0 :         ret = bind(fd, (struct sockaddr *) &addr, sizeof(addr));
     151         [ #  # ]:          0 :         if (ret < 0) {
     152                 :          0 :                 EAL_LOG(ERR, "Failed to bind uevent socket.");
     153                 :          0 :                 goto err;
     154                 :            :         }
     155                 :            : 
     156         [ #  # ]:          0 :         if (dev_uev_set_rcvbuf(fd, EAL_UEV_MSG_RCVBUF) < 0)
     157                 :          0 :                 EAL_LOG(NOTICE, "Failed to set rcvbuf.");
     158                 :            : 
     159         [ #  # ]:          0 :         if (rte_intr_fd_set(intr_handle, fd))
     160                 :          0 :                 goto err;
     161                 :            : 
     162                 :            :         return 0;
     163                 :          0 : err:
     164                 :          0 :         close(fd);
     165                 :          0 :         return ret;
     166                 :            : }
     167                 :            : 
     168                 :            : struct rte_dev_event {
     169                 :            :         enum rte_dev_event_type type;   /**< device event type */
     170                 :            :         int subsystem;                  /**< subsystem id */
     171                 :            :         char *devname;                  /**< device name */
     172                 :            : };
     173                 :            : 
     174                 :            : static int
     175                 :          0 : dev_uev_parse(const char *buf, struct rte_dev_event *event, int length)
     176                 :            : {
     177                 :            :         char action[EAL_UEV_MSG_ELEM_LEN];
     178                 :            :         char subsystem[EAL_UEV_MSG_ELEM_LEN];
     179                 :            :         char pci_slot_name[EAL_UEV_MSG_ELEM_LEN];
     180                 :            :         int i = 0;
     181                 :            : 
     182                 :            :         memset(action, 0, EAL_UEV_MSG_ELEM_LEN);
     183                 :            :         memset(subsystem, 0, EAL_UEV_MSG_ELEM_LEN);
     184                 :            :         memset(pci_slot_name, 0, EAL_UEV_MSG_ELEM_LEN);
     185                 :            : 
     186         [ #  # ]:          0 :         while (i < length) {
     187         [ #  # ]:          0 :                 for (; i < length; i++) {
     188         [ #  # ]:          0 :                         if (*buf)
     189                 :            :                                 break;
     190                 :          0 :                         buf++;
     191                 :            :                 }
     192         [ #  # ]:          0 :                 if (i >= length)
     193                 :            :                         break;
     194                 :            : 
     195         [ #  # ]:          0 :                 if (!strncmp(buf, "ACTION=", 7)) {
     196                 :          0 :                         buf += 7;
     197                 :          0 :                         i += 7;
     198                 :            :                         strlcpy(action, buf, sizeof(action));
     199         [ #  # ]:          0 :                 } else if (!strncmp(buf, "SUBSYSTEM=", 10)) {
     200                 :          0 :                         buf += 10;
     201                 :          0 :                         i += 10;
     202                 :            :                         strlcpy(subsystem, buf, sizeof(subsystem));
     203         [ #  # ]:          0 :                 } else if (!strncmp(buf, "PCI_SLOT_NAME=", 14)) {
     204                 :          0 :                         buf += 14;
     205                 :          0 :                         i += 14;
     206                 :            :                         strlcpy(pci_slot_name, buf, sizeof(subsystem));
     207                 :          0 :                         event->devname = strdup(pci_slot_name);
     208         [ #  # ]:          0 :                         if (event->devname == NULL)
     209                 :            :                                 return -1;
     210                 :            :                 }
     211         [ #  # ]:          0 :                 for (; i < length; i++) {
     212         [ #  # ]:          0 :                         if (*buf == '\0')
     213                 :            :                                 break;
     214                 :          0 :                         buf++;
     215                 :            :                 }
     216                 :            :         }
     217                 :            : 
     218                 :            :         /* parse the subsystem layer */
     219         [ #  # ]:          0 :         if (!strncmp(subsystem, "uio", 3))
     220                 :          0 :                 event->subsystem = EAL_DEV_EVENT_SUBSYSTEM_UIO;
     221         [ #  # ]:          0 :         else if (!strncmp(subsystem, "pci", 3))
     222                 :          0 :                 event->subsystem = EAL_DEV_EVENT_SUBSYSTEM_PCI;
     223         [ #  # ]:          0 :         else if (!strncmp(subsystem, "vfio", 4))
     224                 :          0 :                 event->subsystem = EAL_DEV_EVENT_SUBSYSTEM_VFIO;
     225                 :            :         else
     226                 :          0 :                 goto err;
     227                 :            : 
     228                 :            :         /* parse the action type */
     229         [ #  # ]:          0 :         if (!strncmp(action, "add", 3))
     230                 :          0 :                 event->type = RTE_DEV_EVENT_ADD;
     231         [ #  # ]:          0 :         else if (!strncmp(action, "remove", 6))
     232                 :          0 :                 event->type = RTE_DEV_EVENT_REMOVE;
     233                 :            :         else
     234                 :          0 :                 goto err;
     235                 :            :         return 0;
     236                 :          0 : err:
     237                 :          0 :         free(event->devname);
     238                 :          0 :         return -1;
     239                 :            : }
     240                 :            : 
     241                 :            : static void
     242                 :          0 : dev_delayed_unregister(void *param)
     243                 :            : {
     244                 :          0 :         rte_intr_callback_unregister(intr_handle, dev_uev_handler, param);
     245         [ #  # ]:          0 :         if (rte_intr_fd_get(intr_handle) >= 0) {
     246                 :          0 :                 close(rte_intr_fd_get(intr_handle));
     247                 :          0 :                 rte_intr_fd_set(intr_handle, -1);
     248                 :            :         }
     249                 :          0 : }
     250                 :            : 
     251                 :            : static void
     252                 :          0 : dev_uev_handler(__rte_unused void *param)
     253                 :            : {
     254                 :            :         struct rte_dev_event uevent;
     255                 :            :         int ret;
     256                 :            :         char buf[EAL_UEV_MSG_LEN + 1];
     257                 :            :         struct rte_bus *bus;
     258                 :            :         struct rte_device *dev;
     259                 :            :         const char *busname = "";
     260                 :            : 
     261                 :            :         memset(&uevent, 0, sizeof(struct rte_dev_event));
     262                 :            :         memset(buf, 0, EAL_UEV_MSG_LEN + 1);
     263                 :            : 
     264         [ #  # ]:          0 :         if (rte_intr_fd_get(intr_handle) < 0)
     265                 :          0 :                 return;
     266                 :            : 
     267                 :          0 :         ret = recv(rte_intr_fd_get(intr_handle), buf, EAL_UEV_MSG_LEN,
     268                 :            :                    MSG_DONTWAIT);
     269         [ #  # ]:          0 :         if (ret < 0) {
     270                 :            :                 /* transient error */
     271         [ #  # ]:          0 :                 if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR)
     272                 :            :                         return;
     273                 :            : 
     274                 :            :                 /* kernel netlink messages lost */
     275         [ #  # ]:          0 :                 if (errno == ENOBUFS) {
     276                 :          0 :                         EAL_LOG(NOTICE, "kernel receive buffer overrun");
     277                 :          0 :                         return;
     278                 :            :                 }
     279                 :            : 
     280                 :          0 :                 EAL_LOG(ERR, "unexpected error on uevent recv: %s",
     281                 :            :                         strerror(errno));
     282                 :            : 
     283                 :          0 :                 rte_eal_alarm_set(1, dev_delayed_unregister, NULL);
     284                 :          0 :                 return;
     285                 :            :         }
     286                 :            : 
     287                 :          0 :         ret = dev_uev_parse(buf, &uevent, EAL_UEV_MSG_LEN);
     288         [ #  # ]:          0 :         if (ret < 0) {
     289                 :          0 :                 EAL_LOG(DEBUG, "Ignoring uevent '%s'", buf);
     290                 :          0 :                 return;
     291                 :            :         }
     292                 :            : 
     293                 :          0 :         EAL_LOG(DEBUG, "receive uevent(name:%s, type:%d, subsystem:%d)",
     294                 :            :                 uevent.devname, uevent.type, uevent.subsystem);
     295                 :            : 
     296         [ #  # ]:          0 :         switch (uevent.subsystem) {
     297                 :          0 :         case EAL_DEV_EVENT_SUBSYSTEM_PCI:
     298                 :            :         case EAL_DEV_EVENT_SUBSYSTEM_UIO:
     299                 :            :                 busname = "pci";
     300                 :          0 :                 break;
     301                 :            :         default:
     302                 :            :                 break;
     303                 :            :         }
     304                 :            : 
     305         [ #  # ]:          0 :         if (uevent.devname) {
     306   [ #  #  #  # ]:          0 :                 if (uevent.type == RTE_DEV_EVENT_REMOVE && hotplug_handle) {
     307                 :            :                         rte_spinlock_lock(&failure_handle_lock);
     308                 :          0 :                         bus = rte_bus_find_by_name(busname);
     309         [ #  # ]:          0 :                         if (bus == NULL) {
     310                 :          0 :                                 EAL_LOG(ERR, "Cannot find bus (%s)",
     311                 :            :                                         busname);
     312                 :          0 :                                 goto failure_handle_err;
     313                 :            :                         }
     314                 :            : 
     315                 :          0 :                         dev = bus->find_device(bus, NULL, cmp_dev_name, uevent.devname);
     316         [ #  # ]:          0 :                         if (dev == NULL) {
     317                 :          0 :                                 EAL_LOG(ERR, "Cannot find device (%s) on "
     318                 :            :                                         "bus (%s)", uevent.devname, busname);
     319                 :          0 :                                 goto failure_handle_err;
     320                 :            :                         }
     321                 :            : 
     322                 :          0 :                         ret = bus->hot_unplug_handler(dev);
     323         [ #  # ]:          0 :                         if (ret) {
     324                 :          0 :                                 EAL_LOG(ERR, "Can not handle hot-unplug "
     325                 :            :                                         "for device (%s)", dev->name);
     326                 :            :                         }
     327                 :            :                         rte_spinlock_unlock(&failure_handle_lock);
     328                 :            :                 }
     329                 :          0 :                 rte_dev_event_callback_process(uevent.devname, uevent.type);
     330                 :          0 :                 free(uevent.devname);
     331                 :            :         }
     332                 :            : 
     333                 :            :         return;
     334                 :            : 
     335                 :          0 : failure_handle_err:
     336                 :            :         rte_spinlock_unlock(&failure_handle_lock);
     337                 :          0 :         free(uevent.devname);
     338                 :            : }
     339                 :            : 
     340                 :            : RTE_EXPORT_SYMBOL(rte_dev_event_monitor_start)
     341                 :            : int
     342                 :          0 : rte_dev_event_monitor_start(void)
     343                 :            : {
     344                 :            :         int ret = 0;
     345                 :            : 
     346                 :          0 :         rte_rwlock_write_lock(&monitor_lock);
     347                 :            : 
     348         [ #  # ]:          0 :         if (monitor_refcount) {
     349                 :          0 :                 monitor_refcount++;
     350                 :          0 :                 goto exit;
     351                 :            :         }
     352                 :            : 
     353                 :          0 :         intr_handle = rte_intr_instance_alloc(RTE_INTR_INSTANCE_F_PRIVATE);
     354         [ #  # ]:          0 :         if (intr_handle == NULL) {
     355                 :          0 :                 EAL_LOG(ERR, "Fail to allocate intr_handle");
     356                 :          0 :                 goto exit;
     357                 :            :         }
     358                 :            : 
     359                 :          0 :         ret = rte_intr_type_set(intr_handle, RTE_INTR_HANDLE_DEV_EVENT);
     360         [ #  # ]:          0 :         if (ret)
     361                 :          0 :                 goto exit;
     362                 :            : 
     363                 :          0 :         ret = rte_intr_fd_set(intr_handle, -1);
     364         [ #  # ]:          0 :         if (ret)
     365                 :          0 :                 goto exit;
     366                 :            : 
     367                 :          0 :         ret = dev_uev_socket_fd_create();
     368         [ #  # ]:          0 :         if (ret) {
     369                 :          0 :                 EAL_LOG(ERR, "error create device event fd.");
     370                 :          0 :                 goto exit;
     371                 :            :         }
     372                 :            : 
     373                 :          0 :         ret = rte_intr_callback_register(intr_handle, dev_uev_handler, NULL);
     374                 :            : 
     375         [ #  # ]:          0 :         if (ret) {
     376                 :          0 :                 close(rte_intr_fd_get(intr_handle));
     377                 :          0 :                 goto exit;
     378                 :            :         }
     379                 :            : 
     380                 :          0 :         monitor_refcount++;
     381                 :            : 
     382                 :          0 : exit:
     383         [ #  # ]:          0 :         if (ret) {
     384                 :          0 :                 rte_intr_instance_free(intr_handle);
     385                 :          0 :                 intr_handle = NULL;
     386                 :            :         }
     387                 :            :         rte_rwlock_write_unlock(&monitor_lock);
     388                 :          0 :         return ret;
     389                 :            : }
     390                 :            : 
     391                 :            : RTE_EXPORT_SYMBOL(rte_dev_event_monitor_stop)
     392                 :            : int
     393                 :          0 : rte_dev_event_monitor_stop(void)
     394                 :            : {
     395                 :            :         int ret = 0;
     396                 :            : 
     397                 :          0 :         rte_rwlock_write_lock(&monitor_lock);
     398                 :            : 
     399         [ #  # ]:          0 :         if (!monitor_refcount) {
     400                 :          0 :                 EAL_LOG(ERR, "device event monitor already stopped");
     401                 :          0 :                 goto exit;
     402                 :            :         }
     403                 :            : 
     404         [ #  # ]:          0 :         if (monitor_refcount > 1) {
     405                 :          0 :                 monitor_refcount--;
     406                 :          0 :                 goto exit;
     407                 :            :         }
     408                 :            : 
     409                 :          0 :         ret = rte_intr_callback_unregister(intr_handle, dev_uev_handler,
     410                 :            :                                            (void *)-1);
     411         [ #  # ]:          0 :         if (ret < 0) {
     412                 :          0 :                 EAL_LOG(ERR, "fail to unregister uevent callback.");
     413                 :          0 :                 goto exit;
     414                 :            :         }
     415                 :            : 
     416                 :          0 :         close(rte_intr_fd_get(intr_handle));
     417                 :          0 :         rte_intr_instance_free(intr_handle);
     418                 :          0 :         intr_handle = NULL;
     419                 :            :         ret = 0;
     420                 :            : 
     421                 :          0 :         monitor_refcount--;
     422                 :            : 
     423                 :          0 : exit:
     424                 :            :         rte_rwlock_write_unlock(&monitor_lock);
     425                 :            : 
     426                 :          0 :         return ret;
     427                 :            : }
     428                 :            : 
     429                 :            : static int
     430                 :          0 : dev_sigbus_handler_register(void)
     431                 :            : {
     432                 :            :         sigset_t mask;
     433                 :            :         struct sigaction action;
     434                 :            : 
     435                 :          0 :         rte_errno = 0;
     436                 :            : 
     437         [ #  # ]:          0 :         if (sigbus_need_recover)
     438                 :            :                 return 0;
     439                 :            : 
     440                 :          0 :         sigemptyset(&mask);
     441                 :          0 :         sigaddset(&mask, SIGBUS);
     442                 :          0 :         action.sa_flags = SA_SIGINFO;
     443                 :          0 :         action.sa_mask = mask;
     444                 :          0 :         action.sa_sigaction = sigbus_handler;
     445                 :          0 :         sigbus_need_recover = !sigaction(SIGBUS, &action, &sigbus_action_old);
     446                 :            : 
     447                 :          0 :         return rte_errno;
     448                 :            : }
     449                 :            : 
     450                 :            : static int
     451                 :          0 : dev_sigbus_handler_unregister(void)
     452                 :            : {
     453         [ #  # ]:          0 :         rte_errno = 0;
     454                 :            : 
     455                 :            :         sigbus_action_recover();
     456                 :            : 
     457                 :          0 :         return rte_errno;
     458                 :            : }
     459                 :            : 
     460                 :            : RTE_EXPORT_SYMBOL(rte_dev_hotplug_handle_enable)
     461                 :            : int
     462                 :          0 : rte_dev_hotplug_handle_enable(void)
     463                 :            : {
     464                 :            :         int ret = 0;
     465                 :            : 
     466                 :          0 :         ret = dev_sigbus_handler_register();
     467         [ #  # ]:          0 :         if (ret < 0)
     468                 :          0 :                 EAL_LOG(ERR,
     469                 :            :                         "fail to register sigbus handler for devices.");
     470                 :            : 
     471                 :          0 :         hotplug_handle = true;
     472                 :            : 
     473                 :          0 :         return ret;
     474                 :            : }
     475                 :            : 
     476                 :            : RTE_EXPORT_SYMBOL(rte_dev_hotplug_handle_disable)
     477                 :            : int
     478                 :          0 : rte_dev_hotplug_handle_disable(void)
     479                 :            : {
     480                 :            :         int ret = 0;
     481                 :            : 
     482                 :          0 :         ret = dev_sigbus_handler_unregister();
     483         [ #  # ]:          0 :         if (ret < 0)
     484                 :          0 :                 EAL_LOG(ERR,
     485                 :            :                         "fail to unregister sigbus handler for devices.");
     486                 :            : 
     487                 :          0 :         hotplug_handle = false;
     488                 :            : 
     489                 :          0 :         return ret;
     490                 :            : }

Generated by: LCOV version 1.14