Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 6 Jan 2015 10:02:15 +0000 (UTC)
From:      Hans Petter Selasky <hselasky@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r276749 - in head/sys/ofed: drivers/infiniband/hw/mlx4 drivers/net/mlx4 include/linux
Message-ID:  <201501061002.t06A2F5i015802@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: hselasky
Date: Tue Jan  6 10:02:14 2015
New Revision: 276749
URL: https://svnweb.freebsd.org/changeset/base/276749

Log:
  Fixes and updates for the Linux compatibility layer:
  - Remove unsupported "bus" field from "struct pci_dev".
  - Fix logic inside "pci_enable_msix()" when the number of allocated
    interrupts are less than the number of available interrupts.
  - Update header files included from "list.h".
  - Ensure that "idr_destroy()" removes all entries before destroying
    the IDR root node(s).
  - Set the "device->release" function so that we don't leak memory at
    device destruction.
  - Use FreeBSD's "log()" function for certain debug printouts.
  - Put parenthesis around arguments inside the min, max, min_t and max_t macros.
  - Make sure we don't leak file descriptors by dropping the extra file
    reference counts done by the FreeBSD kernel when calling falloc()
    and fget_unlocked().
  
  MFC after:	1 week
  Sponsored by:	Mellanox Technologies

Modified:
  head/sys/ofed/drivers/infiniband/hw/mlx4/main.c
  head/sys/ofed/drivers/net/mlx4/main.c
  head/sys/ofed/include/linux/file.h
  head/sys/ofed/include/linux/kernel.h
  head/sys/ofed/include/linux/linux_compat.c
  head/sys/ofed/include/linux/linux_idr.c
  head/sys/ofed/include/linux/list.h
  head/sys/ofed/include/linux/pci.h

Modified: head/sys/ofed/drivers/infiniband/hw/mlx4/main.c
==============================================================================
--- head/sys/ofed/drivers/infiniband/hw/mlx4/main.c	Tue Jan  6 09:39:42 2015	(r276748)
+++ head/sys/ofed/drivers/infiniband/hw/mlx4/main.c	Tue Jan  6 10:02:14 2015	(r276749)
@@ -1613,8 +1613,12 @@ static void mlx4_ib_alloc_eqs(struct mlx
 	eq = 0;
 	mlx4_foreach_port(i, dev, MLX4_PORT_TYPE_IB) {
 		for (j = 0; j < eq_per_port; j++) {
-			//sprintf(name, "mlx4-ib-%d-%d@%s",
-			//	i, j, dev->pdev->bus->conf.pd_name);
+			snprintf(name, sizeof(name), "mlx4-ib-%d-%d@%d:%d:%d:%d", i, j,
+			    pci_get_domain(dev->pdev->dev.bsddev),
+			    pci_get_bus(dev->pdev->dev.bsddev),
+			    PCI_SLOT(dev->pdev->devfn),
+			    PCI_FUNC(dev->pdev->devfn));
+
 			/* Set IRQ for specific name (per ring) */
 			if (mlx4_assign_eq(dev, name,
 					   &ibdev->eq_table[eq])) {

Modified: head/sys/ofed/drivers/net/mlx4/main.c
==============================================================================
--- head/sys/ofed/drivers/net/mlx4/main.c	Tue Jan  6 09:39:42 2015	(r276748)
+++ head/sys/ofed/drivers/net/mlx4/main.c	Tue Jan  6 10:02:14 2015	(r276749)
@@ -504,10 +504,6 @@ int mlx4_get_val(struct mlx4_dbdf2val *t
 	if (!pdev)
 		return -EINVAL;
 
-	if (!pdev->bus) {
-		return -EINVAL;
-	}
-
         dbdf = dbdf_to_u64(pci_get_domain(pdev->dev.bsddev), pci_get_bus(pdev->dev.bsddev),
 			   PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn));
 

Modified: head/sys/ofed/include/linux/file.h
==============================================================================
--- head/sys/ofed/include/linux/file.h	Tue Jan  6 09:39:42 2015	(r276748)
+++ head/sys/ofed/include/linux/file.h	Tue Jan  6 10:02:14 2015	(r276749)
@@ -77,7 +77,15 @@ put_unused_fd(unsigned int fd)
 	    NULL) != 0) {
 		return;
 	}
+	/*
+	 * NOTE: We should only get here when the "fd" has not been
+	 * installed, so no need to free the associated Linux file
+	 * structure.
+	 */
 	fdclose(curthread->td_proc->p_fd, file, fd, curthread);
+
+	/* drop extra reference */
+	fdrop(file, curthread);
 }
 
 static inline void
@@ -90,7 +98,10 @@ fd_install(unsigned int fd, struct linux
 		file = NULL;
 	}
 	filp->_file = file;
-        finit(file, filp->f_mode, DTYPE_DEV, filp, &linuxfileops);
+	finit(file, filp->f_mode, DTYPE_DEV, filp, &linuxfileops);
+
+	/* drop the extra reference */
+	fput(filp);
 }
 
 static inline int
