* [PATCH v2 net-next 11/12] be2net: define macro for_all_tx_queues_on_eq()
From: Sathya Perla @ 2014-09-02 4:26 UTC (permalink / raw)
To: netdev
In-Reply-To: <1409632017-15655-1-git-send-email-sathya.perla@emulex.com>
Replace the for() loop that traverses all the TX queues on an EQ
with the macro for_all_tx_queues_on_eq(). With this expalnatory
name, the one line comment is not required anymore.
Signed-off-by: Sathya Perla <sathya.perla@emulex.com>
---
drivers/net/ethernet/emulex/benet/be.h | 4 ++++
drivers/net/ethernet/emulex/benet/be_main.c | 6 +++---
2 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h
index d952ca2..a9f239a 100644
--- a/drivers/net/ethernet/emulex/benet/be.h
+++ b/drivers/net/ethernet/emulex/benet/be.h
@@ -621,6 +621,10 @@ extern const struct ethtool_ops be_ethtool_ops;
for (i = eqo->idx, rxo = &adapter->rx_obj[i]; i < adapter->num_rx_qs;\
i += adapter->num_evt_qs, rxo += adapter->num_evt_qs)
+#define for_all_tx_queues_on_eq(adapter, eqo, txo, i) \
+ for (i = eqo->idx, txo = &adapter->tx_obj[i]; i < adapter->num_tx_qs;\
+ i += adapter->num_evt_qs, txo += adapter->num_evt_qs)
+
#define is_mcc_eqo(eqo) (eqo->idx == 0)
#define mcc_eqo(adapter) (&adapter->eq_obj[0])
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
index 53727ad..f3235d1 100644
--- a/drivers/net/ethernet/emulex/benet/be_main.c
+++ b/drivers/net/ethernet/emulex/benet/be_main.c
@@ -2503,12 +2503,12 @@ int be_poll(struct napi_struct *napi, int budget)
struct be_adapter *adapter = eqo->adapter;
int max_work = 0, work, i, num_evts;
struct be_rx_obj *rxo;
+ struct be_tx_obj *txo;
num_evts = events_get(eqo);
- /* Process all TXQs serviced by this EQ */
- for (i = eqo->idx; i < adapter->num_tx_qs; i += adapter->num_evt_qs)
- be_process_tx(adapter, &adapter->tx_obj[i], i);
+ for_all_tx_queues_on_eq(adapter, eqo, txo, i)
+ be_process_tx(adapter, txo, i);
if (be_lock_napi(eqo)) {
/* This loop will iterate twice for EQ0 in which
--
1.7.1
^ permalink raw reply related
* [PATCH v2 net-next 12/12] be2net: query max_tx_qs for BE3 super-nic profile from FW
From: Sathya Perla @ 2014-09-02 4:26 UTC (permalink / raw)
To: netdev
In-Reply-To: <1409632017-15655-1-git-send-email-sathya.perla@emulex.com>
From: Suresh Reddy <Suresh.Reddy@emulex.com>
In the BE3 super-nic profile, the max_tx_qs value can vary for each function.
So the driver needs to query this value from FW instead of using the
pre-defined constant BE3_MAX_TX_QS.
Signed-off-by: Suresh Reddy <Suresh.Reddy@emulex.com>
Signed-off-by: Sathya Perla <sathya.perla@emulex.com>
---
drivers/net/ethernet/emulex/benet/be_main.c | 14 ++++++++++++--
1 files changed, 12 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
index f3235d1..9eaab4e 100644
--- a/drivers/net/ethernet/emulex/benet/be_main.c
+++ b/drivers/net/ethernet/emulex/benet/be_main.c
@@ -3324,10 +3324,20 @@ static void BEx_get_resources(struct be_adapter *adapter,
*/
if (BE2_chip(adapter) || use_sriov || (adapter->port_num > 1) ||
!be_physfn(adapter) || (be_is_mc(adapter) &&
- !(adapter->function_caps & BE_FUNCTION_CAPS_RSS)))
+ !(adapter->function_caps & BE_FUNCTION_CAPS_RSS))) {
res->max_tx_qs = 1;
- else
+ } else if (adapter->function_caps & BE_FUNCTION_CAPS_SUPER_NIC) {
+ struct be_resources super_nic_res = {0};
+
+ /* On a SuperNIC profile, the driver needs to use the
+ * GET_PROFILE_CONFIG cmd to query the per-function TXQ limits
+ */
+ be_cmd_get_profile_config(adapter, &super_nic_res, 0);
+ /* Some old versions of BE3 FW don't report max_tx_qs value */
+ res->max_tx_qs = super_nic_res.max_tx_qs ? : BE3_MAX_TX_QS;
+ } else {
res->max_tx_qs = BE3_MAX_TX_QS;
+ }
if ((adapter->function_caps & BE_FUNCTION_CAPS_RSS) &&
!use_sriov && be_physfn(adapter))
--
1.7.1
^ permalink raw reply related
* [PATCH v2 net-next 09/12] be2net: make be_cmd_get_regs() return a status
From: Sathya Perla @ 2014-09-02 4:26 UTC (permalink / raw)
To: netdev
In-Reply-To: <1409632017-15655-1-git-send-email-sathya.perla@emulex.com>
From: Vasundhara Volam <vasundhara.volam@emulex.com>
There are a few failure cases in be_cmd_get_regs() that ideally must return
an error value. This style is used across all the routines in be_cmds.c with
this routine being an exception. This patch fixes this.
Signed-off-by: Vasundhara Volam <vasundhara.volam@emulex.com>
Signed-off-by: Sathya Perla <sathya.perla@emulex.com>
---
drivers/net/ethernet/emulex/benet/be_cmds.c | 10 +++++-----
drivers/net/ethernet/emulex/benet/be_cmds.h | 2 +-
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c
index ca9ec18..5be100d 100644
--- a/drivers/net/ethernet/emulex/benet/be_cmds.c
+++ b/drivers/net/ethernet/emulex/benet/be_cmds.c
@@ -1681,17 +1681,17 @@ err:
return status;
}
-void be_cmd_get_regs(struct be_adapter *adapter, u32 buf_len, void *buf)
+int be_cmd_get_regs(struct be_adapter *adapter, u32 buf_len, void *buf)
{
struct be_dma_mem get_fat_cmd;
struct be_mcc_wrb *wrb;
struct be_cmd_req_get_fat *req;
u32 offset = 0, total_size, buf_size,
log_offset = sizeof(u32), payload_len;
- int status;
+ int status = 0;
if (buf_len == 0)
- return;
+ return -EIO;
total_size = buf_len;
@@ -1700,10 +1700,9 @@ void be_cmd_get_regs(struct be_adapter *adapter, u32 buf_len, void *buf)
get_fat_cmd.size,
&get_fat_cmd.dma);
if (!get_fat_cmd.va) {
- status = -ENOMEM;
dev_err(&adapter->pdev->dev,
"Memory allocation failure while retrieving FAT data\n");
- return;
+ return -ENOMEM;
}
spin_lock_bh(&adapter->mcc_lock);
@@ -1746,6 +1745,7 @@ err:
pci_free_consistent(adapter->pdev, get_fat_cmd.size,
get_fat_cmd.va, get_fat_cmd.dma);
spin_unlock_bh(&adapter->mcc_lock);
+ return status;
}
/* Uses synchronous mcc */
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.h b/drivers/net/ethernet/emulex/benet/be_cmds.h
index 5284b82..0e11868 100644
--- a/drivers/net/ethernet/emulex/benet/be_cmds.h
+++ b/drivers/net/ethernet/emulex/benet/be_cmds.h
@@ -2101,7 +2101,7 @@ int be_cmd_get_die_temperature(struct be_adapter *adapter);
int be_cmd_get_cntl_attributes(struct be_adapter *adapter);
int be_cmd_req_native_mode(struct be_adapter *adapter);
int be_cmd_get_reg_len(struct be_adapter *adapter, u32 *log_size);
-void be_cmd_get_regs(struct be_adapter *adapter, u32 buf_len, void *buf);
+int be_cmd_get_regs(struct be_adapter *adapter, u32 buf_len, void *buf);
int be_cmd_get_fn_privileges(struct be_adapter *adapter, u32 *privilege,
u32 domain);
int be_cmd_set_fn_privileges(struct be_adapter *adapter, u32 privileges,
--
1.7.1
^ permalink raw reply related
* [PATCH v2 net-next 07/12] be2net: remove unncessary gotos
From: Sathya Perla @ 2014-09-02 4:26 UTC (permalink / raw)
To: netdev
In-Reply-To: <1409632017-15655-1-git-send-email-sathya.perla@emulex.com>
From: Kalesh AP <kalesh.purayil@emulex.com>
In cases where there is no extra code to handle an error, this patch replaces
gotos with a direct return statement.
Signed-off-by: Kalesh AP <kalesh.purayil@emulex.com>
Signed-off-by: Sathya Perla <sathya.perla@emulex.com>
---
drivers/net/ethernet/emulex/benet/be_main.c | 16 ++++++----------
1 files changed, 6 insertions(+), 10 deletions(-)
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
index 7e89e5b..cdad8bc 100644
--- a/drivers/net/ethernet/emulex/benet/be_main.c
+++ b/drivers/net/ethernet/emulex/benet/be_main.c
@@ -4090,18 +4090,15 @@ static int lancer_fw_download(struct be_adapter *adapter,
if (!IS_ALIGNED(fw->size, sizeof(u32))) {
dev_err(dev, "FW image size should be multiple of 4\n");
- status = -EINVAL;
- goto lancer_fw_exit;
+ return -EINVAL;
}
flash_cmd.size = sizeof(struct lancer_cmd_req_write_object)
+ LANCER_FW_DOWNLOAD_CHUNK;
flash_cmd.va = dma_alloc_coherent(dev, flash_cmd.size,
&flash_cmd.dma, GFP_KERNEL);
- if (!flash_cmd.va) {
- status = -ENOMEM;
- goto lancer_fw_exit;
- }
+ if (!flash_cmd.va)
+ return -ENOMEM;
dest_image_ptr = flash_cmd.va +
sizeof(struct lancer_cmd_req_write_object);
@@ -4139,7 +4136,7 @@ static int lancer_fw_download(struct be_adapter *adapter,
dma_free_coherent(dev, flash_cmd.size, flash_cmd.va, flash_cmd.dma);
if (status) {
dev_err(dev, "Firmware load error\n");
- goto lancer_fw_exit;
+ return be_cmd_status(status);
}
dev_info(dev, "Firmware flashed successfully\n");
@@ -4151,13 +4148,12 @@ static int lancer_fw_download(struct be_adapter *adapter,
if (status) {
dev_err(dev, "Adapter busy, could not reset FW\n");
dev_err(dev, "Reboot server to activate new FW\n");
- goto lancer_fw_exit;
}
} else if (change_status != LANCER_NO_RESET_NEEDED) {
dev_info(dev, "Reboot server to activate new FW\n");
}
-lancer_fw_exit:
- return status;
+
+ return 0;
}
#define UFI_TYPE2 2
--
1.7.1
^ permalink raw reply related
* [PATCH v2 net-next 05/12] be2net: Add a dma_mapping_error counter in ethtool
From: Sathya Perla @ 2014-09-02 4:26 UTC (permalink / raw)
To: netdev
In-Reply-To: <1409632017-15655-1-git-send-email-sathya.perla@emulex.com>
From: Vasundhara Volam <vasundhara.volam@emulex.com>
Add a dma_mapping_error counter to count the number of packets dropped
due to DMA mapping errors.
Signed-off-by: Vasundhara Volam <vasundhara.volam@emulex.com>
Signed-off-by: Sathya Perla <sathya.perla@emulex.com>
---
drivers/net/ethernet/emulex/benet/be.h | 1 +
drivers/net/ethernet/emulex/benet/be_ethtool.c | 2 ++
drivers/net/ethernet/emulex/benet/be_main.c | 3 ++-
3 files changed, 5 insertions(+), 1 deletions(-)
diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h
index d491ac6..069bdda 100644
--- a/drivers/net/ethernet/emulex/benet/be.h
+++ b/drivers/net/ethernet/emulex/benet/be.h
@@ -323,6 +323,7 @@ struct be_rx_obj {
struct be_drv_stats {
u32 be_on_die_temperature;
u32 eth_red_drops;
+ u32 dma_map_errors;
u32 rx_drops_no_pbuf;
u32 rx_drops_no_txpb;
u32 rx_drops_no_erx_descr;
diff --git a/drivers/net/ethernet/emulex/benet/be_ethtool.c b/drivers/net/ethernet/emulex/benet/be_ethtool.c
index 3a7ade4..2fd3826 100644
--- a/drivers/net/ethernet/emulex/benet/be_ethtool.c
+++ b/drivers/net/ethernet/emulex/benet/be_ethtool.c
@@ -119,6 +119,8 @@ static const struct be_ethtool_stat et_stats[] = {
* is more than 9018 bytes
*/
{DRVSTAT_INFO(rx_drops_mtu)},
+ /* Number of dma mapping errors */
+ {DRVSTAT_INFO(dma_map_errors)},
/* Number of packets dropped due to random early drop function */
{DRVSTAT_INFO(eth_red_drops)},
{DRVSTAT_INFO(be_on_die_temperature)},
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
index e9658f7..c95998f 100644
--- a/drivers/net/ethernet/emulex/benet/be_main.c
+++ b/drivers/net/ethernet/emulex/benet/be_main.c
@@ -849,6 +849,7 @@ dma_err:
unmap_tx_frag(dev, wrb, map_single);
map_single = false;
copied -= wrb->frag_len;
+ adapter->drv_stats.dma_map_errors++;
queue_head_inc(txq);
}
return 0;
@@ -1877,7 +1878,7 @@ static void be_post_rx_frags(struct be_rx_obj *rxo, gfp_t gfp)
if (dma_mapping_error(dev, page_dmaaddr)) {
put_page(pagep);
pagep = NULL;
- rx_stats(rxo)->rx_post_fail++;
+ adapter->drv_stats.dma_map_errors++;
break;
}
page_offset = 0;
--
1.7.1
^ permalink raw reply related
* [PATCH v2 net-next 03/12] be2net: add a description for counter rx_input_fifo_overflow_drop
From: Sathya Perla @ 2014-09-02 4:26 UTC (permalink / raw)
To: netdev
In-Reply-To: <1409632017-15655-1-git-send-email-sathya.perla@emulex.com>
Signed-off-by: Sathya Perla <sathya.perla@emulex.com>
---
drivers/net/ethernet/emulex/benet/be_ethtool.c | 5 +++++
1 files changed, 5 insertions(+), 0 deletions(-)
diff --git a/drivers/net/ethernet/emulex/benet/be_ethtool.c b/drivers/net/ethernet/emulex/benet/be_ethtool.c
index 0cd3311..d8d7a4a 100644
--- a/drivers/net/ethernet/emulex/benet/be_ethtool.c
+++ b/drivers/net/ethernet/emulex/benet/be_ethtool.c
@@ -78,6 +78,11 @@ static const struct be_ethtool_stat et_stats[] = {
* fifo must never overflow.
*/
{DRVSTAT_INFO(rxpp_fifo_overflow_drop)},
+ /* Received packets dropped when the RX block runs out of space in
+ * one of its input FIFOs. This could happen due a long burst of
+ * minimum-sized (64b) frames in the receive path.
+ * This counter may also be erroneously incremented rarely.
+ */
{DRVSTAT_INFO(rx_input_fifo_overflow_drop)},
{DRVSTAT_INFO(rx_ip_checksum_errs)},
{DRVSTAT_INFO(rx_tcp_checksum_errs)},
--
1.7.1
^ permalink raw reply related
* [PATCH v2 net-next 01/12] be2net: add a few log messages
From: Sathya Perla @ 2014-09-02 4:26 UTC (permalink / raw)
To: netdev
In-Reply-To: <1409632017-15655-1-git-send-email-sathya.perla@emulex.com>
This patch adds the following log messages to help debugging
failure cases:
1) log FW version number: this is useful when driver initialization
fails and the FW version number cannot be queried via ethtool
2) per function resource limits for BEx chips: these values are
currently being printed only for Skyhawk and Lancer
3) PCI BAR mapping failure
4) function_mode/caps queried from FW: this helps catch any FW bugs
that could advertise wrong capabilities to the driver
Signed-off-by: Sathya Perla <sathya.perla@emulex.com>
---
drivers/net/ethernet/emulex/benet/be_cmds.c | 4 ++++
drivers/net/ethernet/emulex/benet/be_main.c | 20 ++++++++++++--------
2 files changed, 16 insertions(+), 8 deletions(-)
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c
index 4370ec1..ca9ec18 100644
--- a/drivers/net/ethernet/emulex/benet/be_cmds.c
+++ b/drivers/net/ethernet/emulex/benet/be_cmds.c
@@ -1771,6 +1771,7 @@ int be_cmd_get_fw_ver(struct be_adapter *adapter)
status = be_mcc_notify_wait(adapter);
if (!status) {
struct be_cmd_resp_get_fw_version *resp = embedded_payload(wrb);
+
strcpy(adapter->fw_ver, resp->firmware_version_string);
strcpy(adapter->fw_on_flash, resp->fw_on_flash_version_string);
}
@@ -2018,6 +2019,9 @@ int be_cmd_query_fw_cfg(struct be_adapter *adapter)
adapter->function_mode = le32_to_cpu(resp->function_mode);
adapter->function_caps = le32_to_cpu(resp->function_caps);
adapter->asic_rev = le32_to_cpu(resp->asic_revision) & 0xFF;
+ dev_info(&adapter->pdev->dev,
+ "FW config: function_mode=0x%x, function_caps=0x%x\n",
+ adapter->function_mode, adapter->function_caps);
}
mutex_unlock(&adapter->mbox_lock);
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
index 93ff8ef..3d33049 100644
--- a/drivers/net/ethernet/emulex/benet/be_main.c
+++ b/drivers/net/ethernet/emulex/benet/be_main.c
@@ -3413,16 +3413,16 @@ static int be_get_resources(struct be_adapter *adapter)
if (be_roce_supported(adapter))
res.max_evt_qs /= 2;
adapter->res = res;
-
- dev_info(dev, "Max: txqs %d, rxqs %d, rss %d, eqs %d, vfs %d\n",
- be_max_txqs(adapter), be_max_rxqs(adapter),
- be_max_rss(adapter), be_max_eqs(adapter),
- be_max_vfs(adapter));
- dev_info(dev, "Max: uc-macs %d, mc-macs %d, vlans %d\n",
- be_max_uc(adapter), be_max_mc(adapter),
- be_max_vlans(adapter));
}
+ dev_info(dev, "Max: txqs %d, rxqs %d, rss %d, eqs %d, vfs %d\n",
+ be_max_txqs(adapter), be_max_rxqs(adapter),
+ be_max_rss(adapter), be_max_eqs(adapter),
+ be_max_vfs(adapter));
+ dev_info(dev, "Max: uc-macs %d, mc-macs %d, vlans %d\n",
+ be_max_uc(adapter), be_max_mc(adapter),
+ be_max_vlans(adapter));
+
return 0;
}
@@ -3633,6 +3633,7 @@ static int be_setup(struct be_adapter *adapter)
goto err;
be_cmd_get_fw_ver(adapter);
+ dev_info(dev, "FW version is %s\n", adapter->fw_ver);
if (BE2_chip(adapter) && fw_major_num(adapter->fw_ver) < 4) {
dev_err(dev, "Firmware on card is old(%s), IRQs may not work.",
@@ -4506,6 +4507,7 @@ static int be_map_pci_bars(struct be_adapter *adapter)
return 0;
pci_map_err:
+ dev_err(&adapter->pdev->dev, "Error in mapping PCI BARs\n");
be_unmap_pci_bars(adapter);
return -ENOMEM;
}
@@ -4822,6 +4824,8 @@ static int be_probe(struct pci_dev *pdev, const struct pci_device_id *pdev_id)
struct net_device *netdev;
char port_name;
+ dev_info(&pdev->dev, "%s version is %s\n", DRV_NAME, DRV_VER);
+
status = pci_enable_device(pdev);
if (status)
goto do_none;
--
1.7.1
^ permalink raw reply related
* [PATCH v2 net-next 10/12] be2net: get rid of TX budget
From: Sathya Perla @ 2014-09-02 4:26 UTC (permalink / raw)
To: netdev
In-Reply-To: <1409632017-15655-1-git-send-email-sathya.perla@emulex.com>
Enforcing a budget on the TX completion processing in NAPI doesn't
benefit performance in anyway. Just get rid of it.
Signed-off-by: Sathya Perla <sathya.perla@emulex.com>
---
drivers/net/ethernet/emulex/benet/be.h | 2 -
drivers/net/ethernet/emulex/benet/be_main.c | 30 +++++++++-----------------
2 files changed, 11 insertions(+), 21 deletions(-)
diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h
index 5ccfce7..d952ca2 100644
--- a/drivers/net/ethernet/emulex/benet/be.h
+++ b/drivers/net/ethernet/emulex/benet/be.h
@@ -114,7 +114,6 @@ static inline char *nic_name(struct pci_dev *pdev)
#define MAX_ROCE_EQS 5
#define MAX_MSIX_VECTORS 32
#define MIN_MSIX_VECTORS 1
-#define BE_TX_BUDGET 256
#define BE_NAPI_WEIGHT 64
#define MAX_RX_POST BE_NAPI_WEIGHT /* Frags posted at a time */
#define RX_FRAGS_REFILL_WM (RX_Q_LEN - MAX_RX_POST)
@@ -200,7 +199,6 @@ struct be_eq_obj {
u8 idx; /* array index */
u8 msix_idx;
- u16 tx_budget;
u16 spurious_intr;
struct napi_struct napi;
struct be_adapter *adapter;
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
index 04a8092..53727ad 100644
--- a/drivers/net/ethernet/emulex/benet/be_main.c
+++ b/drivers/net/ethernet/emulex/benet/be_main.c
@@ -2143,7 +2143,6 @@ static int be_evt_queues_create(struct be_adapter *adapter)
napi_hash_add(&eqo->napi);
aic = &adapter->aic_obj[i];
eqo->adapter = adapter;
- eqo->tx_budget = BE_TX_BUDGET;
eqo->idx = i;
aic->max_eqd = BE_MAX_EQD;
aic->enable = true;
@@ -2459,20 +2458,19 @@ static inline void lancer_update_tx_err(struct be_tx_obj *txo, u32 status)
}
}
-static bool be_process_tx(struct be_adapter *adapter, struct be_tx_obj *txo,
- int budget, int idx)
+static void be_process_tx(struct be_adapter *adapter, struct be_tx_obj *txo,
+ int idx)
{
struct be_eth_tx_compl *txcp;
- int num_wrbs = 0, work_done;
+ int num_wrbs = 0, work_done = 0;
u32 compl_status;
+ u16 last_idx;
+
+ while ((txcp = be_tx_compl_get(&txo->cq))) {
+ last_idx = GET_TX_COMPL_BITS(wrb_index, txcp);
+ num_wrbs += be_tx_compl_process(adapter, txo, last_idx);
+ work_done++;
- for (work_done = 0; work_done < budget; work_done++) {
- txcp = be_tx_compl_get(&txo->cq);
- if (!txcp)
- break;
- num_wrbs += be_tx_compl_process(adapter, txo,
- GET_TX_COMPL_BITS(wrb_index,
- txcp));
compl_status = GET_TX_COMPL_BITS(status, txcp);
if (compl_status) {
if (lancer_chip(adapter))
@@ -2497,7 +2495,6 @@ static bool be_process_tx(struct be_adapter *adapter, struct be_tx_obj *txo,
tx_stats(txo)->tx_compl += work_done;
u64_stats_update_end(&tx_stats(txo)->sync_compl);
}
- return (work_done < budget); /* Done */
}
int be_poll(struct napi_struct *napi, int budget)
@@ -2506,17 +2503,12 @@ int be_poll(struct napi_struct *napi, int budget)
struct be_adapter *adapter = eqo->adapter;
int max_work = 0, work, i, num_evts;
struct be_rx_obj *rxo;
- bool tx_done;
num_evts = events_get(eqo);
/* Process all TXQs serviced by this EQ */
- for (i = eqo->idx; i < adapter->num_tx_qs; i += adapter->num_evt_qs) {
- tx_done = be_process_tx(adapter, &adapter->tx_obj[i],
- eqo->tx_budget, i);
- if (!tx_done)
- max_work = budget;
- }
+ for (i = eqo->idx; i < adapter->num_tx_qs; i += adapter->num_evt_qs)
+ be_process_tx(adapter, &adapter->tx_obj[i], i);
if (be_lock_napi(eqo)) {
/* This loop will iterate twice for EQ0 in which
--
1.7.1
^ permalink raw reply related
* [PATCH v2 net-next 08/12] be2net: define BE_MAX_MTU
From: Sathya Perla @ 2014-09-02 4:26 UTC (permalink / raw)
To: netdev
In-Reply-To: <1409632017-15655-1-git-send-email-sathya.perla@emulex.com>
From: Kalesh AP <kalesh.purayil@emulex.com>
This patch defines a new macro BE_MAX_MTU to make the code in be_change_mtu()
more readable.
Signed-off-by: Kalesh AP <kalesh.purayil@emulex.com>
Signed-off-by: Sathya Perla <sathya.perla@emulex.com>
---
drivers/net/ethernet/emulex/benet/be.h | 2 ++
drivers/net/ethernet/emulex/benet/be_main.c | 14 +++++++-------
2 files changed, 9 insertions(+), 7 deletions(-)
diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h
index 069bdda..5ccfce7 100644
--- a/drivers/net/ethernet/emulex/benet/be.h
+++ b/drivers/net/ethernet/emulex/benet/be.h
@@ -86,6 +86,8 @@ static inline char *nic_name(struct pci_dev *pdev)
#define BE_MAX_JUMBO_FRAME_SIZE 9018
#define BE_MIN_MTU 256
+#define BE_MAX_MTU (BE_MAX_JUMBO_FRAME_SIZE - \
+ (ETH_HLEN + ETH_FCS_LEN))
#define BE_NUM_VLANS_SUPPORTED 64
#define BE_MAX_EQD 128u
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
index cdad8bc..04a8092 100644
--- a/drivers/net/ethernet/emulex/benet/be_main.c
+++ b/drivers/net/ethernet/emulex/benet/be_main.c
@@ -1073,15 +1073,15 @@ static netdev_tx_t be_xmit(struct sk_buff *skb, struct net_device *netdev)
static int be_change_mtu(struct net_device *netdev, int new_mtu)
{
struct be_adapter *adapter = netdev_priv(netdev);
- if (new_mtu < BE_MIN_MTU ||
- new_mtu > (BE_MAX_JUMBO_FRAME_SIZE - (ETH_HLEN + ETH_FCS_LEN))) {
- dev_info(&adapter->pdev->dev,
- "MTU must be between %d and %d bytes\n",
- BE_MIN_MTU,
- (BE_MAX_JUMBO_FRAME_SIZE - (ETH_HLEN + ETH_FCS_LEN)));
+ struct device *dev = &adapter->pdev->dev;
+
+ if (new_mtu < BE_MIN_MTU || new_mtu > BE_MAX_MTU) {
+ dev_info(dev, "MTU must be between %d and %d bytes\n",
+ BE_MIN_MTU, BE_MAX_MTU);
return -EINVAL;
}
- dev_info(&adapter->pdev->dev, "MTU changed from %d to %d bytes\n",
+
+ dev_info(dev, "MTU changed from %d to %d bytes\n",
netdev->mtu, new_mtu);
netdev->mtu = new_mtu;
return 0;
--
1.7.1
^ permalink raw reply related
* [PATCH v2 net-next 04/12] be2net: Add TX completion error statistics in ethtool
From: Sathya Perla @ 2014-09-02 4:26 UTC (permalink / raw)
To: netdev
In-Reply-To: <1409632017-15655-1-git-send-email-sathya.perla@emulex.com>
From: Kalesh AP <kalesh.purayil@emulex.com>
HW reports TX completion errors in TX completion. This patch adds these
counters to ethtool statistics.
Signed-off-by: Kalesh AP <kalesh.purayil@emulex.com>
Signed-off-by: Sathya Perla <sathya.perla@emulex.com>
---
drivers/net/ethernet/emulex/benet/be.h | 7 ++++
drivers/net/ethernet/emulex/benet/be_ethtool.c | 28 +++++++++++++++
drivers/net/ethernet/emulex/benet/be_hw.h | 12 ++++++
drivers/net/ethernet/emulex/benet/be_main.c | 45 ++++++++++++++++++++++++
4 files changed, 92 insertions(+), 0 deletions(-)
diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h
index d9cd885..d491ac6 100644
--- a/drivers/net/ethernet/emulex/benet/be.h
+++ b/drivers/net/ethernet/emulex/benet/be.h
@@ -248,6 +248,13 @@ struct be_tx_stats {
ulong tx_jiffies;
u32 tx_stops;
u32 tx_drv_drops; /* pkts dropped by driver */
+ /* the error counters are described in be_ethtool.c */
+ u32 tx_hdr_parse_err;
+ u32 tx_dma_err;
+ u32 tx_tso_err;
+ u32 tx_spoof_check_err;
+ u32 tx_qinq_err;
+ u32 tx_internal_parity_err;
struct u64_stats_sync sync;
struct u64_stats_sync sync_compl;
};
diff --git a/drivers/net/ethernet/emulex/benet/be_ethtool.c b/drivers/net/ethernet/emulex/benet/be_ethtool.c
index d8d7a4a..3a7ade4 100644
--- a/drivers/net/ethernet/emulex/benet/be_ethtool.c
+++ b/drivers/net/ethernet/emulex/benet/be_ethtool.c
@@ -157,6 +157,34 @@ static const struct be_ethtool_stat et_rx_stats[] = {
*/
static const struct be_ethtool_stat et_tx_stats[] = {
{DRVSTAT_TX_INFO(tx_compl)}, /* If moving this member see above note */
+ /* This counter is incremented when the HW encounters an error while
+ * parsing the packet header of an outgoing TX request. This counter is
+ * applicable only for BE2, BE3 and Skyhawk based adapters.
+ */
+ {DRVSTAT_TX_INFO(tx_hdr_parse_err)},
+ /* This counter is incremented when an error occurs in the DMA
+ * operation associated with the TX request from the host to the device.
+ */
+ {DRVSTAT_TX_INFO(tx_dma_err)},
+ /* This counter is incremented when MAC or VLAN spoof checking is
+ * enabled on the interface and the TX request fails the spoof check
+ * in HW.
+ */
+ {DRVSTAT_TX_INFO(tx_spoof_check_err)},
+ /* This counter is incremented when the HW encounters an error while
+ * performing TSO offload. This counter is applicable only for Lancer
+ * adapters.
+ */
+ {DRVSTAT_TX_INFO(tx_tso_err)},
+ /* This counter is incremented when the HW detects Q-in-Q style VLAN
+ * tagging in a packet and such tagging is not expected on the outgoing
+ * interface. This counter is applicable only for Lancer adapters.
+ */
+ {DRVSTAT_TX_INFO(tx_qinq_err)},
+ /* This counter is incremented when the HW detects parity errors in the
+ * packet data. This counter is applicable only for Lancer adapters.
+ */
+ {DRVSTAT_TX_INFO(tx_internal_parity_err)},
{DRVSTAT_TX_INFO(tx_bytes)},
{DRVSTAT_TX_INFO(tx_pkts)},
/* Number of skbs queued for trasmission by the driver */
diff --git a/drivers/net/ethernet/emulex/benet/be_hw.h b/drivers/net/ethernet/emulex/benet/be_hw.h
index 8840c64..295ee08 100644
--- a/drivers/net/ethernet/emulex/benet/be_hw.h
+++ b/drivers/net/ethernet/emulex/benet/be_hw.h
@@ -315,6 +315,18 @@ struct be_eth_hdr_wrb {
u32 dw[4];
};
+/********* Tx Compl Status Encoding *********/
+#define BE_TX_COMP_HDR_PARSE_ERR 0x2
+#define BE_TX_COMP_NDMA_ERR 0x3
+#define BE_TX_COMP_ACL_ERR 0x5
+
+#define LANCER_TX_COMP_LSO_ERR 0x1
+#define LANCER_TX_COMP_HSW_DROP_MAC_ERR 0x3
+#define LANCER_TX_COMP_HSW_DROP_VLAN_ERR 0x5
+#define LANCER_TX_COMP_QINQ_ERR 0x7
+#define LANCER_TX_COMP_PARITY_ERR 0xb
+#define LANCER_TX_COMP_DMA_ERR 0xd
+
/* TX Compl Queue Descriptor */
/* Pseudo amap definition for eth_tx_compl in which each bit of the
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
index 810ce5c..e9658f7 100644
--- a/drivers/net/ethernet/emulex/benet/be_main.c
+++ b/drivers/net/ethernet/emulex/benet/be_main.c
@@ -2421,11 +2421,49 @@ loop_continue:
return work_done;
}
+static inline void be_update_tx_err(struct be_tx_obj *txo, u32 status)
+{
+ switch (status) {
+ case BE_TX_COMP_HDR_PARSE_ERR:
+ tx_stats(txo)->tx_hdr_parse_err++;
+ break;
+ case BE_TX_COMP_NDMA_ERR:
+ tx_stats(txo)->tx_dma_err++;
+ break;
+ case BE_TX_COMP_ACL_ERR:
+ tx_stats(txo)->tx_spoof_check_err++;
+ break;
+ }
+}
+
+static inline void lancer_update_tx_err(struct be_tx_obj *txo, u32 status)
+{
+ switch (status) {
+ case LANCER_TX_COMP_LSO_ERR:
+ tx_stats(txo)->tx_tso_err++;
+ break;
+ case LANCER_TX_COMP_HSW_DROP_MAC_ERR:
+ case LANCER_TX_COMP_HSW_DROP_VLAN_ERR:
+ tx_stats(txo)->tx_spoof_check_err++;
+ break;
+ case LANCER_TX_COMP_QINQ_ERR:
+ tx_stats(txo)->tx_qinq_err++;
+ break;
+ case LANCER_TX_COMP_PARITY_ERR:
+ tx_stats(txo)->tx_internal_parity_err++;
+ break;
+ case LANCER_TX_COMP_DMA_ERR:
+ tx_stats(txo)->tx_dma_err++;
+ break;
+ }
+}
+
static bool be_process_tx(struct be_adapter *adapter, struct be_tx_obj *txo,
int budget, int idx)
{
struct be_eth_tx_compl *txcp;
int num_wrbs = 0, work_done;
+ u32 compl_status;
for (work_done = 0; work_done < budget; work_done++) {
txcp = be_tx_compl_get(&txo->cq);
@@ -2434,6 +2472,13 @@ static bool be_process_tx(struct be_adapter *adapter, struct be_tx_obj *txo,
num_wrbs += be_tx_compl_process(adapter, txo,
GET_TX_COMPL_BITS(wrb_index,
txcp));
+ compl_status = GET_TX_COMPL_BITS(status, txcp);
+ if (compl_status) {
+ if (lancer_chip(adapter))
+ lancer_update_tx_err(txo, compl_status);
+ else
+ be_update_tx_err(txo, compl_status);
+ }
}
if (work_done) {
--
1.7.1
^ permalink raw reply related
* [PATCH v2 net-next 06/12] be2net: fix log messages in lancer FW download path
From: Sathya Perla @ 2014-09-02 4:26 UTC (permalink / raw)
To: netdev
In-Reply-To: <1409632017-15655-1-git-send-email-sathya.perla@emulex.com>
From: Kalesh AP <kalesh.purayil@emulex.com>
Log messages in the Lancer FW download path have issues such as:
- a single message spanning multiple lines
- the success message is logged even in failure cases
- status codes are already logged in the FW cmd routines
This patch fixes these issues.
Signed-off-by: Kalesh AP <kalesh.purayil@emulex.com>
Signed-off-by: Sathya Perla <sathya.perla@emulex.com>
---
drivers/net/ethernet/emulex/benet/be_main.c | 30 +++++++++-----------------
1 files changed, 11 insertions(+), 19 deletions(-)
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
index c95998f..7e89e5b 100644
--- a/drivers/net/ethernet/emulex/benet/be_main.c
+++ b/drivers/net/ethernet/emulex/benet/be_main.c
@@ -4076,6 +4076,7 @@ static int lancer_fw_download(struct be_adapter *adapter,
{
#define LANCER_FW_DOWNLOAD_CHUNK (32 * 1024)
#define LANCER_FW_DOWNLOAD_LOCATION "/prg"
+ struct device *dev = &adapter->pdev->dev;
struct be_dma_mem flash_cmd;
const u8 *data_ptr = NULL;
u8 *dest_image_ptr = NULL;
@@ -4088,16 +4089,14 @@ static int lancer_fw_download(struct be_adapter *adapter,
u8 change_status;
if (!IS_ALIGNED(fw->size, sizeof(u32))) {
- dev_err(&adapter->pdev->dev,
- "FW Image not properly aligned. "
- "Length must be 4 byte aligned.\n");
+ dev_err(dev, "FW image size should be multiple of 4\n");
status = -EINVAL;
goto lancer_fw_exit;
}
flash_cmd.size = sizeof(struct lancer_cmd_req_write_object)
+ LANCER_FW_DOWNLOAD_CHUNK;
- flash_cmd.va = dma_alloc_coherent(&adapter->pdev->dev, flash_cmd.size,
+ flash_cmd.va = dma_alloc_coherent(dev, flash_cmd.size,
&flash_cmd.dma, GFP_KERNEL);
if (!flash_cmd.va) {
status = -ENOMEM;
@@ -4137,33 +4136,26 @@ static int lancer_fw_download(struct be_adapter *adapter,
&add_status);
}
- dma_free_coherent(&adapter->pdev->dev, flash_cmd.size, flash_cmd.va,
- flash_cmd.dma);
+ dma_free_coherent(dev, flash_cmd.size, flash_cmd.va, flash_cmd.dma);
if (status) {
- dev_err(&adapter->pdev->dev,
- "Firmware load error. "
- "Status code: 0x%x Additional Status: 0x%x\n",
- status, add_status);
+ dev_err(dev, "Firmware load error\n");
goto lancer_fw_exit;
}
+ dev_info(dev, "Firmware flashed successfully\n");
+
if (change_status == LANCER_FW_RESET_NEEDED) {
- dev_info(&adapter->pdev->dev,
- "Resetting adapter to activate new FW\n");
+ dev_info(dev, "Resetting adapter to activate new FW\n");
status = lancer_physdev_ctrl(adapter,
PHYSDEV_CONTROL_FW_RESET_MASK);
if (status) {
- dev_err(&adapter->pdev->dev,
- "Adapter busy for FW reset.\n"
- "New FW will not be active.\n");
+ dev_err(dev, "Adapter busy, could not reset FW\n");
+ dev_err(dev, "Reboot server to activate new FW\n");
goto lancer_fw_exit;
}
} else if (change_status != LANCER_NO_RESET_NEEDED) {
- dev_err(&adapter->pdev->dev,
- "System reboot required for new FW to be active\n");
+ dev_info(dev, "Reboot server to activate new FW\n");
}
-
- dev_info(&adapter->pdev->dev, "Firmware flashed successfully\n");
lancer_fw_exit:
return status;
}
--
1.7.1
^ permalink raw reply related
* [PATCH v2 net-next 02/12] be2net: shorten AMAP_GET/SET_BITS() macro calls
From: Sathya Perla @ 2014-09-02 4:26 UTC (permalink / raw)
To: netdev
In-Reply-To: <1409632017-15655-1-git-send-email-sathya.perla@emulex.com>
The AMAP_GET/SET_BITS() macro calls take structure name as a parameter
and hence are long and span more than one line. Replace these calls
with a wrapper macros for RX/Tx compls and TX wrb. This results in fewer
lines and more readable code in be_main.c
Signed-off-by: Sathya Perla <sathya.perla@emulex.com>
---
drivers/net/ethernet/emulex/benet/be.h | 12 +++
drivers/net/ethernet/emulex/benet/be_main.c | 115 +++++++++++----------------
2 files changed, 58 insertions(+), 69 deletions(-)
diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h
index 43e08d0..d9cd885 100644
--- a/drivers/net/ethernet/emulex/benet/be.h
+++ b/drivers/net/ethernet/emulex/benet/be.h
@@ -661,6 +661,18 @@ static inline u32 amap_get(void *ptr, u32 dw_offset, u32 mask, u32 offset)
amap_mask(sizeof(((_struct *)0)->field)), \
AMAP_BIT_OFFSET(_struct, field))
+#define GET_RX_COMPL_V0_BITS(field, ptr) \
+ AMAP_GET_BITS(struct amap_eth_rx_compl_v0, field, ptr)
+
+#define GET_RX_COMPL_V1_BITS(field, ptr) \
+ AMAP_GET_BITS(struct amap_eth_rx_compl_v1, field, ptr)
+
+#define GET_TX_COMPL_BITS(field, ptr) \
+ AMAP_GET_BITS(struct amap_eth_tx_compl, field, ptr)
+
+#define SET_TX_WRB_HDR_BITS(field, ptr, val) \
+ AMAP_SET_BITS(struct amap_eth_hdr_wrb, field, ptr, val)
+
#define be_dws_cpu_to_le(wrb, len) swap_dws(wrb, len)
#define be_dws_le_to_cpu(wrb, len) swap_dws(wrb, len)
static inline void swap_dws(void *wrb, int len)
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
index 3d33049..810ce5c 100644
--- a/drivers/net/ethernet/emulex/benet/be_main.c
+++ b/drivers/net/ethernet/emulex/benet/be_main.c
@@ -738,38 +738,37 @@ static void wrb_fill_hdr(struct be_adapter *adapter, struct be_eth_hdr_wrb *hdr,
memset(hdr, 0, sizeof(*hdr));
- AMAP_SET_BITS(struct amap_eth_hdr_wrb, crc, hdr, 1);
+ SET_TX_WRB_HDR_BITS(crc, hdr, 1);
if (skb_is_gso(skb)) {
- AMAP_SET_BITS(struct amap_eth_hdr_wrb, lso, hdr, 1);
- AMAP_SET_BITS(struct amap_eth_hdr_wrb, lso_mss,
- hdr, skb_shinfo(skb)->gso_size);
+ SET_TX_WRB_HDR_BITS(lso, hdr, 1);
+ SET_TX_WRB_HDR_BITS(lso_mss, hdr, skb_shinfo(skb)->gso_size);
if (skb_is_gso_v6(skb) && !lancer_chip(adapter))
- AMAP_SET_BITS(struct amap_eth_hdr_wrb, lso6, hdr, 1);
+ SET_TX_WRB_HDR_BITS(lso6, hdr, 1);
} else if (skb->ip_summed == CHECKSUM_PARTIAL) {
if (skb->encapsulation) {
- AMAP_SET_BITS(struct amap_eth_hdr_wrb, ipcs, hdr, 1);
+ SET_TX_WRB_HDR_BITS(ipcs, hdr, 1);
proto = skb_inner_ip_proto(skb);
} else {
proto = skb_ip_proto(skb);
}
if (proto == IPPROTO_TCP)
- AMAP_SET_BITS(struct amap_eth_hdr_wrb, tcpcs, hdr, 1);
+ SET_TX_WRB_HDR_BITS(tcpcs, hdr, 1);
else if (proto == IPPROTO_UDP)
- AMAP_SET_BITS(struct amap_eth_hdr_wrb, udpcs, hdr, 1);
+ SET_TX_WRB_HDR_BITS(udpcs, hdr, 1);
}
if (vlan_tx_tag_present(skb)) {
- AMAP_SET_BITS(struct amap_eth_hdr_wrb, vlan, hdr, 1);
+ SET_TX_WRB_HDR_BITS(vlan, hdr, 1);
vlan_tag = be_get_tx_vlan_tag(adapter, skb);
- AMAP_SET_BITS(struct amap_eth_hdr_wrb, vlan_tag, hdr, vlan_tag);
+ SET_TX_WRB_HDR_BITS(vlan_tag, hdr, vlan_tag);
}
/* To skip HW VLAN tagging: evt = 1, compl = 0 */
- AMAP_SET_BITS(struct amap_eth_hdr_wrb, complete, hdr, !skip_hw_vlan);
- AMAP_SET_BITS(struct amap_eth_hdr_wrb, event, hdr, 1);
- AMAP_SET_BITS(struct amap_eth_hdr_wrb, num_wrb, hdr, wrb_cnt);
- AMAP_SET_BITS(struct amap_eth_hdr_wrb, len, hdr, len);
+ SET_TX_WRB_HDR_BITS(complete, hdr, !skip_hw_vlan);
+ SET_TX_WRB_HDR_BITS(event, hdr, 1);
+ SET_TX_WRB_HDR_BITS(num_wrb, hdr, wrb_cnt);
+ SET_TX_WRB_HDR_BITS(len, hdr, len);
}
static void unmap_tx_frag(struct device *dev, struct be_eth_wrb *wrb,
@@ -1753,65 +1752,46 @@ static void be_rx_compl_process_gro(struct be_rx_obj *rxo,
static void be_parse_rx_compl_v1(struct be_eth_rx_compl *compl,
struct be_rx_compl_info *rxcp)
{
- rxcp->pkt_size =
- AMAP_GET_BITS(struct amap_eth_rx_compl_v1, pktsize, compl);
- rxcp->vlanf = AMAP_GET_BITS(struct amap_eth_rx_compl_v1, vtp, compl);
- rxcp->err = AMAP_GET_BITS(struct amap_eth_rx_compl_v1, err, compl);
- rxcp->tcpf = AMAP_GET_BITS(struct amap_eth_rx_compl_v1, tcpf, compl);
- rxcp->udpf = AMAP_GET_BITS(struct amap_eth_rx_compl_v1, udpf, compl);
- rxcp->ip_csum =
- AMAP_GET_BITS(struct amap_eth_rx_compl_v1, ipcksm, compl);
- rxcp->l4_csum =
- AMAP_GET_BITS(struct amap_eth_rx_compl_v1, l4_cksm, compl);
- rxcp->ipv6 =
- AMAP_GET_BITS(struct amap_eth_rx_compl_v1, ip_version, compl);
- rxcp->num_rcvd =
- AMAP_GET_BITS(struct amap_eth_rx_compl_v1, numfrags, compl);
- rxcp->pkt_type =
- AMAP_GET_BITS(struct amap_eth_rx_compl_v1, cast_enc, compl);
- rxcp->rss_hash =
- AMAP_GET_BITS(struct amap_eth_rx_compl_v1, rsshash, compl);
+ rxcp->pkt_size = GET_RX_COMPL_V1_BITS(pktsize, compl);
+ rxcp->vlanf = GET_RX_COMPL_V1_BITS(vtp, compl);
+ rxcp->err = GET_RX_COMPL_V1_BITS(err, compl);
+ rxcp->tcpf = GET_RX_COMPL_V1_BITS(tcpf, compl);
+ rxcp->udpf = GET_RX_COMPL_V1_BITS(udpf, compl);
+ rxcp->ip_csum = GET_RX_COMPL_V1_BITS(ipcksm, compl);
+ rxcp->l4_csum = GET_RX_COMPL_V1_BITS(l4_cksm, compl);
+ rxcp->ipv6 = GET_RX_COMPL_V1_BITS(ip_version, compl);
+ rxcp->num_rcvd = GET_RX_COMPL_V1_BITS(numfrags, compl);
+ rxcp->pkt_type = GET_RX_COMPL_V1_BITS(cast_enc, compl);
+ rxcp->rss_hash = GET_RX_COMPL_V1_BITS(rsshash, compl);
if (rxcp->vlanf) {
- rxcp->qnq = AMAP_GET_BITS(struct amap_eth_rx_compl_v1, qnq,
- compl);
- rxcp->vlan_tag = AMAP_GET_BITS(struct amap_eth_rx_compl_v1,
- vlan_tag, compl);
+ rxcp->qnq = GET_RX_COMPL_V1_BITS(qnq, compl);
+ rxcp->vlan_tag = GET_RX_COMPL_V1_BITS(vlan_tag, compl);
}
- rxcp->port = AMAP_GET_BITS(struct amap_eth_rx_compl_v1, port, compl);
+ rxcp->port = GET_RX_COMPL_V1_BITS(port, compl);
rxcp->tunneled =
- AMAP_GET_BITS(struct amap_eth_rx_compl_v1, tunneled, compl);
+ GET_RX_COMPL_V1_BITS(tunneled, compl);
}
static void be_parse_rx_compl_v0(struct be_eth_rx_compl *compl,
struct be_rx_compl_info *rxcp)
{
- rxcp->pkt_size =
- AMAP_GET_BITS(struct amap_eth_rx_compl_v0, pktsize, compl);
- rxcp->vlanf = AMAP_GET_BITS(struct amap_eth_rx_compl_v0, vtp, compl);
- rxcp->err = AMAP_GET_BITS(struct amap_eth_rx_compl_v0, err, compl);
- rxcp->tcpf = AMAP_GET_BITS(struct amap_eth_rx_compl_v0, tcpf, compl);
- rxcp->udpf = AMAP_GET_BITS(struct amap_eth_rx_compl_v0, udpf, compl);
- rxcp->ip_csum =
- AMAP_GET_BITS(struct amap_eth_rx_compl_v0, ipcksm, compl);
- rxcp->l4_csum =
- AMAP_GET_BITS(struct amap_eth_rx_compl_v0, l4_cksm, compl);
- rxcp->ipv6 =
- AMAP_GET_BITS(struct amap_eth_rx_compl_v0, ip_version, compl);
- rxcp->num_rcvd =
- AMAP_GET_BITS(struct amap_eth_rx_compl_v0, numfrags, compl);
- rxcp->pkt_type =
- AMAP_GET_BITS(struct amap_eth_rx_compl_v0, cast_enc, compl);
- rxcp->rss_hash =
- AMAP_GET_BITS(struct amap_eth_rx_compl_v0, rsshash, compl);
+ rxcp->pkt_size = GET_RX_COMPL_V0_BITS(pktsize, compl);
+ rxcp->vlanf = GET_RX_COMPL_V0_BITS(vtp, compl);
+ rxcp->err = GET_RX_COMPL_V0_BITS(err, compl);
+ rxcp->tcpf = GET_RX_COMPL_V0_BITS(tcpf, compl);
+ rxcp->udpf = GET_RX_COMPL_V0_BITS(udpf, compl);
+ rxcp->ip_csum = GET_RX_COMPL_V0_BITS(ipcksm, compl);
+ rxcp->l4_csum = GET_RX_COMPL_V0_BITS(l4_cksm, compl);
+ rxcp->ipv6 = GET_RX_COMPL_V0_BITS(ip_version, compl);
+ rxcp->num_rcvd = GET_RX_COMPL_V0_BITS(numfrags, compl);
+ rxcp->pkt_type = GET_RX_COMPL_V0_BITS(cast_enc, compl);
+ rxcp->rss_hash = GET_RX_COMPL_V0_BITS(rsshash, compl);
if (rxcp->vlanf) {
- rxcp->qnq = AMAP_GET_BITS(struct amap_eth_rx_compl_v0, qnq,
- compl);
- rxcp->vlan_tag = AMAP_GET_BITS(struct amap_eth_rx_compl_v0,
- vlan_tag, compl);
+ rxcp->qnq = GET_RX_COMPL_V0_BITS(qnq, compl);
+ rxcp->vlan_tag = GET_RX_COMPL_V0_BITS(vlan_tag, compl);
}
- rxcp->port = AMAP_GET_BITS(struct amap_eth_rx_compl_v0, port, compl);
- rxcp->ip_frag = AMAP_GET_BITS(struct amap_eth_rx_compl_v0,
- ip_frag, compl);
+ rxcp->port = GET_RX_COMPL_V0_BITS(port, compl);
+ rxcp->ip_frag = GET_RX_COMPL_V0_BITS(ip_frag, compl);
}
static struct be_rx_compl_info *be_rx_compl_get(struct be_rx_obj *rxo)
@@ -2091,9 +2071,7 @@ static void be_tx_compl_clean(struct be_adapter *adapter)
num_wrbs = 0;
txq = &txo->q;
while ((txcp = be_tx_compl_get(&txo->cq))) {
- end_idx =
- AMAP_GET_BITS(struct amap_eth_tx_compl,
- wrb_index, txcp);
+ end_idx = GET_TX_COMPL_BITS(wrb_index, txcp);
num_wrbs += be_tx_compl_process(adapter, txo,
end_idx);
cmpl++;
@@ -2454,9 +2432,8 @@ static bool be_process_tx(struct be_adapter *adapter, struct be_tx_obj *txo,
if (!txcp)
break;
num_wrbs += be_tx_compl_process(adapter, txo,
- AMAP_GET_BITS(struct
- amap_eth_tx_compl,
- wrb_index, txcp));
+ GET_TX_COMPL_BITS(wrb_index,
+ txcp));
}
if (work_done) {
--
1.7.1
^ permalink raw reply related
* [PATCH v2 net-next 00/12] be2net: patch set
From: Sathya Perla @ 2014-09-02 4:26 UTC (permalink / raw)
To: netdev
v2 changes: add a new line after variable declaration in patch 12.
***
Patch 1 adds a few new log messages to help debugging in failure cases.
Patch 2 uses new macros for parsing RX/TX completions and TX wrbs to
help shorten the lines.
Patch 3 adds a description for the RX counter rx_input_fifo_overflow_drop.
Patch 4 adds TX completion error statistics reporting via ethtool.
Patch 5 adds a dma_mapping_error counter and its reporting via ethtool.
Patch 6 fixes up log messages in the Lancer FW download path.
Patch 7 replaces gotos with direct return statements.
Patch 8 cleans up be_change_mtu() code by using a new macro BE_MAX_MTU
Patch 9 makes be_cmd_get_regs() routine to return an integer status
similar to other FW cmd routines in be_cmds.c
Patch 10 gets rid of TX budget as enforcing a budget on TX completion
processing in NAPI is neither suggested nor it provides a performance benefit.
Patch 11 defines and uses a new macro for_all_tx_queues_on_eq() similar
to the RX processing code.
Patch 12 queries max_tx_qs from the FW for BE3 super-nic profiles.
For those profiles, the driver cannot assume a constant BE3_MAX_TX_QS value,
as the value may change for each function.
Please consider applying this patch set to the net-next tree. Thanks!
Kalesh AP (4):
be2net: Add TX completion error statistics in ethtool
be2net: fix log messages in lancer FW download path
be2net: remove unncessary gotos
be2net: define BE_MAX_MTU
Sathya Perla (5):
be2net: add a few log messages
be2net: shorten AMAP_GET/SET_BITS() macro calls
be2net: add a description for counter rx_input_fifo_overflow_drop
be2net: get rid of TX budget
be2net: define macro for_all_tx_queues_on_eq()
Suresh Reddy (1):
be2net: query max_tx_qs for BE3 super-nic profile from FW
Vasundhara Volam (2):
be2net: Add a dma_mapping_error counter in ethtool
be2net: make be_cmd_get_regs() return a status
drivers/net/ethernet/emulex/benet/be.h | 28 +++-
drivers/net/ethernet/emulex/benet/be_cmds.c | 14 +-
drivers/net/ethernet/emulex/benet/be_cmds.h | 2 +-
drivers/net/ethernet/emulex/benet/be_ethtool.c | 35 +++
drivers/net/ethernet/emulex/benet/be_hw.h | 12 +
drivers/net/ethernet/emulex/benet/be_main.c | 283 +++++++++++++-----------
6 files changed, 233 insertions(+), 141 deletions(-)
^ permalink raw reply
* Re: [PATCH net v5 4/4] tg3: Fix tx_pending checks for tg3_tso_bug
From: David Miller @ 2014-09-02 4:23 UTC (permalink / raw)
To: bpoirier; +Cc: prashant, mchan, netdev, linux-kernel
In-Reply-To: <1409345191-8819-4-git-send-email-bpoirier@suse.de>
From: Benjamin Poirier <bpoirier@suse.de>
Date: Fri, 29 Aug 2014 13:46:31 -0700
> This puts us in the exceptional situation that a single skb that
> triggers tg3_tso_bug() may require the entire tx ring.
This is really silly.
If you get fed crap, linearize the SKB, end of story.
Don't try to be clever, and absolutely do not adjust gso_max_segs on
the fly as it was never ever designed to change dynamically and
asynchronously to the code paths which use it to size outgoing TCP
segments.
Nothing else needs adjusting, just linearize when you run into a
packet that can't fit into the TX ring because of these weird
restrictions.
^ permalink raw reply
* RE: [PATCH net-next 12/12] be2net: query max_tx_qs for BE3 super-nic profile from FW
From: Sathya Perla @ 2014-09-02 4:08 UTC (permalink / raw)
To: Sergei Shtylyov, netdev@vger.kernel.org
In-Reply-To: <54047045.4080400@cogentembedded.com>
> -----Original Message-----
> From: Sergei Shtylyov [mailto:sergei.shtylyov@cogentembedded.com]
>
> Hello.
>
> > In the BE3 super-nic profile, the max_tx_qs value can vary for each
> function.
> > So the driver needs to query this value from FW instead of using the
> > pre-defined constant BE3_MAX_TX_QS.
>
> > Signed-off-by: Suresh Reddy <Suresh.Reddy@emulex.com>
> > Signed-off-by: Sathya Perla <sathya.perla@emulex.com>
> > ---
> > drivers/net/ethernet/emulex/benet/be_main.c | 13 +++++++++++--
> > 1 files changed, 11 insertions(+), 2 deletions(-)
>
> > diff --git a/drivers/net/ethernet/emulex/benet/be_main.c
> b/drivers/net/ethernet/emulex/benet/be_main.c
> > index f3235d1..a30156b 100644
> > --- a/drivers/net/ethernet/emulex/benet/be_main.c
> > +++ b/drivers/net/ethernet/emulex/benet/be_main.c
> > @@ -3324,10 +3324,19 @@ static void BEx_get_resources(struct
> be_adapter *adapter,
> > */
> > if (BE2_chip(adapter) || use_sriov || (adapter->port_num > 1) ||
> > !be_physfn(adapter) || (be_is_mc(adapter) &&
> > - !(adapter->function_caps & BE_FUNCTION_CAPS_RSS)))
> > + !(adapter->function_caps & BE_FUNCTION_CAPS_RSS))) {
> > res->max_tx_qs = 1;
> > - else
> > + } else if (adapter->function_caps &
> BE_FUNCTION_CAPS_SUPER_NIC) {
> > + struct be_resources super_nic_res = {0};
>
> Empty line is needed after declaration.
Ok, will fix it. Thks.
>
> > + /* On a SuperNIC profile, the driver needs to use the
> > + * GET_PROFILE_CONFIG cmd to query the per-function TXQ
> limits
> > + */
> > + be_cmd_get_profile_config(adapter, &super_nic_res, 0);
> > + /* Some old versions of BE3 FW don't report max_tx_qs
> value */
> > + res->max_tx_qs = super_nic_res.max_tx_qs ? :
> BE3_MAX_TX_QS;
> > + } else {
> > res->max_tx_qs = BE3_MAX_TX_QS;
> > + }
>
> WBR, Sergei
^ permalink raw reply
* Re: [PATCH net-next 2/2] net: exit busy loop when another process is runnable
From: Jason Wang @ 2014-09-02 4:03 UTC (permalink / raw)
To: Peter Zijlstra, Michael S. Tsirkin
Cc: Mike Galbraith, davem, netdev, linux-kernel, Ingo Molnar,
Eliezer Tamir
In-Reply-To: <20140901101939.GA31157@worktop.ger.corp.intel.com>
On 09/01/2014 06:19 PM, Peter Zijlstra wrote:
> On Mon, Sep 01, 2014 at 12:04:34PM +0200, Peter Zijlstra wrote:
>> > On Mon, Sep 01, 2014 at 12:52:19PM +0300, Michael S. Tsirkin wrote:
>>> > > On Mon, Sep 01, 2014 at 11:31:59AM +0200, Peter Zijlstra wrote:
>>>> > > > On Fri, Aug 22, 2014 at 07:01:05AM +0200, Mike Galbraith wrote:
>>>>>> > > > > > +++ b/include/net/busy_poll.h
>>>>>> > > > > > @@ -109,7 +109,8 @@ static inline bool sk_busy_loop(struct sock *sk, int nonblock)
>>>>>> > > > > > cpu_relax();
>>>>>> > > > > >
>>>>>> > > > > > } while (!nonblock && skb_queue_empty(&sk->sk_receive_queue) &&
>>>>>> > > > > > - !need_resched() && !busy_loop_timeout(end_time));
>>>>>> > > > > > + !need_resched() && !busy_loop_timeout(end_time) &&
>>>>>> > > > > > + nr_running_this_cpu() < 2);
>>>>>> > > > > >
>>>> > > >
>>>> > > > So as has been said by now; this is horrible.
>>>> > > >
>>>> > > > We should not export nr_running like this ever. Your usage of < 2
>>>> > > > implies this can be hit with nr_running == 0, and therefore you can also
>>>> > > > hit it with nr_running == 1 where the one is not network related and you
>>>> > > > get random delays.
>>>> > > >
>>>> > > > Worse still, you have BH (and thereby preemption) disabled, you should
>>>> > > > not _ever_ have undefined and indefinite waits like that.
>>>> > > >
>>>> > > > You also destroy any hope of dropping into lower power states; even when
>>>> > > > there's never going to be a packet ever again, also bad.
>>> > >
>>> > > Hmm this patch sometimes makes us exit from the busy loop *earlier*.
>>> > > How can this interfere with dropping into lower power states?
>> >
>> > Ah.. jetlag.. :/ I read it like it owuld indefinitely spin if there was
>> > only the 'one' task, not avoid the spin unless there was the one task.
>> >
>> > The nr_running thing is still horrible, but let me reread this patch
>> > description to see if it explains why that is a good thing.
> OK I suppose that more or less makes sense, the contextual behaviour is
> of course tedious in that it makes behaviour less predictable. The
> 'other' tasks might not want to generate data and you then destroy
> throughput by not spinning.
The patch try to make sure:
- the the performance of busy read was not worse than it was disabled in
any cases.
- the performance improvement of a single socket was not achieved by
sacrificing the total performance (all other processes) of the system
If 'other' tasks are also CPU or I/O intensive jobs, we switch to do
them so the total performance were kept or even increased, and the
performance of current process were guaranteed not worse than when busy
read was disabled (or even better since it may still do busy read
sometimes when it was the only runnable process). If 'other' task are
not intensive, they just do little work and sleep soon, then the busy
read can still work in most of the time during the future reads, we may
still get obvious improvements.
> I'm not entirely sure I see how its all supposed to work though; the
> various poll functions call sk_busy_poll() and do_select() also loops.
>
> The patch only kills the sk_busy_poll() loop, but then do_select() will
> still loop and not sleep, so how is this helping?
Yes, the patch only help for processes who did a blocking reads (busy
read). For select(), maybe we can do the same thing but need more test
and thoughts.
^ permalink raw reply
* Re: [PATCH net-next 1/2] sunvnet: Avoid sending superfluous LDC messages.
From: David Miller @ 2014-09-02 3:48 UTC (permalink / raw)
To: sowmini.varadhan; +Cc: raghuram.kothakota, netdev
In-Reply-To: <20140829202105.GI14753@oracle.com>
From: Sowmini Varadhan <sowmini.varadhan@oracle.com>
Date: Fri, 29 Aug 2014 16:21:05 -0400
> @@ -380,11 +390,14 @@ static int vnet_walk_rx(struct vnet_port *port, struct vio_dring_state *dr,
> viodbg(DATA, "vnet_walk_rx start[%08x] end[%08x]\n", start, end);
>
> while (start != end) {
> - int ack = 0, err = vnet_walk_rx_one(port, dr, start, &ack);
> + int retries;
> + int ack = 0, err;
> +
> + retries = 0;
> +again:
> + err = vnet_walk_rx_one(port, dr, start, &ack);
> if (err == -ECONNRESET)
> return err;
> - if (err != 0)
> - break;
> if (ack_start == -1)
> ack_start = start;
> ack_end = start;
You're adding a function local label not even used by this patch.
Please be more careful with your patch submissions, I can see here
that you're bleeding patch #2 (which I disagree with) into this one
and you're not testing your changes individually as you should.
^ permalink raw reply
* Re: [PATCH net-next 2/2] sunvnet: Re-check for a VIO_DESC_READY data descriptor after short udelay()
From: David Miller @ 2014-09-02 3:47 UTC (permalink / raw)
To: sowmini.varadhan; +Cc: raghuram.kothakota, netdev
In-Reply-To: <20140829201809.GH14753@oracle.com>
From: Sowmini Varadhan <sowmini.varadhan@oracle.com>
Date: Fri, 29 Aug 2014 16:18:09 -0400
> @@ -398,6 +398,20 @@ again:
> err = vnet_walk_rx_one(port, dr, start, &ack);
> if (err == -ECONNRESET)
> return err;
> + if (err != 0) {
> + /* The descriptor was not READY. Retry with a
> + * small delay, in case we have a bursty sender
> + * that is actively populating the descriptors, to
> + * reduce the overhead of stopping and re-entering
> + * which would involve expensive LDC messages.
> + */
> + if (retries++ < 3) {
> + udelay(4);
> + goto again;
> + } else {
> + break;
> + }
> + }
I'm definitely not happy with this.
If there were no more packets coming, this is wasted useless polling
time in atomic context.
Everything should be event based, and we should not be compensating
and making sacrifices for a producer slower than we are as a consumer.
^ permalink raw reply
* Re: [PATCH net-next] r8152: rename rx_buf_sz
From: David Miller @ 2014-09-02 3:42 UTC (permalink / raw)
To: hayeswang; +Cc: netdev, nic_swsd, linux-kernel, linux-usb
In-Reply-To: <1394712342-15778-25-Taiwan-albertk@realtek.com>
From: Hayes Wang <hayeswang@realtek.com>
Date: Tue, 2 Sep 2014 10:27:52 +0800
> The variable "rx_buf_sz" is used by both tx and rx buffers. Replace
> it with "agg_buf_sz".
>
> Signed-off-by: Hayes Wang <hayeswang@realtek.com>
Applied.
^ permalink raw reply
* Re: [PATCH net-next] net: phy: mdio-bcm-unimac: NULL-terminate unimac_mdio_ids
From: David Miller @ 2014-09-02 3:42 UTC (permalink / raw)
To: f.fainelli; +Cc: netdev, fengguang.wu
In-Reply-To: <1409341436-22900-1-git-send-email-f.fainelli@gmail.com>
From: Florian Fainelli <f.fainelli@gmail.com>
Date: Fri, 29 Aug 2014 12:43:56 -0700
> drivers/net/phy/mdio-bcm-unimac.c:195:37-38: unimac_mdio_ids is not NULL
> terminated at line 195
>
> Make sure of_device_id tables are NULL terminated
> Generated by: scripts/coccinelle/misc/of_table.cocci
>
> Signed-off-by: Fengguang Wu <fengguang.wu@intel.com>
> Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
Applied.
^ permalink raw reply
* Re: [PATCH net-next] net: dsa: make dsa_pack_type static
From: David Miller @ 2014-09-02 3:42 UTC (permalink / raw)
To: f.fainelli; +Cc: netdev, fengguang.wu
In-Reply-To: <1409341327-22527-1-git-send-email-f.fainelli@gmail.com>
From: Florian Fainelli <f.fainelli@gmail.com>
Date: Fri, 29 Aug 2014 12:42:07 -0700
> net/dsa/dsa.c:624:20: sparse: symbol 'dsa_pack_type' was not declared.
> Should it be static?
>
> Fixes: 3e8a72d1dae374 ("net: dsa: reduce number of protocol hooks")
> Signed-off-by: Fengguang Wu <fengguang.wu@intel.com>
> Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
Applied.
^ permalink raw reply
* Re: [PATCH net v1 0/4] amd-xgbe: AMD XGBE driver fixes 2014-08-29
From: David Miller @ 2014-09-02 3:40 UTC (permalink / raw)
To: thomas.lendacky; +Cc: netdev
In-Reply-To: <20140829181643.3257.28011.stgit@tlendack-t1.amdoffice.net>
From: Tom Lendacky <thomas.lendacky@amd.com>
Date: Fri, 29 Aug 2014 13:16:44 -0500
> The following series of patches includes fixes to the driver.
>
> - Tx hardware queue flushing support dependent on hardware version
> - Incorrect reported fifo size
> - Proper mmd select in XPCS debugfs support
> - Proper queue count for configuring Tx flow control
>
> This patch series is based on net.
Series applied, thanks.
^ permalink raw reply
* Re: [PATCH net-next 2/2] net: exit busy loop when another process is runnable
From: Jason Wang @ 2014-09-02 3:38 UTC (permalink / raw)
To: Peter Zijlstra, Michael S. Tsirkin
Cc: Mike Galbraith, davem, netdev, linux-kernel, Ingo Molnar
In-Reply-To: <20140901100434.GD27892@worktop.ger.corp.intel.com>
On 09/01/2014 06:04 PM, Peter Zijlstra wrote:
> On Mon, Sep 01, 2014 at 12:52:19PM +0300, Michael S. Tsirkin wrote:
>> On Mon, Sep 01, 2014 at 11:31:59AM +0200, Peter Zijlstra wrote:
>>> On Fri, Aug 22, 2014 at 07:01:05AM +0200, Mike Galbraith wrote:
>>>>> +++ b/include/net/busy_poll.h
>>>>> @@ -109,7 +109,8 @@ static inline bool sk_busy_loop(struct sock *sk, int nonblock)
>>>>> cpu_relax();
>>>>>
>>>>> } while (!nonblock && skb_queue_empty(&sk->sk_receive_queue) &&
>>>>> - !need_resched() && !busy_loop_timeout(end_time));
>>>>> + !need_resched() && !busy_loop_timeout(end_time) &&
>>>>> + nr_running_this_cpu() < 2);
>>>>>
>>> So as has been said by now; this is horrible.
>>>
>>> We should not export nr_running like this ever. Your usage of < 2
>>> implies this can be hit with nr_running == 0, and therefore you can also
>>> hit it with nr_running == 1 where the one is not network related and you
>>> get random delays.
>>>
>>> Worse still, you have BH (and thereby preemption) disabled, you should
>>> not _ever_ have undefined and indefinite waits like that.
>>>
>>> You also destroy any hope of dropping into lower power states; even when
>>> there's never going to be a packet ever again, also bad.
>> Hmm this patch sometimes makes us exit from the busy loop *earlier*.
>> How can this interfere with dropping into lower power states?
> Ah.. jetlag.. :/ I read it like it owuld indefinitely spin if there was
> only the 'one' task, not avoid the spin unless there was the one task.
>
> The nr_running thing is still horrible, but let me reread this patch
> description to see if it explains why that is a good thing.
I see, how about just exporting a boolean helper like
current_can_busy_loop() and take care all of the conditions (pending bhs
and rcu callbacks, runnable processes) in scheduler code itself?
^ permalink raw reply
* Re: [PATCH] drivers: net: NET_XGENE should depend on HAS_DMA
From: David Miller @ 2014-09-02 3:36 UTC (permalink / raw)
To: geert; +Cc: isubramanian, netdev, linux-kernel
In-Reply-To: <1409329301-6747-1-git-send-email-geert@linux-m68k.org>
From: Geert Uytterhoeven <geert@linux-m68k.org>
Date: Fri, 29 Aug 2014 18:21:41 +0200
> If NO_DMA=y:
...
> Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
Applied.
^ permalink raw reply
* Re: [PATCH net-next 2/2] net: exit busy loop when another process is runnable
From: Jason Wang @ 2014-09-02 3:35 UTC (permalink / raw)
To: Eliezer Tamir, Eric Dumazet
Cc: Ingo Molnar, Mike Galbraith, davem, netdev, linux-kernel, mst,
Peter Zijlstra, Ingo Molnar jacob.e.keller@intel.com
In-Reply-To: <5404186E.4090409@linux.intel.com>
On 09/01/2014 02:55 PM, Eliezer Tamir wrote:
> On 26/08/2014 10:16, Jason Wang wrote:
>> On 08/25/2014 09:16 PM, Eliezer Tamir wrote:
>>> Here are my 2 cents:
>>> I think Ingo's suggestion of only yielding to tasks with same or higher
>>> priority makes sense.
>> I'm not sure I get your meaning. Do you mean calling yield_to() directly
>> in sk_busy_loop?
> Think about the case where two processes are busy polling on the
> same CPU and the same device queue. Since busy polling processes
> incoming packets on the queue from any process, this scenario works
> well currently,
I see, but looks like we can simply do this by exiting the busy loop
when ndo_busy_poll() finds something but not for current socket?
> and will not work at all when polling yields to other
> processes that are of the same priority that are running on the same
> CPU.
So yielding has its limitation, we need let scheduler to do the choice
instead.
>
> As a side note, there is a lot of room for improvement when two
> processes on the same CPU want to busy poll on different device
> queues.
> The RFC code I published for epoll support showed one possible
> way of solving this, but I'm sure that there are other possibilities.
>
> Maybe the networking subsystem should maintain a list of device
> queues that need busypolling and have a thread that would poll
> all of them when there's nothing better to do.
Not sure whether this method will scale considering thousands of sockets
and processes.
>
> I'm aware of similar work on busy polling on NVMe devices, so
> maybe there should be a global busypoll thread for all devices
> that support it.
>
> BTW, I have someone inside Intel that wants to test future patches. Feel
> free to send me patches for testing, even if they are not ready for
> publishing yet.
>
> Cheers,
> Eliezer
Ok, will do it, thanks a lot.
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox