diff options
author | hselasky <hselasky@FreeBSD.org> | 2015-01-13 17:07:30 +0000 |
---|---|---|
committer | hselasky <hselasky@FreeBSD.org> | 2015-01-13 17:07:30 +0000 |
commit | 5c6e5d81e996b18847b942e50e5544b5cafebe50 (patch) | |
tree | 4dce4d994559ed6b5be2cab4248c6dc19f344a39 /sys/ofed | |
parent | ca95da9368ea3ead4c53f70a6a8a812b7f38ffde (diff) | |
download | FreeBSD-src-5c6e5d81e996b18847b942e50e5544b5cafebe50.zip FreeBSD-src-5c6e5d81e996b18847b942e50e5544b5cafebe50.tar.gz |
MFC r276749:
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
Diffstat (limited to 'sys/ofed')
-rw-r--r-- | sys/ofed/drivers/infiniband/hw/mlx4/main.c | 8 | ||||
-rw-r--r-- | sys/ofed/drivers/net/mlx4/main.c | 4 | ||||
-rw-r--r-- | sys/ofed/include/linux/file.h | 15 | ||||
-rw-r--r-- | sys/ofed/include/linux/kernel.h | 82 | ||||
-rw-r--r-- | sys/ofed/include/linux/linux_compat.c | 8 | ||||
-rw-r--r-- | sys/ofed/include/linux/linux_idr.c | 1 | ||||
-rw-r--r-- | sys/ofed/include/linux/list.h | 1 | ||||
-rw-r--r-- | sys/ofed/include/linux/pci.h | 13 |
8 files changed, 90 insertions, 42 deletions
diff --git a/sys/ofed/drivers/infiniband/hw/mlx4/main.c b/sys/ofed/drivers/infiniband/hw/mlx4/main.c index 343b193..3a78502 100644 --- a/sys/ofed/drivers/infiniband/hw/mlx4/main.c +++ b/sys/ofed/drivers/infiniband/hw/mlx4/main.c @@ -1613,8 +1613,12 @@ static void mlx4_ib_alloc_eqs(struct mlx4_dev *dev, struct mlx4_ib_dev *ibdev) 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])) { diff --git a/sys/ofed/drivers/net/mlx4/main.c b/sys/ofed/drivers/net/mlx4/main.c index 12c5836..b92626d 100644 --- a/sys/ofed/drivers/net/mlx4/main.c +++ b/sys/ofed/drivers/net/mlx4/main.c @@ -504,10 +504,6 @@ int mlx4_get_val(struct mlx4_dbdf2val *tbl, struct pci_dev *pdev, int idx, 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)); diff --git a/sys/ofed/include/linux/file.h b/sys/ofed/include/linux/file.h index 6576cd0..b76a408 100644 --- a/sys/ofed/include/linux/file.h +++ b/sys/ofed/include/linux/file.h @@ -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 *filp) 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; } diff --git a/sys/ofed/include/linux/kernel.h b/sys/ofed/include/linux/kernel.h index e1bc220..d9d1ab6 100644 --- a/sys/ofed/include/linux/kernel.h +++ b/sys/ofed/include/linux/kernel.h @@ -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 diff --git a/sys/ofed/include/linux/linux_compat.c b/sys/ofed/include/linux/linux_compat.c index 5ac7dd6..db617bb 100644 --- a/sys/ofed/include/linux/linux_compat.c +++ b/sys/ofed/include/linux/linux_compat.c @@ -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, struct device *parent, dev_t devt, 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); diff --git a/sys/ofed/include/linux/linux_idr.c b/sys/ofed/include/linux/linux_idr.c index 0238c8e..273f2ea 100644 --- a/sys/ofed/include/linux/linux_idr.c +++ b/sys/ofed/include/linux/linux_idr.c @@ -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]; diff --git a/sys/ofed/include/linux/list.h b/sys/ofed/include/linux/list.h index b939ba5..4e9337b 100644 --- a/sys/ofed/include/linux/list.h +++ b/sys/ofed/include/linux/list.h @@ -57,6 +57,7 @@ #include <netinet/in.h> #include <netinet/in_pcb.h> +#include <netinet/in_var.h> #include <netinet6/in6_var.h> #include <netinet6/nd6.h> diff --git a/sys/ofed/include/linux/pci.h b/sys/ofed/include/linux/pci.h index c348832..3e574f0 100644 --- a/sys/ofed/include/linux/pci.h +++ b/sys/ofed/include/linux/pci.h @@ -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 * @@ -577,6 +576,14 @@ pci_enable_msix(struct pci_dev *pdev, struct msix_entry *entries, int nreq) 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; |