@@ -103,6 +114,8 @@ get_unused_fd(void)
 	error = falloc(curthread, &file, &fd, 0);
 	if (error)
 		return -error;
+	/* drop the extra reference */
+	fdrop(file, curthread);
 	return fd;
 }
 

Modified: head/sys/ofed/include/linux/kernel.h
==============================================================================
--- head/sys/ofed/include/linux/kernel.h	Tue Jan  6 09:39:42 2015	(r276748)
+++ head/sys/ofed/include/linux/kernel.h	Tue Jan  6 10:02:14 2015	(r276749)
@@ -35,6 +35,7 @@
 #include <sys/stat.h>
 #include <sys/smp.h>
 #include <sys/stddef.h>
+#include <sys/syslog.h>
 
 #include <linux/bitops.h>
 #include <linux/compiler.h>
@@ -65,7 +66,23 @@
 #define	DIV_ROUND_UP		howmany
 
 #define	printk(X...)		printf(X)
-#define	pr_debug(fmt, ...)	printk(KERN_DEBUG # fmt, ##__VA_ARGS__)
+
+/*
+ * The "pr_debug()" and "pr_devel()" macros should produce zero code
+ * unless DEBUG is defined:
+ */
+#ifdef DEBUG
+#define pr_debug(fmt, ...) \
+        log(LOG_DEBUG, fmt, ##__VA_ARGS__)
+#define pr_devel(fmt, ...) \
+	log(LOG_DEBUG, pr_fmt(fmt), ##__VA_ARGS__)
+#else
+#define pr_debug(fmt, ...) \
+        ({ if (0) log(LOG_DEBUG, fmt, ##__VA_ARGS__); 0; })
+#define pr_devel(fmt, ...) \
+	({ if (0) log(LOG_DEBUG, pr_fmt(fmt), ##__VA_ARGS__); 0; })
+#endif
+
 #define udelay(t)       	DELAY(t)
 
 #ifndef pr_fmt
@@ -75,45 +92,46 @@
 /*
  * Print a one-time message (analogous to WARN_ONCE() et al):
  */
-#define printk_once(x...) ({                    \
-        static bool __print_once;               \
-                                                \
-        if (!__print_once) {                    \
-                __print_once = true;            \
-                printk(x);                      \
-        }                                       \
-})
-
+#define printk_once(...) do {			\
+	static bool __print_once;		\
+						\
+	if (!__print_once) {			\
+		__print_once = true;		\
+		printk(__VA_ARGS__);		\
+	}					\
+} while (0)
 
+/*
+ * Log a one-time message (analogous to WARN_ONCE() et al):
+ */
+#define log_once(level,...) do {		\
+	static bool __log_once;			\
+						\
+	if (!__log_once) {			\
+		__log_once = true;		\
+		log(level, __VA_ARGS__);	\
+	}					\
+} while (0)
 
 #define pr_emerg(fmt, ...) \
-        printk(KERN_EMERG pr_fmt(fmt), ##__VA_ARGS__)
+	log(LOG_EMERG, pr_fmt(fmt), ##__VA_ARGS__)
 #define pr_alert(fmt, ...) \
-        printk(KERN_ALERT pr_fmt(fmt), ##__VA_ARGS__)
+	log(LOG_ALERT, pr_fmt(fmt), ##__VA_ARGS__)
 #define pr_crit(fmt, ...) \
-        printk(KERN_CRIT pr_fmt(fmt), ##__VA_ARGS__)
+	log(LOG_CRIT, pr_fmt(fmt), ##__VA_ARGS__)
 #define pr_err(fmt, ...) \
-        printk(KERN_ERR pr_fmt(fmt), ##__VA_ARGS__)
+	log(LOG_ERR, pr_fmt(fmt), ##__VA_ARGS__)
 #define pr_warning(fmt, ...) \
-        printk(KERN_WARNING pr_fmt(fmt), ##__VA_ARGS__)
+	log(LOG_WARNING, pr_fmt(fmt), ##__VA_ARGS__)
 #define pr_warn pr_warning
 #define pr_notice(fmt, ...) \
-        printk(KERN_NOTICE pr_fmt(fmt), ##__VA_ARGS__)
+	log(LOG_NOTICE, pr_fmt(fmt), ##__VA_ARGS__)
 #define pr_info(fmt, ...) \
-        printk(KERN_INFO pr_fmt(fmt), ##__VA_ARGS__)
+	log(LOG_INFO, pr_fmt(fmt), ##__VA_ARGS__)
 #define pr_info_once(fmt, ...) \
-        printk_once(KERN_INFO pr_fmt(fmt), ##__VA_ARGS__)
+	log_once(LOG_INFO, pr_fmt(fmt), ##__VA_ARGS__)
 #define pr_cont(fmt, ...) \
-        printk(KERN_CONT fmt, ##__VA_ARGS__)
-
-/* pr_devel() should produce zero code unless DEBUG is defined */
-#ifdef DEBUG
-#define pr_devel(fmt, ...) \
-        printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__)
-#else
-#define pr_devel(fmt, ...) \
-        ({ if (0) printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__); 0; })
-#endif
+	printk(KERN_CONT fmt, ##__VA_ARGS__)
 
 #ifndef WARN
 #define WARN(condition, format...) ({                                   \
@@ -136,10 +154,10 @@
 #define	simple_strtol	strtol
 #define kstrtol(a,b,c) ({*(c) = strtol(a,0,b);})
 
-#define min(x, y)	(x < y ? x : y)
-#define max(x, y)	(x > y ? x : y)
-#define min_t(type, _x, _y)	(type)(_x) < (type)(_y) ? (type)(_x) : (_y)
-#define max_t(type, _x, _y)	(type)(_x) > (type)(_y) ? (type)(_x) : (_y)
+#define min(x, y)	((x) < (y) ? (x) : (y))
+#define max(x, y)	((x) > (y) ? (x) : (y))
+#define min_t(type, _x, _y)	((type)(_x) < (type)(_y) ? (type)(_x) : (type)(_y))
+#define max_t(type, _x, _y)	((type)(_x) > (type)(_y) ? (type)(_x) : (type)(_y))
 
 /*
  * This looks more complex than it should be. But we need to

Modified: head/sys/ofed/include/linux/linux_compat.c
==============================================================================
--- head/sys/ofed/include/linux/linux_compat.c	Tue Jan  6 09:39:42 2015	(r276748)
+++ head/sys/ofed/include/linux/linux_compat.c	Tue Jan  6 10:02:14 2015	(r276749)
@@ -174,6 +174,13 @@ kobject_kfree_name(struct kobject *kobj)
 
 struct kobj_type kfree_type = { .release = kobject_kfree };
 
+static void
+dev_release(struct device *dev)
+{
+	pr_debug("dev_release: %s\n", dev_name(dev));
+	kfree(dev);
+}
+
 struct device *
 device_create(struct class *class, struct device *parent, dev_t devt,
     void *drvdata, const char *fmt, ...)
@@ -186,6 +193,7 @@ device_create(struct class *class, struc
 	dev->class = class;
 	dev->devt = devt;
 	dev->driver_data = drvdata;
+	dev->release = dev_release;
 	va_start(args, fmt);
 	kobject_set_name_vargs(&dev->kobj, fmt, args);
 	va_end(args);

Modified: head/sys/ofed/include/linux/linux_idr.c
==============================================================================
--- head/sys/ofed/include/linux/linux_idr.c	Tue Jan  6 09:39:42 2015	(r276748)
+++ head/sys/ofed/include/linux/linux_idr.c	Tue Jan  6 10:02:14 2015	(r276749)
@@ -77,6 +77,7 @@ idr_destroy(struct idr *idr)
 {
 	struct idr_layer *il, *iln;
 
+	idr_remove_all(idr);
 	mtx_lock(&idr->lock);
 	for (il = idr->free; il != NULL; il = iln) {
 		iln = il->ary[0];

Modified: head/sys/ofed/include/linux/list.h
==============================================================================
--- head/sys/ofed/include/linux/list.h	Tue Jan  6 09:39:42 2015	(r276748)
+++ head/sys/ofed/include/linux/list.h	Tue Jan  6 10:02:14 2015	(r276749)
@@ -58,6 +58,7 @@
 
 #include <netinet/in.h>
 #include <netinet/in_pcb.h>
+#include <netinet/in_var.h>
 
 #include <netinet6/in6_var.h>
 #include <netinet6/nd6.h>

Modified: head/sys/ofed/include/linux/pci.h
==============================================================================
--- head/sys/ofed/include/linux/pci.h	Tue Jan  6 09:39:42 2015	(r276748)
+++ head/sys/ofed/include/linux/pci.h	Tue Jan  6 10:02:14 2015	(r276749)
@@ -149,9 +149,8 @@ struct pci_dev {
 	uint16_t		device;
 	uint16_t		vendor;
 	unsigned int		irq;
-        unsigned int            devfn;
-        u8                      revision;
-        struct pci_devinfo      *bus; /* bus this device is on, equivalent to linux struct pci_bus */
+	unsigned int		devfn;
+	u8			revision;
 };
 
 static inline struct resource_list_entry *
@@ -581,6 +580,14 @@ pci_enable_msix(struct pci_dev *pdev, st
 	avail = nreq;
 	if ((error = -pci_alloc_msix(pdev->dev.bsddev, &avail)) != 0)
 		return error;
+	/*
+	 * Handle case where "pci_alloc_msix()" may allocate less
+	 * interrupts than available and return with no error:
+	 */
+	if (avail < nreq) {
+		pci_release_msi(pdev->dev.bsddev);
+		return avail;
+	}
 	rle = _pci_get_rle(pdev, SYS_RES_IRQ, 1);
 	pdev->dev.msix = rle->start;
 	pdev->dev.msix_max = rle->start + avail;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201501061002.t06A2F5i015802>