Date: Mon, 3 Jan 2011 03:34:59 +0000 (UTC) From: Jeff Roberson <jeff@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r216905 - in projects/ofed/head/sys/ofed: drivers/infiniband/core drivers/infiniband/hw/mlx4 include/linux Message-ID: <201101030334.p033YxgH072125@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
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_ */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201101030334.p033YxgH072125>