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;
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to