svn commit: r216905 - in projects/ofed/head/sys/ofed:
drivers/infiniband/core drivers/infiniband/hw/mlx4 include/linux
Jeff Roberson
jeff at FreeBSD.org
Mon Jan 3 03:34:59 UTC 2011
Author: jeff
Date: Mon Jan 3 03:34:59 2011
New Revision: 216905
URL: http://svn.freebsd.org/changeset/base/216905
Log:
- Add netdevice notifiers and re-enable their appropriate handlers in
the core stack and drivers. These are network events for
adding and removing network devices along with link state changes, etc.
Sponsored by: Isilon Systems, iX Systems, and Panasas.
Modified:
projects/ofed/head/sys/ofed/drivers/infiniband/core/cma.c
projects/ofed/head/sys/ofed/drivers/infiniband/hw/mlx4/main.c
projects/ofed/head/sys/ofed/include/linux/netdevice.h
projects/ofed/head/sys/ofed/include/linux/notifier.h
Modified: projects/ofed/head/sys/ofed/drivers/infiniband/core/cma.c
==============================================================================
--- projects/ofed/head/sys/ofed/drivers/infiniband/core/cma.c Mon Jan 3 03:08:08 2011 (r216904)
+++ projects/ofed/head/sys/ofed/drivers/infiniband/core/cma.c Mon Jan 3 03:34:59 2011 (r216905)
@@ -1681,8 +1681,6 @@ out:
kfree(work);
}
-#ifdef __linux__
-/* XXX I need to add an EVENTHANDLER based system for handling these events. */
static void cma_ndev_work_handler(struct work_struct *_work)
{
struct cma_ndev_work *work = container_of(_work, struct cma_ndev_work, work);
@@ -1706,7 +1704,6 @@ out:
rdma_destroy_id(&id_priv->id);
kfree(work);
}
-#endif
static int cma_resolve_ib_route(struct rdma_id_private *id_priv, int timeout_ms)
{
@@ -3183,7 +3180,6 @@ void rdma_leave_multicast(struct rdma_cm
}
EXPORT_SYMBOL(rdma_leave_multicast);
-#ifdef __linux__
static int cma_netdev_change(struct net_device *ndev, struct rdma_id_private *id_priv)
{
struct rdma_dev_addr *dev_addr;
@@ -3191,10 +3187,17 @@ static int cma_netdev_change(struct net_
dev_addr = &id_priv->id.route.addr.dev_addr;
+#ifdef __linux__
if ((dev_addr->bound_dev_if == ndev->ifindex) &&
memcmp(dev_addr->src_dev_addr, ndev->dev_addr, ndev->addr_len)) {
printk(KERN_INFO "RDMA CM addr change for ndev %s used by id %p\n",
ndev->name, &id_priv->id);
+#else
+ if ((dev_addr->bound_dev_if == ndev->if_index) &&
+ memcmp(dev_addr->src_dev_addr, IF_LLADDR(ndev), ndev->if_addrlen)) {
+ printk(KERN_INFO "RDMA CM addr change for ndev %s used by id %p\n",
+ ndev->if_xname, &id_priv->id);
+#endif
work = kzalloc(sizeof *work, GFP_KERNEL);
if (!work)
return -ENOMEM;
@@ -3217,6 +3220,7 @@ static int cma_netdev_callback(struct no
struct rdma_id_private *id_priv;
int ret = NOTIFY_DONE;
+#ifdef __linux__
if (dev_net(ndev) != &init_net)
return NOTIFY_DONE;
@@ -3225,6 +3229,10 @@ static int cma_netdev_callback(struct no
if (!(ndev->flags & IFF_MASTER) || !(ndev->priv_flags & IFF_BONDING))
return NOTIFY_DONE;
+#else
+ if (event != NETDEV_DOWN && event != NETDEV_UNREGISTER)
+ return NOTIFY_DONE;
+#endif
mutex_lock(&lock);
list_for_each_entry(cma_dev, &dev_list, list)
@@ -3242,7 +3250,6 @@ out:
static struct notifier_block cma_nb = {
.notifier_call = cma_netdev_callback
};
-#endif
static void cma_add_one(struct ib_device *device)
{
@@ -3352,9 +3359,7 @@ static int cma_init(void)
ib_sa_register_client(&sa_client);
rdma_addr_register_client(&addr_client);
-#ifdef __linux__
register_netdevice_notifier(&cma_nb);
-#endif
ret = ib_register_client(&cma_client);
if (ret)
@@ -3362,9 +3367,7 @@ static int cma_init(void)
return 0;
err:
-#ifdef __linux__
unregister_netdevice_notifier(&cma_nb);
-#endif
rdma_addr_unregister_client(&addr_client);
ib_sa_unregister_client(&sa_client);
destroy_workqueue(cma_wq);
@@ -3374,9 +3377,7 @@ err:
static void cma_cleanup(void)
{
ib_unregister_client(&cma_client);
-#ifdef __linux__
unregister_netdevice_notifier(&cma_nb);
-#endif
rdma_addr_unregister_client(&addr_client);
ib_sa_unregister_client(&sa_client);
destroy_workqueue(cma_wq);
Modified: projects/ofed/head/sys/ofed/drivers/infiniband/hw/mlx4/main.c
==============================================================================
--- projects/ofed/head/sys/ofed/drivers/infiniband/hw/mlx4/main.c Mon Jan 3 03:08:08 2011 (r216904)
+++ projects/ofed/head/sys/ofed/drivers/infiniband/hw/mlx4/main.c Mon Jan 3 03:34:59 2011 (r216905)
@@ -94,9 +94,7 @@ static void init_query_mad(struct ib_smp
mad->method = IB_MGMT_METHOD_GET;
}
-#ifdef __linux__
static union ib_gid zgid;
-#endif
static int mlx4_ib_query_device(struct ib_device *ibdev,
struct ib_device_attr *props)
@@ -664,10 +662,9 @@ static int add_gid_entry(struct ib_qp *i
int mlx4_ib_add_mc(struct mlx4_ib_dev *mdev, struct mlx4_ib_qp *mqp,
union ib_gid *gid)
{
- int ret = 0;
-#ifdef __linux__
u8 mac[6];
struct net_device *ndev;
+ int ret = 0;
if (!mqp->port)
return 0;
@@ -684,7 +681,6 @@ int mlx4_ib_add_mc(struct mlx4_ib_dev *m
rtnl_unlock();
dev_put(ndev);
}
-#endif
return ret;
}
@@ -732,10 +728,8 @@ static int mlx4_ib_mcg_detach(struct ib_
int err;
struct mlx4_ib_dev *mdev = to_mdev(ibqp->device);
struct mlx4_ib_qp *mqp = to_mqp(ibqp);
-#ifdef __linux__
u8 mac[6];
struct net_device *ndev;
-#endif
struct gid_entry *ge;
err = mlx4_multicast_detach(mdev->dev,
@@ -746,7 +740,6 @@ static int mlx4_ib_mcg_detach(struct ib_
mutex_lock(&mqp->mutex);
ge = find_gid_entry(mqp, gid->raw);
if (ge) {
-#ifdef __linux__
spin_lock(&mdev->iboe.lock);
ndev = ge->added ? mdev->iboe.netdevs[ge->port - 1] : NULL;
if (ndev)
@@ -759,7 +752,6 @@ static int mlx4_ib_mcg_detach(struct ib_
rtnl_unlock();
dev_put(ndev);
}
-#endif
list_del(&ge->list);
kfree(ge);
} else
@@ -1056,7 +1048,6 @@ struct attribute_group diag_counters_gro
.attrs = diag_rprt_attrs
};
-#ifdef __linux__
static void mlx4_addrconf_ifid_eui48(u8 *eui, int is_vlan, u16 vlan_id, struct net_device *dev)
{
#ifdef __linux__
@@ -1114,12 +1105,14 @@ static int update_ipv6_gids(struct mlx4_
{
struct net_device *ndev = dev->iboe.netdevs[port - 1];
struct update_gid_work *work;
+#ifdef __linux__
struct net_device *tmp;
+#endif
int i;
u8 *hits;
int ret;
union ib_gid gid;
- int free = -1;
+ int tofree = -1;
int found;
int need_update = 0;
int is_vlan;
@@ -1135,15 +1128,17 @@ static int update_ipv6_gids(struct mlx4_
goto out;
}
- /* XXX vlan */
+#ifdef __linux__
read_lock(&dev_base_lock);
for_each_netdev(&init_net, tmp) {
if (ndev && (tmp == ndev
+ /* XXX vlan */
#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
|| vlan_dev_real_dev(tmp) == ndev)) {
#else
)) {
#endif
+#endif
gid.global.subnet_prefix = cpu_to_be64(0xfe80000000000000LL);
#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
vid = vlan_dev_vlan_id(tmp);
@@ -1155,23 +1150,25 @@ static int update_ipv6_gids(struct mlx4_
mlx4_addrconf_ifid_eui48(&gid.raw[8], is_vlan, vid, ndev);
found = 0;
for (i = 0; i < 128; ++i) {
- if (free < 0 &&
+ if (tofree < 0 &&
!memcmp(&dev->iboe.gid_table[port - 1][i], &zgid, sizeof zgid))
- free = i;
+ tofree = i;
if (!memcmp(&dev->iboe.gid_table[port - 1][i], &gid, sizeof gid)) {
hits[i] = 1;
found = 1;
break;
}
}
- if (!found && free >= 0) {
- dev->iboe.gid_table[port - 1][free] = gid;
- hits[free] = 1;
+ if (!found && tofree >= 0) {
+ dev->iboe.gid_table[port - 1][tofree] = gid;
+ hits[tofree] = 1;
++need_update;
}
+#ifdef __linux__
}
}
read_unlock(&dev_base_lock);
+#endif
for (i = 0; i < 128; ++i)
if (!hits[i]) {
@@ -1221,7 +1218,6 @@ static void netdev_removed(struct mlx4_i
update_ipv6_gids(dev, port, 1);
}
-/* XXX netdev event needed. */
static int mlx4_ib_netdev_event(struct notifier_block *this, unsigned long event,
void *ptr)
{
@@ -1231,8 +1227,10 @@ static int mlx4_ib_netdev_event(struct n
struct mlx4_ib_iboe *iboe;
int port;
+#ifdef __linux__
if (!net_eq(dev_net(dev), &init_net))
return NOTIFY_DONE;
+#endif
ibdev = container_of(this, struct mlx4_ib_dev, iboe.nb);
iboe = &ibdev->iboe;
@@ -1268,7 +1266,6 @@ static int mlx4_ib_netdev_event(struct n
return NOTIFY_DONE;
}
-#endif
static void *mlx4_ib_add(struct mlx4_dev *dev)
{
@@ -1434,14 +1431,12 @@ static void *mlx4_ib_add(struct mlx4_dev
if (mlx4_ib_mad_init(ibdev))
goto err_reg;
-#ifdef __linux__
if (dev->caps.flags & MLX4_DEV_CAP_FLAG_IBOE && !iboe->nb.notifier_call) {
iboe->nb.notifier_call = mlx4_ib_netdev_event;
err = register_netdevice_notifier(&iboe->nb);
if (err)
goto err_reg;
}
-#endif
for (i = 0; i < ARRAY_SIZE(mlx4_class_attributes); ++i) {
if (device_create_file(&ibdev->ib_dev.dev,
mlx4_class_attributes[i]))
@@ -1456,10 +1451,8 @@ static void *mlx4_ib_add(struct mlx4_dev
return ibdev;
err_notif:
-#ifdef __linux__
if (unregister_netdevice_notifier(&ibdev->iboe.nb))
printk(KERN_WARNING "failure unregistering notifier\n");
-#endif
flush_workqueue(wq);
err_reg:
@@ -1498,9 +1491,7 @@ static void mlx4_ib_remove(struct mlx4_d
mlx4_counter_free(ibdev->dev, ibdev->counters[k]);
if (ibdev->iboe.nb.notifier_call) {
-#ifdef __linux__
unregister_netdevice_notifier(&ibdev->iboe.nb);
-#endif
flush_workqueue(wq);
ibdev->iboe.nb.notifier_call = NULL;
}
Modified: projects/ofed/head/sys/ofed/include/linux/netdevice.h
==============================================================================
--- projects/ofed/head/sys/ofed/include/linux/netdevice.h Mon Jan 3 03:08:08 2011 (r216904)
+++ projects/ofed/head/sys/ofed/include/linux/netdevice.h Mon Jan 3 03:34:59 2011 (r216905)
@@ -54,9 +54,99 @@ extern struct net init_net;
#define net_device ifnet
#define dev_get_by_index(n, idx) ifnet_byindex_ref((idx))
+#define dev_hold(d) if_ref((d))
#define dev_put(d) if_rele((d))
#define netif_running(dev) !!(dev->if_drv_flags & IFF_DRV_RUNNING)
#define netif_oper_up(dev) !!(dev->if_flags & IFF_UP)
+static inline void
+_handle_ifnet_link_event(void *arg, struct ifnet *ifp, int linkstate)
+{
+ struct notifier_block *nb;
+
+ nb = arg;
+ if (linkstate == LINK_STATE_UP)
+ nb->notifier_call(nb, NETDEV_UP, ifp);
+ else
+ nb->notifier_call(nb, NETDEV_DOWN, ifp);
+}
+
+static inline void
+_handle_ifnet_arrival_event(void *arg, struct ifnet *ifp)
+{
+ struct notifier_block *nb;
+
+ nb = arg;
+ nb->notifier_call(nb, NETDEV_REGISTER, ifp);
+}
+
+static inline void
+_handle_ifnet_departure_event(void *arg, struct ifnet *ifp)
+{
+ struct notifier_block *nb;
+
+ nb = arg;
+ nb->notifier_call(nb, NETDEV_UNREGISTER, ifp);
+}
+
+static inline int
+register_netdevice_notifier(struct notifier_block *nb)
+{
+
+ nb->tags[NETDEV_UP] = EVENTHANDLER_REGISTER(
+ ifnet_link_event, _handle_ifnet_link_event, nb, 0);
+ nb->tags[NETDEV_REGISTER] = EVENTHANDLER_REGISTER(
+ ifnet_arrival_event, _handle_ifnet_arrival_event, nb, 0);
+ nb->tags[NETDEV_UNREGISTER] = EVENTHANDLER_REGISTER(
+ ifnet_departure_event, _handle_ifnet_departure_event, nb, 0);
+ return (0);
+}
+
+static inline int
+unregister_netdevice_notifier(struct notifier_block *nb)
+{
+
+ EVENTHANDLER_DEREGISTER(ifnet_link_event, nb->tags[NETDEV_UP]);
+ EVENTHANDLER_DEREGISTER(ifnet_arrival_event, nb->tags[NETDEV_REGISTER]);
+ EVENTHANDLER_DEREGISTER(ifnet_departure_event,
+ nb->tags[NETDEV_UNREGISTER]);
+ return (0);
+}
+
+#define rtnl_lock()
+#define rtnl_unlock()
+
+static inline int
+dev_mc_delete(struct net_device *dev, void *addr, int alen, int all)
+{
+ struct sockaddr_dl sdl;
+
+ if (alen > sizeof(sdl.sdl_data))
+ return (-EINVAL);
+ memset(&sdl, 0, sizeof(sdl));
+ sdl.sdl_len = sizeof(sdl);
+ sdl.sdl_family = AF_LINK;
+ sdl.sdl_alen = alen;
+ memcpy(&sdl.sdl_data, addr, alen);
+
+ return -if_delmulti(dev, (struct sockaddr *)&sdl);
+}
+
+static inline int
+dev_mc_add(struct net_device *dev, void *addr, int alen, int newonly)
+{
+ struct sockaddr_dl sdl;
+
+ if (alen > sizeof(sdl.sdl_data))
+ return (-EINVAL);
+ memset(&sdl, 0, sizeof(sdl));
+ sdl.sdl_len = sizeof(sdl);
+ sdl.sdl_family = AF_LINK;
+ sdl.sdl_alen = alen;
+ memcpy(&sdl.sdl_data, addr, alen);
+
+ return -if_addmulti(dev, (struct sockaddr *)&sdl, NULL);
+}
+
#endif /* _LINUX_NETDEVICE_H_ */
Modified: projects/ofed/head/sys/ofed/include/linux/notifier.h
==============================================================================
--- projects/ofed/head/sys/ofed/include/linux/notifier.h Mon Jan 3 03:08:08 2011 (r216904)
+++ projects/ofed/head/sys/ofed/include/linux/notifier.h Mon Jan 3 03:34:59 2011 (r216905)
@@ -34,13 +34,21 @@
/*
* Max number of FreeBSD events to map to Linux events per notify type.
*/
-#define NB_COUNT 5
+#define NOTIFY_DONE 0
+#define _NOTIFY_COUNT 5
struct notifier_block {
int (*notifier_call)(struct notifier_block *, unsigned long, void *);
struct notifier_block *next;
int priority;
- eventhandler_tag tags[NB_COUNT];
+ eventhandler_tag tags[_NOTIFY_COUNT];
};
+/* Values must be less than NOTIFY_COUNT */
+#define NETDEV_UP 0x0001
+#define NETDEV_DOWN 0x0002
+#define NETDEV_REGISTER 0x0003
+#define NETDEV_UNREGISTER 0x0004
+
+
#endif /* _LINUX_NOTIFIER_H_ */
More information about the svn-src-projects
mailing list