/* * Copyright (c) 2004 Topspin Communications. 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 * OpenIB.org 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. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ #include <linux/sched/signal.h> #include <linux/init.h> #include <linux/seq_file.h> #include <linux/uaccess.h> #include "ipoib.h" static ssize_t parent_show(struct device *d, struct device_attribute *attr, char *buf) { … } static DEVICE_ATTR_RO(parent); static bool is_child_unique(struct ipoib_dev_priv *ppriv, struct ipoib_dev_priv *priv) { … } /* * NOTE: If this function fails then the priv->dev will remain valid, however * priv will have been freed and must not be touched by caller in the error * case. * * If (ndev->reg_state == NETREG_UNINITIALIZED) then it is up to the caller to * free the net_device (just as rtnl_newlink does) otherwise the net_device * will be freed when the rtnl is unlocked. */ int __ipoib_vlan_add(struct ipoib_dev_priv *ppriv, struct ipoib_dev_priv *priv, u16 pkey, int type) { … } int ipoib_vlan_add(struct net_device *pdev, unsigned short pkey) { … } struct ipoib_vlan_delete_work { … }; /* * sysfs callbacks of a netdevice cannot obtain the rtnl lock as * unregister_netdev ultimately deletes the sysfs files while holding the rtnl * lock. This deadlocks the system. * * A callback can use rtnl_trylock to avoid the deadlock but it cannot call * unregister_netdev as that internally takes and releases the rtnl_lock. So * instead we find the netdev to unregister and then do the actual unregister * from the global work queue where we can obtain the rtnl_lock safely. */ static void ipoib_vlan_delete_task(struct work_struct *work) { … } int ipoib_vlan_delete(struct net_device *pdev, unsigned short pkey) { … }