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
This commit is contained in:
hselasky 2015-01-06 10:02:14 +00:00
parent 18328f686a
commit ff9d81bf5b
8 changed files with 90 additions and 42 deletions

View File

@ -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])) {

View File

@ -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));

View File

@ -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;
}

View File

@ -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

View File

@ -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);

View File

@ -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];

View File

@ -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>

View File

@ -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, 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;