/* * Copyright (c) 2015, Cisco Systems, Inc. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU * General Public License (GPL) Version 2, available from the file * COPYING in the main directory of this source tree, or the * BSD license below: * * Redistribution and use in source and binary forms, with or * without modification, are permitted provided that the following * conditions are met: * * - Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * - Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ /* * The code in this file prevents spurious libibverbs warnings on * stderr about devices that it doesn't recognize. * * Specifically, Cisco usNIC devices are exposed through the Linux * InfiniBand kernel interface (i.e., they show up in * /sys/class/infiniband). However, the userspace side of these * drivers is not exposed through libibverbs (i.e., there is no * libibverbs provider/plugin for usNIC). Therefore, when * ibv_get_device_list() is invoked, libibverbs cannot find a plugin * for usnic devices. This causes libibverbs to emit a spurious * warning message on stderr. * * Since libfabric can have a verbs provider, libibverbs is invoked, * triggering the sequence described above, resulting in warning * messages about usnic devices. To avoid these extra stderr * warnings, we insert a fake usnic verbs libibverbs provider that * safely squelches these warnings. * * More specifically: the userspace side of usNIC is exposed through * libfabric; we don't need libibverbs warnings about not being able * to find a usnic driver. */ #include "config.h" #include <stdio.h> #include <infiniband/verbs.h> #include <infiniband/driver.h> /***********************************************************************/ #ifndef PCI_VENDOR_ID_CISCO #define PCI_VENDOR_ID_CISCO 0x1137 #endif static struct ibv_context *fake_alloc_context(struct ibv_device *ibdev, int cmd_fd) { /* Nothing to do here */ return NULL; } static void fake_free_context(struct ibv_context *ibctx) { /* Nothing to do here */ } /* Put just enough in here to convince libibverbs that this is a valid device, and a little extra just in case someone looks at this struct in a debugger. */ static struct ibv_device fake_dev = { .ops = { .alloc_context = fake_alloc_context, .free_context = fake_free_context }, .name = "fake ibv_device inserted by libfabric:usNIC" }; static struct ibv_device *fake_driver_init(const char *uverbs_sys_path, int abi_version) { char value[8]; int vendor; /* This function should only be invoked for /sys/class/infiniband/usnic_X devices, but double check just to be absolutely sure: read the vendor ID and ensure that it is Cisco. */ if (ibv_read_sysfs_file(uverbs_sys_path, "device/vendor", value, sizeof(value)) < 0) { return NULL; } sscanf(value, "%i", &vendor); if (vendor == PCI_VENDOR_ID_CISCO) { return &fake_dev; } /* We didn't find a device that we want to support */ return NULL; } void usdf_setup_fake_ibv_provider(void) { /* Register a fake driver for "usnic_verbs" devices */ ibv_register_driver("usnic_verbs", fake_driver_init); }