NTB Update
Subsystems (2)
cover NTB Update
The following patches are intended for inclusion in the 3.15 kernel. They include a number of bug fixes, some cleanups, and the conversion to pci_enable_msix_range.
Please let me know if there are any issues.
Thanks,
Jon
---
Alexander Gordeev (4):
ntb: Fix leakage of ntb_device::msix_entries[] array
ntb: Use pci_msix_vec_count() to obtain number of MSI-Xs
ntb: Split ntb_setup_msix() into separate BWD/SNB routines
ntb: Use pci_enable_msix_range() instead of pci_enable_msix()
Jon Mason (4):
ntb_netdev: Fix list_for_each_entry exit issue
ntb_netdev: Fix skb free issue in open
NTB: client event cleanup
NTB: Code Style Clean-up
Roland Dreier (1):
NTB: Fix typo in setting one translation register
PATCH 1/9 ntb_netdev: Fix list_for_each_entry exit issue
If list_for_each_entry exits without finding the ntb_device, the dev pointer will not be NULL. Thus the check will never be true and the code will not exit when it should. Correct this by adding a bool to determine when the device is found, otherwise exit in good fashion.
--- drivers/net/ntb_netdev.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
drivers/net/ntb_netdev.c +5 -2
@@ -367,12 +367,15 @@ static void ntb_netdev_remove(struct pci_dev *pdev) {struct net_device *ndev;struct ntb_netdev *dev; +bool found = false;list_for_each_entry (dev, &dev_list, list) { -if (dev->pdev == pdev) +if (dev->pdev == pdev) { + found = true;break ; + } } -if (dev ==NULL ) +if (!found)return ;list_del (&dev->list);
Signature · 1 line
1.8.3.2
PATCH 2/9 ntb_netdev: Fix skb free issue in open
In reply to Jon MasonIn ntb_netdev_open, when ntb_transport_rx_enqueue fails the skb that was attempting to be enqueued is not freed. Free this skb on the ntb_transport_rx_enqueue error.
--- drivers/net/ntb_netdev.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/net/ntb_netdev.c +3 -1
@@ -182,8 +182,10 @@ static int ntb_netdev_open(struct net_device *ndev) rc =ntb_transport_rx_enqueue (dev->qp, skb, skb->data, ndev->mtu +ETH_HLEN ); -if (rc == -EINVAL ) +if (rc == -EINVAL ) { +dev_kfree_skb (skb); goto err; + } }netif_carrier_off (ndev);
Signature · 1 line
1.8.3.2
PATCH 3/9 NTB: Fix typo in setting one translation register
In reply to Jon MasonFrom: Roland Dreier <[email protected]>
In the code for Xeon devices in back-to-back mode with xeon_errata_workaround disabled, the downstream device puts the wrong value in SNB_B2B_XLAT_OFFSETL (SNB_MBAR01_DSD_ADDR vs. SNB_MBAR01_USD_ADDR).
This was spotted while reading code, since the typo has no practical effect, at least for now: the low 32 bits of both constants are actually identical anyway. However, it's clearer and safer to use the right name.
--- drivers/ntb/ntb_hw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/ntb/ntb_hw.c +1 -1
@@ -785,7 +785,7 @@ static int ntb_xeon_setup(struct ntb_device *ndev)/* B2B_XLAT_OFFSET is a 64bit register, but can * only take 32bit writes */ -writel (SNB_MBAR01_DSD_ADDR &0xffffffff , +writel (SNB_MBAR01_USD_ADDR &0xffffffff , ndev->reg_base +SNB_B2B_XLAT_OFFSETL );writel (SNB_MBAR01_USD_ADDR >>32 , ndev->reg_base +SNB_B2B_XLAT_OFFSETU );
Signature · 1 line
1.8.3.2
PATCH 4/9 ntb: Fix leakage of ntb_device::msix_entries[] array
In reply to Jon MasonFrom: Alexander Gordeev <[email protected]>
--- drivers/ntb/ntb_hw.c | 1 + 1 file changed, 1 insertion(+)
drivers/ntb/ntb_hw.c +1 -0
@@ -1281,6 +1281,7 @@ static void ntb_free_interrupts(struct ntb_device *ndev)free_irq (msix->vector, &ndev->db_cb[i]); }pci_disable_msix (pdev); +kfree (ndev->msix_entries); }else {free_irq (pdev->irq, ndev);
Signature · 1 line
1.8.3.2
PATCH 5/9 NTB: client event cleanup
In reply to Jon MasonProvide a better event interface between the client and transport
--- drivers/net/ntb_netdev.c | 16 ++++++++++++---- drivers/ntb/ntb_hw.h | 4 +--- drivers/ntb/ntb_transport.c | 1 - include/linux/ntb.h | 5 +++++ 4 files changed, 18 insertions(+), 8 deletions(-)
drivers/net/ntb_netdev.c +12 -4
@@ -78,11 +78,19 @@ static void ntb_netdev_event_handler(void *data, int status)netdev_dbg (ndev,"Event %x, Link %x\n" , status,ntb_transport_link_query (dev->qp)); -/* Currently, only link status event is supported */ -if (status) -netif_carrier_on (ndev); -else +switch (status) { +case NTB_LINK_DOWN :netif_carrier_off (ndev); +break ; +case NTB_LINK_UP : +if (!ntb_transport_link_query (dev->qp)) +return ; + +netif_carrier_on (ndev); +break ; +default : +netdev_warn (ndev,"Unsupported event type %d\n" , status); + } } static void ntb_netdev_rx_handler(struct ntb_transport_qp *qp, void *qp_data,
drivers/ntb/ntb_hw.h +1 -3
@@ -45,6 +45,7 @@* Contact Information: * Jon Mason <[email protected]> */ +#include <linux/ntb.h> #define PCI_DEVICE_ID_INTEL_NTB_B2B_JSF 0x3725#define PCI_DEVICE_ID_INTEL_NTB_PS_JSF 0x3726
@@ -83,9 +84,6 @@ static inline void writeq(u64 val, void __iomem *addr)#define NTB_BAR_MASK ((1 << NTB_BAR_MMIO) | (1 << NTB_BAR_23) |\ (1 << NTB_BAR_45)) -#define NTB_LINK_DOWN 0 -#define NTB_LINK_UP 1 -#define NTB_HB_TIMEOUT msecs_to_jiffies(1000)#define NTB_MAX_NUM_MW 2
drivers/ntb/ntb_transport.c +0 -1
@@ -56,7 +56,6 @@#include <linux/pci.h> #include <linux/slab.h> #include <linux/types.h> -#include <linux/ntb.h> #include "ntb_hw.h" #define NTB_TRANSPORT_VERSION 3
include/linux/ntb.h +5 -0
@@ -54,6 +54,11 @@ struct ntb_client {void (*remove) (struct pci_dev *pdev); }; +enum { +NTB_LINK_DOWN =0 , +NTB_LINK_UP , +}; +int ntb_register_client (struct ntb_client *drvr);void ntb_unregister_client (struct ntb_client *drvr);int ntb_register_client_dev (char *device_name);
Signature · 1 line
1.8.3.2
PATCH 6/9 NTB: Code Style Clean-up
In reply to Jon MasonSome white space and 80 char overruns corrected.
--- drivers/net/ntb_netdev.c | 2 +- drivers/ntb/ntb_hw.c | 19 ++++++++++--------- drivers/ntb/ntb_hw.h | 2 +- drivers/ntb/ntb_transport.c | 19 +++++++++---------- include/linux/ntb.h | 14 +++++++------- 5 files changed, 28 insertions(+), 28 deletions(-)
drivers/net/ntb_netdev.c +1 -1
@@ -377,7 +377,7 @@ static void ntb_netdev_remove(struct pci_dev *pdev) {struct net_device *ndev;struct ntb_netdev *dev; -bool found = false; +bool found = false;list_for_each_entry (dev, &dev_list, list) {if (dev->pdev == pdev) {
drivers/ntb/ntb_hw.c +10 -9
@@ -91,7 +91,7 @@ static struct dentry *debugfs_dir;/* Translate memory window 0,1 to BAR 2,4 */ #define MW_TO_BAR (mw) (mw * NTB_MAX_NUM_MW + 2) -static DEFINE_PCI_DEVICE_TABLE (ntb_pci_tbl) = { +static const struct pci_device_id ntb_pci_tbl[] = { {PCI_VDEVICE (INTEL ,PCI_DEVICE_ID_INTEL_NTB_B2B_BWD )}, {PCI_VDEVICE (INTEL ,PCI_DEVICE_ID_INTEL_NTB_B2B_JSF )}, {PCI_VDEVICE (INTEL ,PCI_DEVICE_ID_INTEL_NTB_B2B_SNB )},
@@ -120,7 +120,8 @@ MODULE_DEVICE_TABLE(pci, ntb_pci_tbl);* RETURNS: An appropriate -ERRNO error value on error, or zero for success. */ int ntb_register_event_callback (struct ntb_device *ndev, -void (*func)(void *handle,enum ntb_hw_event event)) +void (*func)(void *handle, +enum ntb_hw_event event)) {if (ndev->event_cb)return -EINVAL ;
@@ -715,9 +716,9 @@ static int ntb_xeon_setup(struct ntb_device *ndev) SNB_PBAR4LMT_OFFSET);/* HW errata on the Limit registers. They can only be * written when the base register is 4GB aligned and -* < 32bit. This should already be the case based on the -* driver defaults, but write the Limit registers first -* just in case. +* < 32bit. This should already be the case based on +* the driver defaults, but write the Limit registers +* first just in case. */ }else { ndev->limits.max_mw =SNB_MAX_MW ;
@@ -739,9 +740,9 @@ static int ntb_xeon_setup(struct ntb_device *ndev)writeq (0 , ndev->reg_base +SNB_PBAR4LMT_OFFSET );/* HW errata on the Limit registers. They can only be * written when the base register is 4GB aligned and -* < 32bit. This should already be the case based on the -* driver defaults, but write the Limit registers first -* just in case. +* < 32bit. This should already be the case based on +* the driver defaults, but write the Limit registers +* first just in case. */ }
@@ -803,7 +804,7 @@ static int ntb_xeon_setup(struct ntb_device *ndev) ndev->conn_type =NTB_CONN_RP ;if (xeon_errata_workaround) { -dev_err (&ndev->pdev->dev, +dev_err (&ndev->pdev->dev,"NTB-RP disabled due to hardware errata. To disregard this warning and potentially lock-up the system, add the parameter 'xeon_errata_workaround=0'.\n" );return -EINVAL ; }
drivers/ntb/ntb_hw.h +1 -1
@@ -231,7 +231,7 @@ int ntb_register_db_callback(struct ntb_device *ndev, unsigned int idx, int db_num));void ntb_unregister_db_callback (struct ntb_device *ndev,unsigned int idx);int ntb_register_event_callback (struct ntb_device *ndev, -void (*event_cb_func) (void *handle, +void (*event_cb_func)(void *handle,enum ntb_hw_event event));void ntb_unregister_event_callback (struct ntb_device *ndev);int ntb_get_max_spads (struct ntb_device *ndev);
drivers/ntb/ntb_transport.c +9 -10
@@ -106,8 +106,8 @@ struct ntb_transport_qp {struct ntb_rx_info __iomem *rx_info;struct ntb_rx_info *remote_rx_info; -void (*tx_handler) (struct ntb_transport_qp *qp,void *qp_data, -void *data,int len); +void (*tx_handler)(struct ntb_transport_qp *qp,void *qp_data, +void *data,int len);struct list_head tx_free_q;spinlock_t ntb_tx_free_q_lock;void __iomem *tx_mw;
@@ -116,8 +116,8 @@ struct ntb_transport_qp {unsigned int tx_max_entry;unsigned int tx_max_frame; -void (*rx_handler) (struct ntb_transport_qp *qp,void *qp_data, -void *data,int len); +void (*rx_handler)(struct ntb_transport_qp *qp,void *qp_data, +void *data,int len);struct list_head rx_pend_q;struct list_head rx_free_q;spinlock_t ntb_rx_pend_q_lock;
@@ -128,7 +128,7 @@ struct ntb_transport_qp {unsigned int rx_max_frame;dma_cookie_t last_cookie; -void (*event_handler) (void *data,int status); +void (*event_handler)(void *data,int status);struct delayed_work link_work;struct work_struct link_cleanup;
@@ -479,7 +479,7 @@ static void ntb_list_add(spinlock_t *lock, struct list_head *entry, }static struct ntb_queue_entry *ntb_list_rm (spinlock_t *lock, -struct list_head *list) +struct list_head *list) {struct ntb_queue_entry *entry;unsigned long flags;
@@ -838,7 +838,7 @@ static void ntb_qp_link_work(struct work_struct *work) }static int ntb_transport_init_queue (struct ntb_transport *nt, -unsigned int qp_num) +unsigned int qp_num) {struct ntb_transport_qp *qp;unsigned int num_qps_mw, tx_size;
@@ -1054,7 +1054,7 @@ static void ntb_async_rx(struct ntb_queue_entry *entry, void *offset,if (!chan) goto err; -if (len < copy_bytes) +if (len < copy_bytes) goto err_wait; device = chan->device;
@@ -1189,8 +1189,7 @@ out:return 0 ; err: -ntb_list_add (&qp->ntb_rx_pend_q_lock, &entry->entry, - &qp->rx_pend_q); +ntb_list_add (&qp->ntb_rx_pend_q_lock, &entry->entry, &qp->rx_pend_q);/* Ensure that the data is fully copied out before clearing the flag */ wmb (); hdr->flags =0 ;
include/linux/ntb.h +7 -7
@@ -50,8 +50,8 @@ struct ntb_transport_qp;struct ntb_client {struct device_driver driver; -int (*probe) (struct pci_dev *pdev); -void (*remove) (struct pci_dev *pdev); +int (*probe)(struct pci_dev *pdev); +void (*remove)(struct pci_dev *pdev); };enum {
@@ -65,11 +65,11 @@ int ntb_register_client_dev(char *device_name);void ntb_unregister_client_dev (char *device_name);struct ntb_queue_handlers { -void (*rx_handler) (struct ntb_transport_qp *qp,void *qp_data, -void *data,int len); -void (*tx_handler) (struct ntb_transport_qp *qp,void *qp_data, -void *data,int len); -void (*event_handler) (void *data,int status); +void (*rx_handler)(struct ntb_transport_qp *qp,void *qp_data, +void *data,int len); +void (*tx_handler)(struct ntb_transport_qp *qp,void *qp_data, +void *data,int len); +void (*event_handler)(void *data,int status); };unsigned char ntb_transport_qp_num (struct ntb_transport_qp *qp);
Signature · 1 line
1.8.3.2
PATCH 7/9 ntb: Use pci_msix_vec_count() to obtain number of MSI-Xs
In reply to Jon MasonFrom: Alexander Gordeev <[email protected]>
--- drivers/ntb/ntb_hw.c | 15 ++++----------- drivers/ntb/ntb_hw.h | 2 -- 2 files changed, 4 insertions(+), 13 deletions(-)
drivers/ntb/ntb_hw.c +4 -11
@@ -1086,19 +1086,12 @@ static int ntb_setup_msix(struct ntb_device *ndev)struct msix_entry *msix;int msix_entries;int rc, i; -u16 val; -if (!pdev->msix_cap) { - rc = -EIO ; - goto err; - } - - rc =pci_read_config_word (pdev, pdev->msix_cap +PCI_MSIX_FLAGS , &val); -if (rc) + msix_entries =pci_msix_vec_count (pdev); +if (msix_entries <0 ) { + rc = msix_entries; goto err; - - msix_entries =msix_table_size (val); -if (msix_entries > ndev->limits.msix_cnt) { + }else if (msix_entries > ndev->limits.msix_cnt) { rc = -EINVAL ; goto err; }
drivers/ntb/ntb_hw.h +0 -2
@@ -61,8 +61,6 @@#define PCI_DEVICE_ID_INTEL_NTB_SS_HSX 0x2F0F#define PCI_DEVICE_ID_INTEL_NTB_B2B_BWD 0x0C4E -#define msix_table_size (control) ((control & PCI_MSIX_FLAGS_QSIZE)+1) -#ifndef readqstatic inline u64 readq (void __iomem *addr) {
Signature · 1 line
1.8.3.2
PATCH 8/9 ntb: Split ntb_setup_msix() into separate BWD/SNB routines
In reply to Jon MasonFrom: Alexander Gordeev <[email protected]>
This is an cleanup effort to make ntb_setup_msix() more readable - use ntb_setup_bwd_msix() to init MSI-Xs on BWD hardware and ntb_setup_snb_msix() - on SNB hardware.
Function ntb_setup_snb_msix() also initializes MSI-Xs the way it should has been done - looping pci_enable_msix() until success or failure.
--- drivers/ntb/ntb_hw.c | 167 +++++++++++++++++++++++++++++++-------------------- 1 file changed, 102 insertions(+), 65 deletions(-)
drivers/ntb/ntb_hw.c +102 -65
@@ -1080,10 +1080,106 @@ static irqreturn_t ntb_interrupt(int irq, void *dev)return IRQ_HANDLED ; } -static int ntb_setup_msix (struct ntb_device *ndev) +static int ntb_setup_snb_msix (struct ntb_device *ndev,int msix_entries) {struct pci_dev *pdev = ndev->pdev;struct msix_entry *msix; +int rc, i; + +if (msix_entries < ndev->limits.msix_cnt) +return -ENOSPC ; + + rc =pci_enable_msix (pdev, ndev->msix_entries, msix_entries); +if (rc <0 ) +return rc; +else if (rc >0 ) +return -ENOSPC ; + +for (i =0 ; i < msix_entries; i++) { + msix = &ndev->msix_entries[i]; +WARN_ON (!msix->vector); + +if (i == msix_entries -1 ) { + rc =request_irq (msix->vector, + xeon_event_msix_irq,0 , +"ntb-event-msix" , ndev); +if (rc) + goto err; + }else { + rc =request_irq (msix->vector, + xeon_callback_msix_irq,0 , +"ntb-callback-msix" , + &ndev->db_cb[i]); +if (rc) + goto err; + } + } + + ndev->num_msix = msix_entries; + ndev->max_cbs = msix_entries -1 ; + +return 0 ; + +err: +while (--i >=0 ) { +/* Code never reaches here for entry nr 'ndev->num_msix - 1' */ + msix = &ndev->msix_entries[i]; +free_irq (msix->vector, &ndev->db_cb[i]); + } + +pci_disable_msix (pdev); + ndev->num_msix =0 ; + +return rc; +} + +static int ntb_setup_bwd_msix (struct ntb_device *ndev,int msix_entries) +{ +struct pci_dev *pdev = ndev->pdev; +struct msix_entry *msix; +int rc, i; + +retry: + rc =pci_enable_msix (pdev, ndev->msix_entries, msix_entries); +if (rc <0 ) +return rc; +else if (rc >0 ) { +dev_warn (&pdev->dev, +"Only %d MSI-X vectors. " +"Limiting the number of queues to that number.\n" , + rc); + msix_entries = rc; + goto retry; + } + +for (i =0 ; i < msix_entries; i++) { + msix = &ndev->msix_entries[i]; +WARN_ON (!msix->vector); + + rc =request_irq (msix->vector, bwd_callback_msix_irq,0 , +"ntb-callback-msix" , &ndev->db_cb[i]); +if (rc) + goto err; + } + + ndev->num_msix = msix_entries; + ndev->max_cbs = msix_entries; + +return 0 ; + +err: +while (--i >=0 ) +free_irq (msix->vector, &ndev->db_cb[i]); + +pci_disable_msix (pdev); + ndev->num_msix =0 ; + +return rc; +} + +static int ntb_setup_msix (struct ntb_device *ndev) +{ +struct pci_dev *pdev = ndev->pdev;int msix_entries;int rc, i;
@@ -1106,78 +1202,19 @@ static int ntb_setup_msix(struct ntb_device *ndev)for (i =0 ; i < msix_entries; i++) ndev->msix_entries[i].entry = i; - rc =pci_enable_msix (pdev, ndev->msix_entries, msix_entries); -if (rc <0 ) - goto err1; -if (rc >0 ) { -/* On SNB, the link interrupt is always tied to 4th vector. If -* we can't get all 4, then we can't use MSI-X. -*/ -if (ndev->hw_type !=BWD_HW ) { - rc = -EIO ; - goto err1; - } - -dev_warn (&pdev->dev, -"Only %d MSI-X vectors. Limiting the number of queues to that number.\n" , - rc); - msix_entries = rc; - - rc =pci_enable_msix (pdev, ndev->msix_entries, msix_entries); -if (rc) - goto err1; - } - -for (i =0 ; i < msix_entries; i++) { - msix = &ndev->msix_entries[i]; -WARN_ON (!msix->vector); - -/* Use the last MSI-X vector for Link status */ -if (ndev->hw_type ==BWD_HW ) { - rc =request_irq (msix->vector, bwd_callback_msix_irq,0 , -"ntb-callback-msix" , &ndev->db_cb[i]); -if (rc) - goto err2; - }else { -if (i == msix_entries -1 ) { - rc =request_irq (msix->vector, - xeon_event_msix_irq,0 , -"ntb-event-msix" , ndev); -if (rc) - goto err2; - }else { - rc =request_irq (msix->vector, - xeon_callback_msix_irq,0 , -"ntb-callback-msix" , - &ndev->db_cb[i]); -if (rc) - goto err2; - } - } - } - - ndev->num_msix = msix_entries;if (ndev->hw_type ==BWD_HW ) - ndev->max_cbs = msix_entries; + rc =ntb_setup_bwd_msix (ndev, msix_entries);else - ndev->max_cbs = msix_entries -1 ; + rc =ntb_setup_snb_msix (ndev, msix_entries); +if (rc) + goto err1;return 0 ; -err2: -while (--i >=0 ) { - msix = &ndev->msix_entries[i]; -if (ndev->hw_type !=BWD_HW && i == ndev->num_msix -1 ) -free_irq (msix->vector, ndev); -else -free_irq (msix->vector, &ndev->db_cb[i]); - } -pci_disable_msix (pdev); err1:kfree (ndev->msix_entries); -dev_err (&pdev->dev,"Error allocating MSI-X interrupt\n" ); err: - ndev->num_msix =0 ; +dev_err (&pdev->dev,"Error allocating MSI-X interrupt\n" );return rc; }
Signature · 1 line
1.8.3.2
PATCH 9/9 ntb: Use pci_enable_msix_range() instead of pci_enable_msix()
In reply to Jon MasonFrom: Alexander Gordeev <[email protected]>
As result of deprecation of MSI-X/MSI enablement functions pci_enable_msix() and pci_enable_msi_block() all drivers using these two interfaces need to be updated to use the new pci_enable_msi_range() or pci_enable_msi_exact() and pci_enable_msix_range() or pci_enable_msix_exact() interfaces.
--- drivers/ntb/ntb_hw.c | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-)
drivers/ntb/ntb_hw.c +5 -15
@@ -1089,11 +1089,9 @@ static int ntb_setup_snb_msix(struct ntb_device *ndev, int msix_entries)if (msix_entries < ndev->limits.msix_cnt)return -ENOSPC ; - rc =pci_enable_msix (pdev, ndev->msix_entries, msix_entries); + rc =pci_enable_msix_exact (pdev, ndev->msix_entries, msix_entries);if (rc <0 )return rc; -else if (rc >0 ) -return -ENOSPC ;for (i =0 ; i < msix_entries; i++) { msix = &ndev->msix_entries[i];
@@ -1139,18 +1137,10 @@ static int ntb_setup_bwd_msix(struct ntb_device *ndev, int msix_entries)struct msix_entry *msix;int rc, i; -retry: - rc =pci_enable_msix (pdev, ndev->msix_entries, msix_entries); -if (rc <0 ) -return rc; -else if (rc >0 ) { -dev_warn (&pdev->dev, -"Only %d MSI-X vectors. " -"Limiting the number of queues to that number.\n" , - rc); - msix_entries = rc; - goto retry; - } + msix_entries =pci_enable_msix_range (pdev, ndev->msix_entries, +1 , msix_entries); +if (msix_entries <0 ) +return msix_entries;for (i =0 ; i < msix_entries; i++) { msix = &ndev->msix_entries[i];
Signature · 1 line
1.8.3.2