svn commit: r216789 - in projects/ofed/head/sys/ofed: drivers/infiniband/core include/linux include/net

Jeff Roberson jeff at FreeBSD.org
Wed Dec 29 04:17:50 UTC 2010


Author: jeff
Date: Wed Dec 29 04:17:50 2010
New Revision: 216789
URL: http://svn.freebsd.org/changeset/base/216789

Log:
   - Solve a bug in addr.c where ifp could end up NULL.
  
  Reported/Tested by:	gnn
  
   - Add support for Linux netevents via BSD eventhandlers.
  
  Sponsored by:	Isilon Systems, iX Systems, and Panasas.

Modified:
  projects/ofed/head/sys/ofed/drivers/infiniband/core/addr.c
  projects/ofed/head/sys/ofed/include/linux/notifier.h
  projects/ofed/head/sys/ofed/include/net/netevent.h

Modified: projects/ofed/head/sys/ofed/drivers/infiniband/core/addr.c
==============================================================================
--- projects/ofed/head/sys/ofed/drivers/infiniband/core/addr.c	Wed Dec 29 04:16:12 2010	(r216788)
+++ projects/ofed/head/sys/ofed/drivers/infiniband/core/addr.c	Wed Dec 29 04:17:50 2010	(r216789)
@@ -427,17 +427,21 @@ static int addr_resolve(struct sockaddr 
 	}
 	/*
 	 * If it's not multicast or broadcast and the route doesn't match the
-	 * requested interface return unreachable.
+	 * requested interface return unreachable.  Otherwise fetch the
+	 * correct interface pointer and unlock the route.
 	 */
 	if (multi || bcast) {
+		if (ifp == NULL)
+			ifp = rte->rt_ifp;
 		RTFREE_LOCKED(rte);
 	} else if (ifp && ifp != rte->rt_ifp) {
 		RTFREE_LOCKED(rte);
 		return -ENETUNREACH;
-	} else
+	} else {
+		if (ifp == NULL)
+			ifp = rte->rt_ifp;
 		RT_UNLOCK(rte);
-	if (ifp == NULL)
-		ifp = rte->rt_ifp;
+	}
 mcast:
 	if (bcast)
 		return rdma_copy_addr(addr, ifp, ifp->if_broadcastaddr);
@@ -584,17 +588,19 @@ void rdma_addr_cancel(struct rdma_dev_ad
 }
 EXPORT_SYMBOL(rdma_addr_cancel);
 
-#ifdef __linux__
-/* XXX Need this callback to reduce timeout time. */
 static int netevent_callback(struct notifier_block *self, unsigned long event,
 	void *ctx)
 {
 	if (event == NETEVENT_NEIGH_UPDATE) {
+#ifdef __linux__
 		struct neighbour *neigh = ctx;
 
 		if (neigh->nud_state & NUD_VALID) {
 			set_timeout(jiffies);
 		}
+#else
+		set_timeout(jiffies);
+#endif
 	}
 	return 0;
 }
@@ -602,7 +608,6 @@ static int netevent_callback(struct noti
 static struct notifier_block nb = {
 	.notifier_call = netevent_callback
 };
-#endif
 
 static int addr_init(void)
 {
@@ -611,17 +616,13 @@ static int addr_init(void)
 	if (!addr_wq)
 		return -ENOMEM;
 
-#ifdef __linux__
 	register_netevent_notifier(&nb);
-#endif
 	return 0;
 }
 
 static void addr_cleanup(void)
 {
-#ifdef __linux__
 	unregister_netevent_notifier(&nb);
-#endif
 	destroy_workqueue(addr_wq);
 }
 

Modified: projects/ofed/head/sys/ofed/include/linux/notifier.h
==============================================================================
--- projects/ofed/head/sys/ofed/include/linux/notifier.h	Wed Dec 29 04:16:12 2010	(r216788)
+++ projects/ofed/head/sys/ofed/include/linux/notifier.h	Wed Dec 29 04:17:50 2010	(r216789)
@@ -29,10 +29,18 @@
 #ifndef	_LINUX_NOTIFIER_H_
 #define	_LINUX_NOTIFIER_H_
 
+#include <sys/eventhandler.h>
+
+/*
+ * Max number of FreeBSD events to map to Linux events per notify type.
+ */
+#define	NB_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];
 };
 
 #endif	/* _LINUX_NOTIFIER_H_ */

Modified: projects/ofed/head/sys/ofed/include/net/netevent.h
==============================================================================
--- projects/ofed/head/sys/ofed/include/net/netevent.h	Wed Dec 29 04:16:12 2010	(r216788)
+++ projects/ofed/head/sys/ofed/include/net/netevent.h	Wed Dec 29 04:17:50 2010	(r216789)
@@ -25,3 +25,47 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
+
+#ifndef	_LINUX_NET_NETEVENT_H_
+#define	_LINUX_NET_NETEVENT_H_
+
+#include <netinet/if_ether.h>
+
+enum netevent_notif_type {
+	NETEVENT_NEIGH_UPDATE = 0,
+#if 0 /* Unsupported events. */
+        NETEVENT_PMTU_UPDATE,
+        NETEVENT_REDIRECT,
+#endif
+};
+
+struct llentry;
+
+static inline void
+_handle_arp_update_event(void *arg, struct llentry *lle)
+{
+	struct notifier_block *nb;
+
+	nb = arg;
+	nb->notifier_call(nb, NETEVENT_NEIGH_UPDATE, lle);
+}
+
+static inline int
+register_netevent_notifier(struct notifier_block *nb)
+{
+	nb->tags[NETEVENT_NEIGH_UPDATE] = EVENTHANDLER_REGISTER(
+	    arp_update_event, _handle_arp_update_event, nb, 0);
+	return (0);
+}
+
+static inline int
+unregister_netevent_notifier(struct notifier_block *nb)
+{
+
+	EVENTHANDLER_DEREGISTER(arp_update_event,
+	    nb->tags[NETEVENT_NEIGH_UPDATE]);
+
+	return (0);
+}
+
+#endif /* _LINUX_NET_NETEVENT_H_ */


More information about the svn-src-projects mailing list