Skip to content

Commit

Permalink
NTB: Correct debugfs to work with more than 1 NTB Device
Browse files Browse the repository at this point in the history
Debugfs was setup in NTB to only have a single debugfs directory.  This
resulted in the leaking of debugfs directories and files when multiple
NTB devices were present, due to each device stomping on the variables
containing the previous device's values (thus preventing them from being
freed on cleanup).  Correct this by creating a secondary directory of
the PCI BDF for each device present, and nesting the previously existing
information in those directories.

Signed-off-by: Jon Mason <jon.mason@intel.com>
  • Loading branch information
Jon Mason committed Sep 3, 2013
1 parent b6750cf commit 1517a3f
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 12 deletions.
27 changes: 27 additions & 0 deletions drivers/ntb/ntb_hw.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ enum {
BWD_HW,
};

static struct dentry *debugfs_dir;

/* Translate memory window 0,1 to BAR 2,4 */
#define MW_TO_BAR(mw) (mw * 2 + 2)

Expand Down Expand Up @@ -998,6 +1000,28 @@ static void ntb_free_callbacks(struct ntb_device *ndev)
kfree(ndev->db_cb);
}

static void ntb_setup_debugfs(struct ntb_device *ndev)
{
if (!debugfs_initialized())
return;

if (!debugfs_dir)
debugfs_dir = debugfs_create_dir(KBUILD_MODNAME, NULL);

ndev->debugfs_dir = debugfs_create_dir(pci_name(ndev->pdev),
debugfs_dir);
}

static void ntb_free_debugfs(struct ntb_device *ndev)
{
debugfs_remove_recursive(ndev->debugfs_dir);

if (debugfs_dir && simple_empty(debugfs_dir)) {
debugfs_remove_recursive(debugfs_dir);
debugfs_dir = NULL;
}
}

static int ntb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
struct ntb_device *ndev;
Expand All @@ -1010,6 +1034,7 @@ static int ntb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
ndev->pdev = pdev;
ndev->link_status = NTB_LINK_DOWN;
pci_set_drvdata(pdev, ndev);
ntb_setup_debugfs(ndev);

rc = pci_enable_device(pdev);
if (rc)
Expand Down Expand Up @@ -1106,6 +1131,7 @@ static int ntb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
err1:
pci_disable_device(pdev);
err:
ntb_free_debugfs(ndev);
kfree(ndev);

dev_err(&pdev->dev, "Error loading %s module\n", KBUILD_MODNAME);
Expand Down Expand Up @@ -1135,6 +1161,7 @@ static void ntb_pci_remove(struct pci_dev *pdev)
iounmap(ndev->reg_base);
pci_release_selected_regions(pdev, NTB_BAR_MASK);
pci_disable_device(pdev);
ntb_free_debugfs(ndev);
kfree(ndev);
}

Expand Down
16 changes: 16 additions & 0 deletions drivers/ntb/ntb_hw.h
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,8 @@ struct ntb_device {
unsigned char link_status;
struct delayed_work hb_timer;
unsigned long last_ts;

struct dentry *debugfs_dir;
};

/**
Expand Down Expand Up @@ -155,6 +157,20 @@ static inline struct pci_dev *ntb_query_pdev(struct ntb_device *ndev)
return ndev->pdev;
}

/**
* ntb_query_debugfs() - return the debugfs pointer
* @ndev: pointer to ntb_device instance
*
* Given the ntb pointer, return the debugfs directory pointer for the NTB
* hardware device
*
* RETURNS: a pointer to the debugfs directory
*/
static inline struct dentry *ntb_query_debugfs(struct ntb_device *ndev)
{
return ndev->debugfs_dir;
}

struct ntb_device *ntb_register_transport(struct pci_dev *pdev,
void *transport);
void ntb_unregister_transport(struct ntb_device *ndev);
Expand Down
17 changes: 5 additions & 12 deletions drivers/ntb/ntb_transport.c
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,6 @@ struct ntb_transport {
bool transport_link;
struct delayed_work link_work;
struct work_struct link_cleanup;
struct dentry *debugfs_dir;
};

enum {
Expand Down Expand Up @@ -824,12 +823,12 @@ static void ntb_transport_init_queue(struct ntb_transport *nt,
qp->tx_max_frame = min(transport_mtu, tx_size / 2);
qp->tx_max_entry = tx_size / qp->tx_max_frame;

if (nt->debugfs_dir) {
if (ntb_query_debugfs(nt->ndev)) {
char debugfs_name[4];

snprintf(debugfs_name, 4, "qp%d", qp_num);
qp->debugfs_dir = debugfs_create_dir(debugfs_name,
nt->debugfs_dir);
ntb_query_debugfs(nt->ndev));

qp->debugfs_stats = debugfs_create_file("stats", S_IRUSR,
qp->debugfs_dir, qp,
Expand Down Expand Up @@ -857,11 +856,6 @@ int ntb_transport_init(struct pci_dev *pdev)
if (!nt)
return -ENOMEM;

if (debugfs_initialized())
nt->debugfs_dir = debugfs_create_dir(KBUILD_MODNAME, NULL);
else
nt->debugfs_dir = NULL;

nt->ndev = ntb_register_transport(pdev, nt);
if (!nt->ndev) {
rc = -EIO;
Expand Down Expand Up @@ -907,7 +901,6 @@ int ntb_transport_init(struct pci_dev *pdev)
err1:
ntb_unregister_transport(nt->ndev);
err:
debugfs_remove_recursive(nt->debugfs_dir);
kfree(nt);
return rc;
}
Expand All @@ -921,16 +914,16 @@ void ntb_transport_free(void *transport)
nt->transport_link = NTB_LINK_DOWN;

/* verify that all the qp's are freed */
for (i = 0; i < nt->max_qps; i++)
for (i = 0; i < nt->max_qps; i++) {
if (!test_bit(i, &nt->qp_bitmap))
ntb_transport_free_queue(&nt->qps[i]);
debugfs_remove_recursive(nt->qps[i].debugfs_dir);
}

ntb_bus_remove(nt);

cancel_delayed_work_sync(&nt->link_work);

debugfs_remove_recursive(nt->debugfs_dir);

ntb_unregister_event_callback(nt->ndev);

pdev = ntb_query_pdev(nt->ndev);
Expand Down

0 comments on commit 1517a3f

Please sign in to comment.