* Re: [PATCH v2 net-next 3/4] qed: Fix maximum number of CQs for iWARP
From: Leon Romanovsky @ 2017-09-24 10:35 UTC (permalink / raw)
To: Michal Kalderon
Cc: davem-fT/PcQaiUtIeIZ0/mPfg9Q, netdev-u79uwXL29TY76Z2rM5mHXA,
linux-rdma-u79uwXL29TY76Z2rM5mHXA,
dledford-H+wXaHxf7aLQT0dZR+AlfA, Ariel Elior
In-Reply-To: <1506244185-2129-4-git-send-email-Michal.Kalderon-YGCgFSpz5w/QT0dZR+AlfA@public.gmane.org>
[-- Attachment #1: Type: text/plain, Size: 760 bytes --]
On Sun, Sep 24, 2017 at 12:09:44PM +0300, Michal Kalderon wrote:
> The maximum number of CQs supported is bound to the number
> of connections supported, which differs between RoCE and iWARP.
>
> This fixes a crash that occurred in iWARP when running 1000 sessions
> using perftest.
>
> Fixes: 67b40dccc45 ("qed: Implement iWARP initialization, teardown and qp operations")
>
> Signed-off-by: Michal Kalderon <Michal.Kalderon-YGCgFSpz5w/QT0dZR+AlfA@public.gmane.org>
> Signed-off-by: Ariel Elior <Ariel.Elior-YGCgFSpz5w/QT0dZR+AlfA@public.gmane.org>
> ---
> drivers/net/ethernet/qlogic/qed/qed_rdma.c | 12 ++++++------
> 1 file changed, 6 insertions(+), 6 deletions(-)
>
Thanks,
Reviewed-by: Leon Romanovsky <leonro-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply
* [PATCH v2 net-next 2/4] qed: Add iWARP out of order support
From: Michal Kalderon @ 2017-09-24 9:09 UTC (permalink / raw)
To: davem, netdev, leon; +Cc: linux-rdma, dledford, Michal Kalderon, Ariel Elior
In-Reply-To: <1506244185-2129-1-git-send-email-Michal.Kalderon@cavium.com>
iWARP requires OOO support which is already provided by the ll2
interface (until now was used only for iSCSI offload).
The changes mostly include opening a ll2 dedicated connection for
OOO and notifiying the FW about the handle id.
Signed-off-by: Michal Kalderon <Michal.Kalderon@cavium.com>
Signed-off-by: Ariel Elior <Ariel.Elior@cavium.com>
---
drivers/net/ethernet/qlogic/qed/qed_iwarp.c | 44 +++++++++++++++++++++++++++++
drivers/net/ethernet/qlogic/qed/qed_iwarp.h | 11 +++++++-
drivers/net/ethernet/qlogic/qed/qed_rdma.c | 7 +++--
3 files changed, 59 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/qlogic/qed/qed_iwarp.c b/drivers/net/ethernet/qlogic/qed/qed_iwarp.c
index 9d989c9..568e985 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_iwarp.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_iwarp.c
@@ -41,6 +41,7 @@
#include "qed_rdma.h"
#include "qed_reg_addr.h"
#include "qed_sp.h"
+#include "qed_ooo.h"
#define QED_IWARP_ORD_DEFAULT 32
#define QED_IWARP_IRD_DEFAULT 32
@@ -119,6 +120,13 @@ static void qed_iwarp_cid_cleaned(struct qed_hwfn *p_hwfn, u32 cid)
spin_unlock_bh(&p_hwfn->p_rdma_info->lock);
}
+void qed_iwarp_init_fw_ramrod(struct qed_hwfn *p_hwfn,
+ struct iwarp_init_func_params *p_ramrod)
+{
+ p_ramrod->ll2_ooo_q_index = RESC_START(p_hwfn, QED_LL2_QUEUE) +
+ p_hwfn->p_rdma_info->iwarp.ll2_ooo_handle;
+}
+
static int qed_iwarp_alloc_cid(struct qed_hwfn *p_hwfn, u32 *cid)
{
int rc;
@@ -1876,6 +1884,16 @@ static int qed_iwarp_ll2_stop(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
iwarp_info->ll2_syn_handle = QED_IWARP_HANDLE_INVAL;
}
+ if (iwarp_info->ll2_ooo_handle != QED_IWARP_HANDLE_INVAL) {
+ rc = qed_ll2_terminate_connection(p_hwfn,
+ iwarp_info->ll2_ooo_handle);
+ if (rc)
+ DP_INFO(p_hwfn, "Failed to terminate ooo connection\n");
+
+ qed_ll2_release_connection(p_hwfn, iwarp_info->ll2_ooo_handle);
+ iwarp_info->ll2_ooo_handle = QED_IWARP_HANDLE_INVAL;
+ }
+
qed_llh_remove_mac_filter(p_hwfn,
p_ptt, p_hwfn->p_rdma_info->iwarp.mac_addr);
return rc;
@@ -1927,10 +1945,12 @@ static int qed_iwarp_ll2_stop(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
struct qed_iwarp_info *iwarp_info;
struct qed_ll2_acquire_data data;
struct qed_ll2_cbs cbs;
+ u16 n_ooo_bufs;
int rc = 0;
iwarp_info = &p_hwfn->p_rdma_info->iwarp;
iwarp_info->ll2_syn_handle = QED_IWARP_HANDLE_INVAL;
+ iwarp_info->ll2_ooo_handle = QED_IWARP_HANDLE_INVAL;
iwarp_info->max_mtu = params->max_mtu;
@@ -1978,6 +1998,29 @@ static int qed_iwarp_ll2_stop(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
if (rc)
goto err;
+ /* Start OOO connection */
+ data.input.conn_type = QED_LL2_TYPE_OOO;
+ data.input.mtu = params->max_mtu;
+
+ n_ooo_bufs = (QED_IWARP_MAX_OOO * QED_IWARP_RCV_WND_SIZE_DEF) /
+ iwarp_info->max_mtu;
+ n_ooo_bufs = min_t(u32, n_ooo_bufs, QED_IWARP_LL2_OOO_MAX_RX_SIZE);
+
+ data.input.rx_num_desc = n_ooo_bufs;
+ data.input.rx_num_ooo_buffers = n_ooo_bufs;
+
+ data.input.tx_max_bds_per_packet = 1; /* will never be fragmented */
+ data.input.tx_num_desc = QED_IWARP_LL2_OOO_DEF_TX_SIZE;
+ data.p_connection_handle = &iwarp_info->ll2_ooo_handle;
+
+ rc = qed_ll2_acquire_connection(p_hwfn, &data);
+ if (rc)
+ goto err;
+
+ rc = qed_ll2_establish_connection(p_hwfn, iwarp_info->ll2_ooo_handle);
+ if (rc)
+ goto err;
+
return rc;
err:
qed_iwarp_ll2_stop(p_hwfn, p_ptt);
@@ -2014,6 +2057,7 @@ int qed_iwarp_setup(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt,
qed_spq_register_async_cb(p_hwfn, PROTOCOLID_IWARP,
qed_iwarp_async_event);
+ qed_ooo_setup(p_hwfn);
return qed_iwarp_ll2_start(p_hwfn, params, p_ptt);
}
diff --git a/drivers/net/ethernet/qlogic/qed/qed_iwarp.h b/drivers/net/ethernet/qlogic/qed/qed_iwarp.h
index 148ef3c..9e2bfde 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_iwarp.h
+++ b/drivers/net/ethernet/qlogic/qed/qed_iwarp.h
@@ -47,7 +47,12 @@ enum qed_iwarp_qp_state {
#define QED_IWARP_LL2_SYN_TX_SIZE (128)
#define QED_IWARP_LL2_SYN_RX_SIZE (256)
#define QED_IWARP_MAX_SYN_PKT_SIZE (128)
-#define QED_IWARP_HANDLE_INVAL (0xff)
+
+#define QED_IWARP_LL2_OOO_DEF_TX_SIZE (256)
+#define QED_IWARP_MAX_OOO (16)
+#define QED_IWARP_LL2_OOO_MAX_RX_SIZE (16384)
+
+#define QED_IWARP_HANDLE_INVAL (0xff)
struct qed_iwarp_ll2_buff {
void *data;
@@ -67,6 +72,7 @@ struct qed_iwarp_info {
u8 crc_needed;
u8 tcp_flags;
u8 ll2_syn_handle;
+ u8 ll2_ooo_handle;
u8 peer2peer;
enum mpa_negotiation_mode mpa_rev;
enum mpa_rtr_type rtr_type;
@@ -147,6 +153,9 @@ struct qed_iwarp_listener {
int qed_iwarp_setup(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt,
struct qed_rdma_start_in_params *params);
+void qed_iwarp_init_fw_ramrod(struct qed_hwfn *p_hwfn,
+ struct iwarp_init_func_params *p_ramrod);
+
int qed_iwarp_stop(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt);
void qed_iwarp_resc_free(struct qed_hwfn *p_hwfn);
diff --git a/drivers/net/ethernet/qlogic/qed/qed_rdma.c b/drivers/net/ethernet/qlogic/qed/qed_rdma.c
index 06715f7..4f46f28 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_rdma.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_rdma.c
@@ -551,10 +551,13 @@ static int qed_rdma_start_fw(struct qed_hwfn *p_hwfn,
if (rc)
return rc;
- if (QED_IS_IWARP_PERSONALITY(p_hwfn))
+ if (QED_IS_IWARP_PERSONALITY(p_hwfn)) {
+ qed_iwarp_init_fw_ramrod(p_hwfn,
+ &p_ent->ramrod.iwarp_init_func.iwarp);
p_ramrod = &p_ent->ramrod.iwarp_init_func.rdma;
- else
+ } else {
p_ramrod = &p_ent->ramrod.roce_init_func.rdma;
+ }
p_params_header = &p_ramrod->params_header;
p_params_header->cnq_start_offset = (u8)RESC_START(p_hwfn,
--
1.8.3.1
^ permalink raw reply related
* [PATCH v2 net-next 1/4] qed: Add iWARP enablement support
From: Michal Kalderon @ 2017-09-24 9:09 UTC (permalink / raw)
To: davem, netdev, leon; +Cc: linux-rdma, dledford, Michal Kalderon, Ariel Elior
In-Reply-To: <1506244185-2129-1-git-send-email-Michal.Kalderon@cavium.com>
This patch is the last of the initial iWARP patch series. It
adds the possiblity to actually detect iWARP from the device and enable
it in the critical locations which basically make iWARP available.
It wasn't submitted until now as iWARP hadn't been accepted into
the rdma tree.
Signed-off-by: Michal Kalderon <Michal.Kalderon@cavium.com>
Signed-off-by: Ariel Elior <Ariel.Elior@cavium.com>
---
drivers/net/ethernet/qlogic/qed/qed_cxt.c | 6 ++++++
drivers/net/ethernet/qlogic/qed/qed_mcp.c | 10 +++++-----
drivers/net/ethernet/qlogic/qed/qed_rdma.c | 5 ++++-
drivers/net/ethernet/qlogic/qed/qed_sp_commands.c | 1 +
4 files changed, 16 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/qlogic/qed/qed_cxt.c b/drivers/net/ethernet/qlogic/qed/qed_cxt.c
index af106be..afd07ad 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_cxt.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_cxt.c
@@ -2069,6 +2069,12 @@ static void qed_rdma_set_pf_params(struct qed_hwfn *p_hwfn,
num_srqs = min_t(u32, 32 * 1024, p_params->num_srqs);
+ if (p_hwfn->mcp_info->func_info.protocol == QED_PCI_ETH_RDMA) {
+ DP_NOTICE(p_hwfn,
+ "Current day drivers don't support RoCE & iWARP simultaneously on the same PF. Default to RoCE-only\n");
+ p_hwfn->hw_info.personality = QED_PCI_ETH_ROCE;
+ }
+
switch (p_hwfn->hw_info.personality) {
case QED_PCI_ETH_IWARP:
/* Each QP requires one connection */
diff --git a/drivers/net/ethernet/qlogic/qed/qed_mcp.c b/drivers/net/ethernet/qlogic/qed/qed_mcp.c
index 376485d..8b99c7d 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_mcp.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_mcp.c
@@ -1691,12 +1691,12 @@ int qed_mcp_get_media_type(struct qed_dev *cdev, u32 *p_media_type)
case FW_MB_PARAM_GET_PF_RDMA_ROCE:
*p_proto = QED_PCI_ETH_ROCE;
break;
- case FW_MB_PARAM_GET_PF_RDMA_BOTH:
- DP_NOTICE(p_hwfn,
- "Current day drivers don't support RoCE & iWARP. Default to RoCE-only\n");
- *p_proto = QED_PCI_ETH_ROCE;
- break;
case FW_MB_PARAM_GET_PF_RDMA_IWARP:
+ *p_proto = QED_PCI_ETH_IWARP;
+ break;
+ case FW_MB_PARAM_GET_PF_RDMA_BOTH:
+ *p_proto = QED_PCI_ETH_RDMA;
+ break;
default:
DP_NOTICE(p_hwfn,
"MFW answers GET_PF_RDMA_PROTOCOL but param is %08x\n",
diff --git a/drivers/net/ethernet/qlogic/qed/qed_rdma.c b/drivers/net/ethernet/qlogic/qed/qed_rdma.c
index 6fb9951..06715f7 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_rdma.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_rdma.c
@@ -156,7 +156,10 @@ static int qed_rdma_alloc(struct qed_hwfn *p_hwfn,
return rc;
p_hwfn->p_rdma_info = p_rdma_info;
- p_rdma_info->proto = PROTOCOLID_ROCE;
+ if (QED_IS_IWARP_PERSONALITY(p_hwfn))
+ p_rdma_info->proto = PROTOCOLID_IWARP;
+ else
+ p_rdma_info->proto = PROTOCOLID_ROCE;
num_cons = qed_cxt_get_proto_cid_count(p_hwfn, p_rdma_info->proto,
NULL);
diff --git a/drivers/net/ethernet/qlogic/qed/qed_sp_commands.c b/drivers/net/ethernet/qlogic/qed/qed_sp_commands.c
index 46d0c3c..a1d33f3 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_sp_commands.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_sp_commands.c
@@ -377,6 +377,7 @@ int qed_sp_pf_start(struct qed_hwfn *p_hwfn,
p_ramrod->personality = PERSONALITY_ISCSI;
break;
case QED_PCI_ETH_ROCE:
+ case QED_PCI_ETH_IWARP:
p_ramrod->personality = PERSONALITY_RDMA_AND_ETH;
break;
default:
--
1.8.3.1
^ permalink raw reply related
* [PATCH v2 net-next 0/4] qed: iWARP fixes and enhancements
From: Michal Kalderon @ 2017-09-24 9:09 UTC (permalink / raw)
To: davem, netdev, leon; +Cc: linux-rdma, dledford, Michal Kalderon, Ariel Elior
This patch series includes several fixes and enhancements
related to iWARP.
Patch #1 is actually the last of the initial iWARP submission.
It has been delayed until now as I wanted to make sure that qedr
supports iWARP prior to enabling iWARP device detection.
iWARP changes in RDMA tree have been accepted and targeted at
kernel 4.15, therefore, all iWARP fixes for this cycle are
submitted to net-next.
Changes from v1->v2
- Added "Fixes:" tag to commit message of patch #3
Signed-off by: Michal.Kalderon@cavium.com
Signed-off-by: Ariel Elior <Ariel.Elior@cavium.com>
Michal Kalderon (4):
qed: Add iWARP enablement support
qed: Add iWARP out of order support
qed: Fix maximum number of CQs for iWARP
qed: iWARP - Add check for errors on a SYN packet
drivers/net/ethernet/qlogic/qed/qed_cxt.c | 6 +++
drivers/net/ethernet/qlogic/qed/qed_iwarp.c | 52 +++++++++++++++++++++++
drivers/net/ethernet/qlogic/qed/qed_iwarp.h | 11 ++++-
drivers/net/ethernet/qlogic/qed/qed_ll2.c | 1 +
drivers/net/ethernet/qlogic/qed/qed_mcp.c | 10 ++---
drivers/net/ethernet/qlogic/qed/qed_rdma.c | 24 +++++++----
drivers/net/ethernet/qlogic/qed/qed_sp_commands.c | 1 +
include/linux/qed/qed_ll2_if.h | 1 +
8 files changed, 91 insertions(+), 15 deletions(-)
--
1.8.3.1
^ permalink raw reply
* [PATCH v2 net-next 4/4] qed: iWARP - Add check for errors on a SYN packet
From: Michal Kalderon @ 2017-09-24 9:09 UTC (permalink / raw)
To: davem-fT/PcQaiUtIeIZ0/mPfg9Q, netdev-u79uwXL29TY76Z2rM5mHXA,
leon-DgEjT+Ai2ygdnm+yROfE0A
Cc: linux-rdma-u79uwXL29TY76Z2rM5mHXA,
dledford-H+wXaHxf7aLQT0dZR+AlfA, Michal Kalderon, Ariel Elior
In-Reply-To: <1506244185-2129-1-git-send-email-Michal.Kalderon-YGCgFSpz5w/QT0dZR+AlfA@public.gmane.org>
A SYN packet which arrives with errors from FW should be dropped.
This required adding an additional field to the ll2
rx completion data.
Signed-off-by: Michal Kalderon <Michal.Kalderon-YGCgFSpz5w/QT0dZR+AlfA@public.gmane.org>
Signed-off-by: Ariel Elior <Ariel.Elior-YGCgFSpz5w/QT0dZR+AlfA@public.gmane.org>
---
drivers/net/ethernet/qlogic/qed/qed_iwarp.c | 8 ++++++++
drivers/net/ethernet/qlogic/qed/qed_ll2.c | 1 +
include/linux/qed/qed_ll2_if.h | 1 +
3 files changed, 10 insertions(+)
diff --git a/drivers/net/ethernet/qlogic/qed/qed_iwarp.c b/drivers/net/ethernet/qlogic/qed/qed_iwarp.c
index 568e985..8fc9c811 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_iwarp.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_iwarp.c
@@ -1733,6 +1733,14 @@ int qed_iwarp_reject(void *rdma_cxt, struct qed_iwarp_reject_in *iparams)
memset(&cm_info, 0, sizeof(cm_info));
ll2_syn_handle = p_hwfn->p_rdma_info->iwarp.ll2_syn_handle;
+
+ /* Check if packet was received with errors... */
+ if (data->err_flags) {
+ DP_NOTICE(p_hwfn, "Error received on SYN packet: 0x%x\n",
+ data->err_flags);
+ goto err;
+ }
+
if (GET_FIELD(data->parse_flags,
PARSING_AND_ERR_FLAGS_L4CHKSMWASCALCULATED) &&
GET_FIELD(data->parse_flags, PARSING_AND_ERR_FLAGS_L4CHKSMERROR)) {
diff --git a/drivers/net/ethernet/qlogic/qed/qed_ll2.c b/drivers/net/ethernet/qlogic/qed/qed_ll2.c
index c06ad4f..250afa5 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_ll2.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_ll2.c
@@ -413,6 +413,7 @@ static void qed_ll2_rxq_parse_reg(struct qed_hwfn *p_hwfn,
struct qed_ll2_comp_rx_data *data)
{
data->parse_flags = le16_to_cpu(p_cqe->rx_cqe_fp.parse_flags.flags);
+ data->err_flags = le16_to_cpu(p_cqe->rx_cqe_fp.err_flags.flags);
data->length.packet_length =
le16_to_cpu(p_cqe->rx_cqe_fp.packet_length);
data->vlan = le16_to_cpu(p_cqe->rx_cqe_fp.vlan);
diff --git a/include/linux/qed/qed_ll2_if.h b/include/linux/qed/qed_ll2_if.h
index dd7a3b8..89fa0bb 100644
--- a/include/linux/qed/qed_ll2_if.h
+++ b/include/linux/qed/qed_ll2_if.h
@@ -101,6 +101,7 @@ struct qed_ll2_comp_rx_data {
void *cookie;
dma_addr_t rx_buf_addr;
u16 parse_flags;
+ u16 err_flags;
u16 vlan;
bool b_last_packet;
u8 connection_handle;
--
1.8.3.1
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH v2 net-next 3/4] qed: Fix maximum number of CQs for iWARP
From: Michal Kalderon @ 2017-09-24 9:09 UTC (permalink / raw)
To: davem-fT/PcQaiUtIeIZ0/mPfg9Q, netdev-u79uwXL29TY76Z2rM5mHXA,
leon-DgEjT+Ai2ygdnm+yROfE0A
Cc: linux-rdma-u79uwXL29TY76Z2rM5mHXA,
dledford-H+wXaHxf7aLQT0dZR+AlfA, Michal Kalderon, Ariel Elior
In-Reply-To: <1506244185-2129-1-git-send-email-Michal.Kalderon-YGCgFSpz5w/QT0dZR+AlfA@public.gmane.org>
The maximum number of CQs supported is bound to the number
of connections supported, which differs between RoCE and iWARP.
This fixes a crash that occurred in iWARP when running 1000 sessions
using perftest.
Fixes: 67b40dccc45 ("qed: Implement iWARP initialization, teardown and qp operations")
Signed-off-by: Michal Kalderon <Michal.Kalderon-YGCgFSpz5w/QT0dZR+AlfA@public.gmane.org>
Signed-off-by: Ariel Elior <Ariel.Elior-YGCgFSpz5w/QT0dZR+AlfA@public.gmane.org>
---
drivers/net/ethernet/qlogic/qed/qed_rdma.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/qlogic/qed/qed_rdma.c b/drivers/net/ethernet/qlogic/qed/qed_rdma.c
index 4f46f28..c8c4b39 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_rdma.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_rdma.c
@@ -209,11 +209,11 @@ static int qed_rdma_alloc(struct qed_hwfn *p_hwfn,
goto free_pd_map;
}
- /* Allocate bitmap for cq's. The maximum number of CQs is bounded to
- * twice the number of QPs.
+ /* Allocate bitmap for cq's. The maximum number of CQs is bound to
+ * the number of connections we support. (num_qps in iWARP or
+ * num_qps/2 in RoCE).
*/
- rc = qed_rdma_bmap_alloc(p_hwfn, &p_rdma_info->cq_map,
- p_rdma_info->num_qps * 2, "CQ");
+ rc = qed_rdma_bmap_alloc(p_hwfn, &p_rdma_info->cq_map, num_cons, "CQ");
if (rc) {
DP_VERBOSE(p_hwfn, QED_MSG_RDMA,
"Failed to allocate cq bitmap, rc = %d\n", rc);
@@ -222,10 +222,10 @@ static int qed_rdma_alloc(struct qed_hwfn *p_hwfn,
/* Allocate bitmap for toggle bit for cq icids
* We toggle the bit every time we create or resize cq for a given icid.
- * The maximum number of CQs is bounded to twice the number of QPs.
+ * Size needs to equal the size of the cq bmap.
*/
rc = qed_rdma_bmap_alloc(p_hwfn, &p_rdma_info->toggle_bits,
- p_rdma_info->num_qps * 2, "Toggle");
+ num_cons, "Toggle");
if (rc) {
DP_VERBOSE(p_hwfn, QED_MSG_RDMA,
"Failed to allocate toogle bits, rc = %d\n", rc);
--
1.8.3.1
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* Re: [PATCH net-next] bpf/verifier: improve disassembly of BPF_END instructions
From: Alexei Starovoitov @ 2017-09-24 5:50 UTC (permalink / raw)
To: Y Song
Cc: Edward Cree, Daniel Borkmann, David Miller, netdev, Jiong Wang,
Jakub Kicinski
In-Reply-To: <CAH3MdRUCPNzXHQRQtVp7-p9XLDbJrkhxYEe=c0Fkt4+D9Tk9sw@mail.gmail.com>
On Fri, Sep 22, 2017 at 09:49:10PM -0700, Y Song wrote:
> On Fri, Sep 22, 2017 at 9:23 AM, Edward Cree <ecree@solarflare.com> wrote:
> > On 22/09/17 16:16, Alexei Starovoitov wrote:
> >> looks like we're converging on
> >> "be16/be32/be64/le16/le32/le64 #register" for BPF_END.
> >> I guess it can live with that. I would prefer more C like syntax
> >> to match the rest, but llvm parsing point is a strong one.
> > Yep, agreed. I'll post a v2 once we've settled BPF_NEG.
> >> For BPG_NEG I prefer to do it in C syntax like interpreter does:
> >> ALU_NEG:
> >> DST = (u32) -DST;
> >> ALU64_NEG:
> >> DST = -DST;
> >> Yonghong, does it mean that asmparser will equally suffer?
> > Correction to my earlier statements: verifier will currently disassemble
> > neg as:
> > (87) r0 neg 0
> > (84) (u32) r0 neg (u32) 0
> > because it pretends 'neg' is a compound-assignment operator like +=.
> > The analogy with be16 and friends would be to use
> > neg64 r0
> > neg32 r0
> > whereas the analogy with everything else would be
> > r0 = -r0
> > r0 = (u32) -r0
> > as Alexei says.
> > I'm happy to go with Alexei's version if it doesn't cause problems for llvm.
>
> I got some time to do some prototyping in llvm and it looks like that
> I am able to
> resolve the issue and we are able to use more C-like syntax. That is:
> for bswap:
> r1 = (be16) (u16) r1
> or
> r1 = (be16) r1
> or
> r1 = be16 r1
> for neg:
> r0 = -r0
> (for 32bit support, llvm may output "w0 = -w0" in the future. But
> since it is not
> enabled yet, you can continue to output "r0 = (u32) -r0".)
>
> Not sure which syntax is best for bswap. The "r1 = (be16) (u16) r1" is most
> explicit in its intention.
>
> Attaching my llvm patch as well and cc'ing Jiong and Jakub so they can see my
> implementation and the relative discussion here. (In this patch, I did
> not implement
> bswap for little endian yet.) Maybe they can provide additional comments.
This is awesome. In such case I'd like to swing back to the C syntax for bpf_end :)
Any of these
r1 = (be16) (u16) r1
or
r1 = (be16) r1
or
r1 = be16 r1
are better than just
be16 r1
I like 1st the most, since it's explicit in terms of what happens with upper bits,
but 2nd is also ok. 3rd is not quite C-like.
^ permalink raw reply
* [PATCH] mac80211: aead api to reduce redundancy
From: Xiang Gao @ 2017-09-24 5:40 UTC (permalink / raw)
To: herbert, davem, johannes, linux-crypto, linux-kernel,
linux-wireless, netdev
Cc: qasdfgtyuiop
Currently, the aes_ccm.c and aes_gcm.c are almost line by line
copy of each other. This patch reduce code redundancy by moving
the code in these two files to crypto/aead_api.c to make it a
higher level aead api. The aes_ccm.c and aes_gcm.c are removed
and all the functions are now implemented in their headers using
the newly added aead api.
Signed-off-by: Xiang Gao <qasdfgtyuiop@gmail.com>
---
crypto/Makefile | 2 +-
net/mac80211/aes_gcm.c => crypto/aead_api.c | 53 +++++++------
include/crypto/aead_api.h | 21 +++++
net/mac80211/Makefile | 2 -
net/mac80211/aes_ccm.c | 115 ----------------------------
net/mac80211/aes_ccm.h | 42 +++++++---
net/mac80211/aes_gcm.h | 40 ++++++++--
net/mac80211/key.c | 1 +
net/mac80211/wpa.c | 11 +--
9 files changed, 118 insertions(+), 169 deletions(-)
rename net/mac80211/aes_gcm.c => crypto/aead_api.c (54%)
create mode 100644 include/crypto/aead_api.h
delete mode 100644 net/mac80211/aes_ccm.c
diff --git a/crypto/Makefile b/crypto/Makefile
index d41f0331b085..541316db5841 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -14,7 +14,7 @@ crypto_algapi-$(CONFIG_PROC_FS) += proc.o
crypto_algapi-y := algapi.o scatterwalk.o $(crypto_algapi-y)
obj-$(CONFIG_CRYPTO_ALGAPI2) += crypto_algapi.o
-obj-$(CONFIG_CRYPTO_AEAD2) += aead.o
+obj-$(CONFIG_CRYPTO_AEAD2) += aead.o aead_api.o
crypto_blkcipher-y := ablkcipher.o
crypto_blkcipher-y += blkcipher.o
diff --git a/net/mac80211/aes_gcm.c b/crypto/aead_api.c
similarity index 54%
rename from net/mac80211/aes_gcm.c
rename to crypto/aead_api.c
index 8a4397cc1b08..9585ee400b2e 100644
--- a/net/mac80211/aes_gcm.c
+++ b/crypto/aead_api.c
@@ -1,7 +1,4 @@
-/*
- * Copyright 2014-2015, Qualcomm Atheros, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
+/* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
@@ -9,43 +6,43 @@
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/err.h>
-#include <crypto/aead.h>
+#include <linux/scatterlist.h>
-#include <net/mac80211.h>
-#include "key.h"
-#include "aes_gcm.h"
+#include <crypto/aead_api.h>
-int ieee80211_aes_gcm_encrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad,
- u8 *data, size_t data_len, u8 *mic)
+int aead_encrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad, size_t aad_len,
+ u8 *data, size_t data_len, u8 *auth)
{
struct scatterlist sg[3];
struct aead_request *aead_req;
int reqsize = sizeof(*aead_req) + crypto_aead_reqsize(tfm);
u8 *__aad;
- aead_req = kzalloc(reqsize + GCM_AAD_LEN, GFP_ATOMIC);
+ aead_req = kzalloc(reqsize + aad_len, GFP_ATOMIC);
if (!aead_req)
return -ENOMEM;
__aad = (u8 *)aead_req + reqsize;
- memcpy(__aad, aad, GCM_AAD_LEN);
+ memcpy(__aad, aad, aad_len);
sg_init_table(sg, 3);
- sg_set_buf(&sg[0], &__aad[2], be16_to_cpup((__be16 *)__aad));
+ sg_set_buf(&sg[0], __aad, aad_len);
sg_set_buf(&sg[1], data, data_len);
- sg_set_buf(&sg[2], mic, IEEE80211_GCMP_MIC_LEN);
+ sg_set_buf(&sg[2], auth, tfm->authsize);
aead_request_set_tfm(aead_req, tfm);
- aead_request_set_crypt(aead_req, sg, sg, data_len, j_0);
+ aead_request_set_crypt(aead_req, sg, sg, data_len, b_0);
aead_request_set_ad(aead_req, sg[0].length);
crypto_aead_encrypt(aead_req);
kzfree(aead_req);
+
return 0;
}
+EXPORT_SYMBOL_GPL(aead_encrypt);
-int ieee80211_aes_gcm_decrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad,
- u8 *data, size_t data_len, u8 *mic)
+int aead_decrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad, size_t aad_len,
+ u8 *data, size_t data_len, u8 *auth)
{
struct scatterlist sg[3];
struct aead_request *aead_req;
@@ -56,21 +53,20 @@ int ieee80211_aes_gcm_decrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad,
if (data_len == 0)
return -EINVAL;
- aead_req = kzalloc(reqsize + GCM_AAD_LEN, GFP_ATOMIC);
+ aead_req = kzalloc(reqsize + aad_len, GFP_ATOMIC);
if (!aead_req)
return -ENOMEM;
__aad = (u8 *)aead_req + reqsize;
- memcpy(__aad, aad, GCM_AAD_LEN);
+ memcpy(__aad, aad, aad_len);
sg_init_table(sg, 3);
sg_set_buf(&sg[0], &__aad[2], be16_to_cpup((__be16 *)__aad));
sg_set_buf(&sg[1], data, data_len);
- sg_set_buf(&sg[2], mic, IEEE80211_GCMP_MIC_LEN);
+ sg_set_buf(&sg[2], auth, tfm->authsize);
aead_request_set_tfm(aead_req, tfm);
- aead_request_set_crypt(aead_req, sg, sg,
- data_len + IEEE80211_GCMP_MIC_LEN, j_0);
+ aead_request_set_crypt(aead_req, sg, sg, data_len + tfm->authsize, b_0);
aead_request_set_ad(aead_req, sg[0].length);
err = crypto_aead_decrypt(aead_req);
@@ -78,21 +74,22 @@ int ieee80211_aes_gcm_decrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad,
return err;
}
+EXPORT_SYMBOL_GPL(aead_decrypt);
-struct crypto_aead *ieee80211_aes_gcm_key_setup_encrypt(const u8 key[],
- size_t key_len)
+struct crypto_aead *aead_key_setup_encrypt(const char *alg,
+ const u8 key[], size_t key_len, size_t authsize)
{
struct crypto_aead *tfm;
int err;
- tfm = crypto_alloc_aead("gcm(aes)", 0, CRYPTO_ALG_ASYNC);
+ tfm = crypto_alloc_aead(alg, 0, CRYPTO_ALG_ASYNC);
if (IS_ERR(tfm))
return tfm;
err = crypto_aead_setkey(tfm, key, key_len);
if (err)
goto free_aead;
- err = crypto_aead_setauthsize(tfm, IEEE80211_GCMP_MIC_LEN);
+ err = crypto_aead_setauthsize(tfm, authsize);
if (err)
goto free_aead;
@@ -102,8 +99,10 @@ struct crypto_aead *ieee80211_aes_gcm_key_setup_encrypt(const u8 key[],
crypto_free_aead(tfm);
return ERR_PTR(err);
}
+EXPORT_SYMBOL_GPL(aead_key_setup_encrypt);
-void ieee80211_aes_gcm_key_free(struct crypto_aead *tfm)
+void aead_key_free(struct crypto_aead *tfm)
{
crypto_free_aead(tfm);
}
+EXPORT_SYMBOL_GPL(aead_key_free);
diff --git a/include/crypto/aead_api.h b/include/crypto/aead_api.h
new file mode 100644
index 000000000000..45deda0d538f
--- /dev/null
+++ b/include/crypto/aead_api.h
@@ -0,0 +1,21 @@
+/* This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef _AEAD_API_H
+#define _AEAD_API_H
+
+#include <crypto/aead.h>
+#include <linux/crypto.h>
+
+struct crypto_aead *aead_key_setup_encrypt(const char *alg,
+ const u8 key[], size_t key_len, size_t authsize);
+
+int aead_encrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad,
+ size_t aad_len, u8 *data, size_t data_len, u8 *auth);
+int aead_decrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad,
+ size_t aad_len, u8 *data, size_t data_len, u8 *auth);
+void aead_key_free(struct crypto_aead *tfm);
+
+#endif /* _AEAD_API_H */
diff --git a/net/mac80211/Makefile b/net/mac80211/Makefile
index 282912245938..f1efc8c81ce6 100644
--- a/net/mac80211/Makefile
+++ b/net/mac80211/Makefile
@@ -15,8 +15,6 @@ mac80211-y := \
rate.o \
michael.o \
tkip.o \
- aes_ccm.o \
- aes_gcm.o \
aes_cmac.o \
aes_gmac.o \
fils_aead.o \
diff --git a/net/mac80211/aes_ccm.c b/net/mac80211/aes_ccm.c
deleted file mode 100644
index a4e0d59a40dd..000000000000
--- a/net/mac80211/aes_ccm.c
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright 2003-2004, Instant802 Networks, Inc.
- * Copyright 2005-2006, Devicescape Software, Inc.
- *
- * Rewrite: Copyright (C) 2013 Linaro Ltd <ard.biesheuvel@linaro.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/err.h>
-#include <crypto/aead.h>
-
-#include <net/mac80211.h>
-#include "key.h"
-#include "aes_ccm.h"
-
-int ieee80211_aes_ccm_encrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad,
- u8 *data, size_t data_len, u8 *mic,
- size_t mic_len)
-{
- struct scatterlist sg[3];
- struct aead_request *aead_req;
- int reqsize = sizeof(*aead_req) + crypto_aead_reqsize(tfm);
- u8 *__aad;
-
- aead_req = kzalloc(reqsize + CCM_AAD_LEN, GFP_ATOMIC);
- if (!aead_req)
- return -ENOMEM;
-
- __aad = (u8 *)aead_req + reqsize;
- memcpy(__aad, aad, CCM_AAD_LEN);
-
- sg_init_table(sg, 3);
- sg_set_buf(&sg[0], &__aad[2], be16_to_cpup((__be16 *)__aad));
- sg_set_buf(&sg[1], data, data_len);
- sg_set_buf(&sg[2], mic, mic_len);
-
- aead_request_set_tfm(aead_req, tfm);
- aead_request_set_crypt(aead_req, sg, sg, data_len, b_0);
- aead_request_set_ad(aead_req, sg[0].length);
-
- crypto_aead_encrypt(aead_req);
- kzfree(aead_req);
-
- return 0;
-}
-
-int ieee80211_aes_ccm_decrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad,
- u8 *data, size_t data_len, u8 *mic,
- size_t mic_len)
-{
- struct scatterlist sg[3];
- struct aead_request *aead_req;
- int reqsize = sizeof(*aead_req) + crypto_aead_reqsize(tfm);
- u8 *__aad;
- int err;
-
- if (data_len == 0)
- return -EINVAL;
-
- aead_req = kzalloc(reqsize + CCM_AAD_LEN, GFP_ATOMIC);
- if (!aead_req)
- return -ENOMEM;
-
- __aad = (u8 *)aead_req + reqsize;
- memcpy(__aad, aad, CCM_AAD_LEN);
-
- sg_init_table(sg, 3);
- sg_set_buf(&sg[0], &__aad[2], be16_to_cpup((__be16 *)__aad));
- sg_set_buf(&sg[1], data, data_len);
- sg_set_buf(&sg[2], mic, mic_len);
-
- aead_request_set_tfm(aead_req, tfm);
- aead_request_set_crypt(aead_req, sg, sg, data_len + mic_len, b_0);
- aead_request_set_ad(aead_req, sg[0].length);
-
- err = crypto_aead_decrypt(aead_req);
- kzfree(aead_req);
-
- return err;
-}
-
-struct crypto_aead *ieee80211_aes_key_setup_encrypt(const u8 key[],
- size_t key_len,
- size_t mic_len)
-{
- struct crypto_aead *tfm;
- int err;
-
- tfm = crypto_alloc_aead("ccm(aes)", 0, CRYPTO_ALG_ASYNC);
- if (IS_ERR(tfm))
- return tfm;
-
- err = crypto_aead_setkey(tfm, key, key_len);
- if (err)
- goto free_aead;
- err = crypto_aead_setauthsize(tfm, mic_len);
- if (err)
- goto free_aead;
-
- return tfm;
-
-free_aead:
- crypto_free_aead(tfm);
- return ERR_PTR(err);
-}
-
-void ieee80211_aes_key_free(struct crypto_aead *tfm)
-{
- crypto_free_aead(tfm);
-}
diff --git a/net/mac80211/aes_ccm.h b/net/mac80211/aes_ccm.h
index fcd3254c5cf0..b51ef23201c1 100644
--- a/net/mac80211/aes_ccm.h
+++ b/net/mac80211/aes_ccm.h
@@ -10,19 +10,39 @@
#ifndef AES_CCM_H
#define AES_CCM_H
-#include <linux/crypto.h>
+#include <crypto/aead_api.h>
#define CCM_AAD_LEN 32
-struct crypto_aead *ieee80211_aes_key_setup_encrypt(const u8 key[],
- size_t key_len,
- size_t mic_len);
-int ieee80211_aes_ccm_encrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad,
- u8 *data, size_t data_len, u8 *mic,
- size_t mic_len);
-int ieee80211_aes_ccm_decrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad,
- u8 *data, size_t data_len, u8 *mic,
- size_t mic_len);
-void ieee80211_aes_key_free(struct crypto_aead *tfm);
+static inline struct crypto_aead *ieee80211_aes_key_setup_encrypt(
+ const u8 key[], size_t key_len, size_t mic_len)
+{
+ return aead_key_setup_encrypt("ccm(aes)", key, key_len, mic_len);
+}
+
+static inline int ieee80211_aes_ccm_encrypt(
+ struct crypto_aead *tfm,
+ u8 *b_0, u8 *aad, u8 *data,
+ size_t data_len, u8 *mic)
+{
+ return aead_encrypt(tfm, b_0, aad + 2,
+ be16_to_cpup((__be16 *)aad),
+ data, data_len, mic);
+}
+
+static inline int ieee80211_aes_ccm_decrypt(
+ struct crypto_aead *tfm,
+ u8 *b_0, u8 *aad, u8 *data,
+ size_t data_len, u8 *mic)
+{
+ return aead_decrypt(tfm, b_0, aad + 2,
+ be16_to_cpup((__be16 *)aad),
+ data, data_len, mic);
+}
+
+static inline void ieee80211_aes_key_free(struct crypto_aead *tfm)
+{
+ return aead_key_free(tfm);
+}
#endif /* AES_CCM_H */
diff --git a/net/mac80211/aes_gcm.h b/net/mac80211/aes_gcm.h
index 55aed5352494..f07359d5ebbd 100644
--- a/net/mac80211/aes_gcm.h
+++ b/net/mac80211/aes_gcm.h
@@ -9,16 +9,40 @@
#ifndef AES_GCM_H
#define AES_GCM_H
-#include <linux/crypto.h>
+#include <crypto/aead_api.h>
#define GCM_AAD_LEN 32
-int ieee80211_aes_gcm_encrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad,
- u8 *data, size_t data_len, u8 *mic);
-int ieee80211_aes_gcm_decrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad,
- u8 *data, size_t data_len, u8 *mic);
-struct crypto_aead *ieee80211_aes_gcm_key_setup_encrypt(const u8 key[],
- size_t key_len);
-void ieee80211_aes_gcm_key_free(struct crypto_aead *tfm);
+static inline int ieee80211_aes_gcm_encrypt(
+ struct crypto_aead *tfm,
+ u8 *j_0, u8 *aad, u8 *data,
+ size_t data_len, u8 *mic)
+{
+ return aead_encrypt(tfm, j_0, aad + 2,
+ be16_to_cpup((__be16 *)aad),
+ data, data_len, mic);
+}
+
+static inline int ieee80211_aes_gcm_decrypt(
+ struct crypto_aead *tfm,
+ u8 *j_0, u8 *aad, u8 *data,
+ size_t data_len, u8 *mic)
+{
+ return aead_decrypt(tfm, j_0, aad + 2,
+ be16_to_cpup((__be16 *)aad),
+ data, data_len, mic);
+}
+
+static inline struct crypto_aead *ieee80211_aes_gcm_key_setup_encrypt(
+ const u8 key[], size_t key_len)
+{
+ return aead_key_setup_encrypt("gcm(aes)", key,
+ key_len, IEEE80211_GCMP_MIC_LEN);
+}
+
+static inline void ieee80211_aes_gcm_key_free(struct crypto_aead *tfm)
+{
+ return aead_key_free(tfm);
+}
#endif /* AES_GCM_H */
diff --git a/net/mac80211/key.c b/net/mac80211/key.c
index a98fc2b5e0dc..a61cecd078bb 100644
--- a/net/mac80211/key.c
+++ b/net/mac80211/key.c
@@ -18,6 +18,7 @@
#include <linux/rtnetlink.h>
#include <linux/slab.h>
#include <linux/export.h>
+#include <linux/crypto.h>
#include <net/mac80211.h>
#include <asm/unaligned.h>
#include "ieee80211_i.h"
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c
index 0d722ea98a1b..e30e09c1e149 100644
--- a/net/mac80211/wpa.c
+++ b/net/mac80211/wpa.c
@@ -464,7 +464,7 @@ static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb,
pos += IEEE80211_CCMP_HDR_LEN;
ccmp_special_blocks(skb, pn, b_0, aad);
return ieee80211_aes_ccm_encrypt(key->u.ccmp.tfm, b_0, aad, pos, len,
- skb_put(skb, mic_len), mic_len);
+ skb_put(skb, key->u.ccmp.tfm->authsize));
}
@@ -540,10 +540,11 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx,
ccmp_special_blocks(skb, pn, b_0, aad);
if (ieee80211_aes_ccm_decrypt(
- key->u.ccmp.tfm, b_0, aad,
- skb->data + hdrlen + IEEE80211_CCMP_HDR_LEN,
- data_len,
- skb->data + skb->len - mic_len, mic_len))
+ key->u.ccmp.tfm, b_0, aad,
+ skb->data + hdrlen + IEEE80211_CCMP_HDR_LEN,
+ data_len,
+ skb->data + skb->len - key->u.ccmp.tfm->authsize
+ ))
return RX_DROP_UNUSABLE;
}
--
2.14.1
^ permalink raw reply related
* Re: [PATCH 1/1] forcedeth: optimize the xmit/rx with unlikely
From: David Miller @ 2017-09-24 3:04 UTC (permalink / raw)
To: yanjun.zhu; +Cc: jarod, netdev
In-Reply-To: <1506090021-16489-1-git-send-email-yanjun.zhu@oracle.com>
From: Zhu Yanjun <yanjun.zhu@oracle.com>
Date: Fri, 22 Sep 2017 10:20:21 -0400
> In the xmit/rx fastpath, the function dma_map_single rarely fails.
> Therefore, add an unlikely() optimization to this error check
> conditional.
>
> Signed-off-by: Zhu Yanjun <yanjun.zhu@oracle.com>
Applied to net-next, thanks.
^ permalink raw reply
* Re: [PATCH net] net: qualcomm: rmnet: Fix rcu splat in rmnet_is_real_dev_registered
From: David Miller @ 2017-09-24 3:00 UTC (permalink / raw)
To: subashab; +Cc: xiaolong.ye, netdev
In-Reply-To: <1506038436-4865-1-git-send-email-subashab@codeaurora.org>
From: Subash Abhinov Kasiviswanathan <subashab@codeaurora.org>
Date: Thu, 21 Sep 2017 18:00:36 -0600
> Xiaolong reported a suspicious rcu_dereference_check in the device
> unregister notifier callback. Since we do not dereference the
> rx_handler_data, it's ok to just check for the value of the pointer.
> Note that this section is already protected by rtnl_lock.
...
> Fixes: ceed73a2cf4a ("drivers: net: ethernet: qualcomm: rmnet: Initial implementation")
> Signed-off-by: Subash Abhinov Kasiviswanathan <subashab@codeaurora.org>
> Reported-by: kernel test robot <xiaolong.ye@intel.com>
Applied, thank you.
^ permalink raw reply
* Re: [PATCH net-next 09/14] gtp: Allow configuring GTP interface as standalone
From: Harald Welte @ 2017-09-24 2:16 UTC (permalink / raw)
To: Tom Herbert
Cc: Andreas Schultz, Tom Herbert, David S. Miller,
Linux Kernel Network Developers, Pablo Neira Ayuso, Rohit Seth
In-Reply-To: <CAPDqMeq69rjzPh8jo-G9gKT26h-br4OrE0yxTJGk97qRgX0K2A@mail.gmail.com>
Hi Tom,
On Thu, Sep 21, 2017 at 09:43:02AM -0700, Tom Herbert wrote:
> Please see the cover letter for the original GTP kernel patches dated
> May 10, 2016. My first question on those was "Is there a timeline for
> adding IPv6 support?". To which Pablo replied that there was a
> preliminary patch for it that has not been released.
I'll suggest Pablo to comment on that. I don't recall the details at
that time, I was only involved in the earliest development of the module
and then handed over.
> If you don't like my patches or don't think that can be adapted to
> fully support the GTP specification, that's fine.
It's not about "not liking". I'm very happy about contributions,
including (of course) yours. It's about making sure that code we merge
into the kernel GTP driver will actually be usable to create a
standards-compliant GTP application or not.
There's no use in merging an IPv6 support patch if already by code
review it can be shown that it's impossible to create a spec-compliant
implementation using that patch. To me, that would be "merging IPv6
support so we can check off a box on a management form or marketing
sheet", but not for any practical value.
> But then you need to provide a viable alternative.
Why do *I* have to provide a viable alternative? Who says that *I* have
an obligation to do so? A (co-)maintainer of a given driver doesn't
have the obligation of implementing any feature as requested.
Community based collaborative development only gets those things done
that people contribute. I have already contributed almost a decade of
my life to creating Free Software implementations of cellular protocol
stacks, and it continues to be the center of my work and spare time.
GTP is only one protocol layer on one of those stacks.
Pablo, Andreas and I have contributed a Linux kernel implementation that
currently only implements IPv4. This implementation can by anyone
extended to support IPv6, and as you see from this e-mail thread, there
is interest in helping this along by
* providing code review (even at times when it's personally difficult
for me)
* providing free hardware for setting up a "private cellular network"
to test interoperability
* providing testing tools for validation in absence of such a cellular
network
> We are at the point where a kernel networking feature that only
> supports IPv4 when it could support IPv6 must be considered
> incomplete.
I agree it is incomplete. There's no doubt about that. But then,
even the current "incomplete" implementation is working and can be used
to operate an interoperable, spec-compatible IPv4 GGSN. So it serves a
practical purpose. All I'm asking is that any IPv6 support patches are
developed with that same practical purpose in mind.
Going through the cover letter of your series again:
> - IPv6 support
Cannot be merged as-is, see lengthy review discussion
> - Configurable networking interfaces so that GTP kernel can be
> used and tested without needing GSN network emulation (i.e. no user
> space daemon needed).
> - Port numbers are configurable
As I indicated, I'm not fundamentally opposed to it, but I'm wondering
how much value they bring in reality. Andreas has raised the valid
concern that we're adding code that is not used in production setups or
by any of the userspace implementations using this tunneling module.
The code gets more complex and gets code paths that will not be
exercised/tested.
Nevertheless, if it helps you to work on GTP, we can merge them from my
point of view - unless Pablo and/or Andreas object more strongly.
> - GSO,GRO
> - A facility that allows application specific GSO callbacks
Fine with me, but I think you need to convince other folks about the
"application specific GSO" and the usage of the upper bits of
shinfo(skb)->gso_type.
> - Control of zero UDP checksums
Same as above, Dave was raising some question about it, not sure if
his concern remains.
> - Addition of a dst_cache in the GTP structure
Fine with me.
As for the patches touching gtp.c:
* 04/14 udp recv clean up:
fine with me, but kbuild robot complaint?
On a minor note, I think you're mixing two unrelated topics:
Separating the UDP receive functions and conversion to gro_cells,
which violates the "one patch per feature" rule. I'd still
merge it, but would prefer two separate patches
* 05/14 Remove special mtu handling
Pending your rework
* 06/14 Eliminate pktinfo and add port configuration
I don't like the combination of a non-functional "cosmetic"
refactoring of removing a data structure with the introduction
of a new feature. Makes it harder to review, impossible to
merge only one of the two. For the rationale of introducing the
gtp_pktinfo struct, see
http://git.osmocom.org/osmo-gtp-kernel/commit/?id=3bc7019c7afd06b5c7d94e5621728d092b82bb85
it was actually intended to make IPv6 support easier, but the
partial IPv6 support was removed before mainline submission.
* 07/14 Support encapsulation of IPv6 packets
Not acceptable in its current form, see extensive review
* 08/14 Support encpasulating over IPv6
No concerns in principle. Pending you making it dependent on AF
of socket
* 09/14 Allow configuring GTP interface as standalone
Can be merged unless strong objection from Pablo/Andreas (see above)
* 10/14 Add support for devnet
No concerns from my side
* 12/14 Configuration for zero UDP checksum
Up to Dave, he raised a question on it
* 13/14 Support for GRO
No concerns from my side
* 14/14 GSO support
No concerns from my side
BTW: Where have the iproute2/ip patches been posted, which you mention
in your cover page of the patch series?
--
- Harald Welte <laforge@gnumonks.org> http://laforge.gnumonks.org/
============================================================================
"Privacy in residential applications is a desirable marketing option."
(ETSI EN 300 175-7 Ch. A6)
^ permalink raw reply
* Re: [PATCH net-next 03/14] gtp: Call common functions to get tunnel routes and add dst_cache
From: Harald Welte @ 2017-09-24 1:33 UTC (permalink / raw)
To: Andreas Schultz; +Cc: David Miller, tom, netdev, pablo, rohit
In-Reply-To: <01c68c74-455c-9bff-e5bb-b1708d8f92f4@tpip.net>
Hi Andreas,
On Wed, Sep 20, 2017 at 05:37:52PM +0200, Andreas Schultz wrote:
> I think we had this discussion before. The sending IP and port are not part
> of the identity of the PDP context. So IMHO the sender is permitted
> to change the source IP at random.
Thanks for the reminder: You are correct, at least in the uplink case
(MS->GGSN) where there is mobility of the MS. In the downlink case
(GGSN->MS), which is the "sending" part for the kernel GTP code used at
a GGSN, I'm not sure if that theory holds true in reality.
Do you agree that the current behavior of not using automatic source
address selection for encapsulated GTP packets but rather using the
source address of the socket is intended?
Do you further agree that the dst_cache support patch by Tom retains
that intended behavior and it should be merged?
--
- Harald Welte <laforge@gnumonks.org> http://laforge.gnumonks.org/
============================================================================
"Privacy in residential applications is a desirable marketing option."
(ETSI EN 300 175-7 Ch. A6)
^ permalink raw reply
* [PATCH] staging: rtl8822be: Keep array subscript no lower than zero
From: Larry Finger @ 2017-09-24 0:36 UTC (permalink / raw)
To: gregkh; +Cc: netdev, devel, Larry Finger
The kbuild test robot reports the following:
drivers/staging//rtlwifi/phydm/phydm_dig.c: In function 'odm_pause_dig':
drivers/staging//rtlwifi/phydm/phydm_dig.c:494:45: warning: array subscript is below array bounds [-Warray-bounds]
odm_write_dig(dm, dig_tab->pause_dig_value[max_level]);
This condition is caused when a loop falls through. The fix is to pin
max_level to be >= 0.
Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
c: kbuild test robot <fengguang.wu@intel.com>
Fixes: 9ce99b04b5b82fdf11e4c76b60a5f82c1e541297 staging: r8822be: Add phydm mini driver
---
drivers/staging/rtlwifi/phydm/phydm_dig.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/staging/rtlwifi/phydm/phydm_dig.c b/drivers/staging/rtlwifi/phydm/phydm_dig.c
index 31a4f3fcad19..c88b9788363a 100644
--- a/drivers/staging/rtlwifi/phydm/phydm_dig.c
+++ b/drivers/staging/rtlwifi/phydm/phydm_dig.c
@@ -490,6 +490,8 @@ void odm_pause_dig(void *dm_void, enum phydm_pause_type pause_type,
break;
}
+ /* pin max_level to be >= 0 */
+ max_level = max_t(s8, 0, max_level);
/* write IGI of lower level */
odm_write_dig(dm, dig_tab->pause_dig_value[max_level]);
ODM_RT_TRACE(dm, ODM_COMP_DIG,
--
2.12.3
^ permalink raw reply related
* Re: [Patch net-next] net_sched: use idr to allocate bpf filter handles
From: David Miller @ 2017-09-24 0:15 UTC (permalink / raw)
To: xiyou.wangcong; +Cc: netdev, daniel, chrism, jhs
In-Reply-To: <20170921234302.26558-1-xiyou.wangcong@gmail.com>
From: Cong Wang <xiyou.wangcong@gmail.com>
Date: Thu, 21 Sep 2017 16:43:00 -0700
> @@ -421,27 +427,6 @@ static int cls_bpf_set_parms(struct net *net, struct tcf_proto *tp,
> return 0;
> }
>
> -static u32 cls_bpf_grab_new_handle(struct tcf_proto *tp,
> - struct cls_bpf_head *head)
> -{
> - unsigned int i = 0x80000000;
> - u32 handle;
> -
> - do {
> - if (++head->hgen == 0x7FFFFFFF)
> - head->hgen = 1;
> - } while (--i > 0 && cls_bpf_get(tp, head->hgen));
> -
> - if (unlikely(i == 0)) {
> - pr_err("Insufficient number of handles\n");
> - handle = 0;
> - } else {
> - handle = head->hgen;
> - }
> -
> - return handle;
> -}
> -
If I read the code properly, the existing code allows IDs from '1' to
and including '0x7ffffffe', whereas the new code allows up to and
including '0x7ffffffff'.
Whether intentional or not this is a change in behavior. If it's OK,
it should be at least documented either in a comment or in the
commit log itself.
Similarly for your other scheduler IDR changes.
Thanks.
^ permalink raw reply
* Re: [PATCH] cnic: Fix an error handling path in 'cnic_alloc_bnx2x_resc()'
From: David Miller @ 2017-09-24 0:04 UTC (permalink / raw)
To: christophe.jaillet
Cc: jmaxwell37, stephen, danielj, parav, netdev, linux-kernel,
kernel-janitors
In-Reply-To: <20170921230111.10135-1-christophe.jaillet@wanadoo.fr>
From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
Date: Fri, 22 Sep 2017 01:01:11 +0200
> All the error handling paths 'goto error', except this one.
> We should also go to error in this case, or some resources will be
> leaking.
>
> Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
Applied, thank you.
^ permalink raw reply
* Re: [PATCH net-next v3 3/6] rtnetlink: add helper to dump ifalias
From: Florian Westphal @ 2017-09-23 21:21 UTC (permalink / raw)
To: Eric Dumazet; +Cc: Florian Westphal, netdev
In-Reply-To: <1506200690.29839.217.camel@edumazet-glaptop3.roam.corp.google.com>
Eric Dumazet <eric.dumazet@gmail.com> wrote:
> On Sat, 2017-09-23 at 21:26 +0200, Florian Westphal wrote:
> > Reviewed-by: David Ahern <dsahern@gmail.com>
> > Signed-off-by: Florian Westphal <fw@strlen.de>
> > ---
> > Changes since v3: don't add rtnl assertion, I placed the assertion
> > in my working tree instead as a reminder.
> >
> > net/core/rtnetlink.c | 11 +++++++++--
> > 1 file changed, 9 insertions(+), 2 deletions(-)
> >
> > diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
> > index c801212ee40e..47c17c3de79a 100644
> > --- a/net/core/rtnetlink.c
> > +++ b/net/core/rtnetlink.c
> > @@ -1332,6 +1332,14 @@ static int nla_put_iflink(struct sk_buff *skb, const struct net_device *dev)
> > return nla_put_u32(skb, IFLA_LINK, ifindex);
> > }
> >
> > +static noinline int nla_put_ifalias(struct sk_buff *skb, struct net_device *dev)
>
>
> Why noinline here ?
>
> This function does not use stack at all (and that would call for
> noinline_for_stack )
>
> > +{
> > + if (dev->ifalias)
> > + return nla_put_string(skb, IFLA_IFALIAS, dev->ifalias);
> > +
> > + return 0;
> > +}
> > +
>
> I really do not see the point of not making this RCU aware right away,
> or at least make it in the same patch series...
I saw no point to mix these refactoring with actual change :-|
(and it doesn't help either as-is with netlink dumping, only sysfs path can
elide rtnl).
Subject: [PATCH net-next] net: core: decouple ifalias get/set from rtnl lock
Device alias can be set by either rtnetlink (rtnl is held) or sysfs.
rtnetlink holds rtnl mutex, sysfs acquires it for this purpose.
Add a new mutex for it plus a seqcount to get a consistent snapshot
of the alias buffer.
This allows the sysfs path to not take rtnl and would later allow
to not hold it when dumping ifalias.
Signed-off-by: Florian Westphal <fw@strlen.de>
---
include/linux/netdevice.h | 3 +-
net/core/dev.c | 70 +++++++++++++++++++++++++++++++++++++++--------
net/core/net-sysfs.c | 14 ++++------
net/core/rtnetlink.c | 7 +++--
4 files changed, 70 insertions(+), 24 deletions(-)
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index f535779d9dc1..0bcedb498f6f 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -1632,7 +1632,7 @@ enum netdev_priv_flags {
struct net_device {
char name[IFNAMSIZ];
struct hlist_node name_hlist;
- char *ifalias;
+ char __rcu *ifalias;
/*
* I/O specific fields
* FIXME: Merge these and struct ifmap into one
@@ -3275,6 +3275,7 @@ void __dev_notify_flags(struct net_device *, unsigned int old_flags,
unsigned int gchanges);
int dev_change_name(struct net_device *, const char *);
int dev_set_alias(struct net_device *, const char *, size_t);
+int dev_get_alias(const struct net_device *, char *, size_t);
int dev_change_net_namespace(struct net_device *, struct net *, const char *);
int __dev_set_mtu(struct net_device *, int);
int dev_set_mtu(struct net_device *, int);
diff --git a/net/core/dev.c b/net/core/dev.c
index 97abddd9039a..92d87b4a2db1 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -188,6 +188,9 @@ static struct napi_struct *napi_by_id(unsigned int napi_id);
DEFINE_RWLOCK(dev_base_lock);
EXPORT_SYMBOL(dev_base_lock);
+static DEFINE_MUTEX(ifalias_mutex);
+static seqcount_t ifalias_rename_seq;
+
/* protects napi_hash addition/deletion and napi_gen_id */
static DEFINE_SPINLOCK(napi_hash_lock);
@@ -1265,29 +1268,72 @@ int dev_change_name(struct net_device *dev, const char *newname)
*/
int dev_set_alias(struct net_device *dev, const char *alias, size_t len)
{
- char *new_ifalias;
-
- ASSERT_RTNL();
+ char *new_ifalias, *old_ifalias;
if (len >= IFALIASZ)
return -EINVAL;
+ mutex_lock(&ifalias_mutex);
+
+ old_ifalias = rcu_dereference_protected(dev->ifalias,
+ mutex_is_locked(&ifalias_mutex));
if (!len) {
- kfree(dev->ifalias);
- dev->ifalias = NULL;
- return 0;
+ RCU_INIT_POINTER(dev->ifalias, NULL);
+ goto out;
}
- new_ifalias = krealloc(dev->ifalias, len + 1, GFP_KERNEL);
- if (!new_ifalias)
+ new_ifalias = __krealloc(old_ifalias, len + 1, GFP_KERNEL);
+ if (!new_ifalias) {
+ mutex_unlock(&ifalias_mutex);
return -ENOMEM;
- dev->ifalias = new_ifalias;
- memcpy(dev->ifalias, alias, len);
- dev->ifalias[len] = 0;
+ }
+ if (new_ifalias == old_ifalias) {
+ write_seqcount_begin(&ifalias_rename_seq);
+ memcpy(new_ifalias, alias, len);
+ new_ifalias[len] = 0;
+ write_seqcount_end(&ifalias_rename_seq);
+ mutex_unlock(&ifalias_mutex);
+ return len;
+ }
+
+ memcpy(new_ifalias, alias, len);
+ new_ifalias[len] = 0;
+
+ rcu_assign_pointer(dev->ifalias, new_ifalias);
+out:
+ mutex_unlock(&ifalias_mutex);
+ if (old_ifalias) {
+ synchronize_net();
+ kfree(old_ifalias);
+ }
return len;
}
+int dev_get_alias(const struct net_device *dev, char *alias, size_t len)
+{
+ unsigned int seq;
+ int ret;
+
+ for (;;) {
+ const char *name;
+
+ ret = 0;
+ rcu_read_lock();
+ name = rcu_dereference(dev->ifalias);
+ seq = raw_seqcount_begin(&ifalias_rename_seq);
+ if (name)
+ ret = snprintf(alias, len, "%s", name);
+ rcu_read_unlock();
+
+ if (!read_seqcount_retry(&ifalias_rename_seq, seq))
+ break;
+
+ cond_resched();
+ }
+
+ return ret;
+}
/**
* netdev_features_change - device changes features
@@ -8749,6 +8795,8 @@ static int __init net_dev_init(void)
NULL, dev_cpu_dead);
WARN_ON(rc < 0);
rc = 0;
+
+ seqcount_init(&ifalias_rename_seq);
out:
return rc;
}
diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c
index 927a6dcbad96..530de7996d65 100644
--- a/net/core/net-sysfs.c
+++ b/net/core/net-sysfs.c
@@ -391,10 +391,7 @@ static ssize_t ifalias_store(struct device *dev, struct device_attribute *attr,
if (len > 0 && buf[len - 1] == '\n')
--count;
- if (!rtnl_trylock())
- return restart_syscall();
ret = dev_set_alias(netdev, buf, count);
- rtnl_unlock();
return ret < 0 ? ret : len;
}
@@ -403,13 +400,12 @@ static ssize_t ifalias_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
const struct net_device *netdev = to_net_dev(dev);
+ char tmp[IFALIASZ];
ssize_t ret = 0;
- if (!rtnl_trylock())
- return restart_syscall();
- if (netdev->ifalias)
- ret = sprintf(buf, "%s\n", netdev->ifalias);
- rtnl_unlock();
+ ret = dev_get_alias(netdev, tmp, sizeof(tmp));
+ if (ret > 0)
+ ret = sprintf(buf, "%s\n", tmp);
return ret;
}
static DEVICE_ATTR_RW(ifalias);
@@ -1488,7 +1484,7 @@ static void netdev_release(struct device *d)
BUG_ON(dev->reg_state != NETREG_RELEASED);
- kfree(dev->ifalias);
+ dev_set_alias(dev, "", 0);
netdev_freemem(dev);
}
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index c69451964a44..bab108ced7d8 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -1368,10 +1368,11 @@ static int nla_put_iflink(struct sk_buff *skb, const struct net_device *dev)
static noinline int nla_put_ifalias(struct sk_buff *skb, struct net_device *dev)
{
- if (dev->ifalias)
- return nla_put_string(skb, IFLA_IFALIAS, dev->ifalias);
+ char buf[IFALIASZ];
+ int ret;
- return 0;
+ ret = dev_get_alias(dev, buf, sizeof(buf));
+ return ret > 0 ? nla_put_string(skb, IFLA_IFALIAS, buf) : 0;
}
static noinline int rtnl_fill_link_netnsid(struct sk_buff *skb,
--
2.13.5
^ permalink raw reply related
* Re: [PATCH net-next v3 3/6] rtnetlink: add helper to dump ifalias
From: Eric Dumazet @ 2017-09-23 21:04 UTC (permalink / raw)
To: Florian Westphal; +Cc: netdev
In-Reply-To: <20170923192636.3932-4-fw@strlen.de>
On Sat, 2017-09-23 at 21:26 +0200, Florian Westphal wrote:
> Reviewed-by: David Ahern <dsahern@gmail.com>
> Signed-off-by: Florian Westphal <fw@strlen.de>
> ---
> Changes since v3: don't add rtnl assertion, I placed the assertion
> in my working tree instead as a reminder.
>
> net/core/rtnetlink.c | 11 +++++++++--
> 1 file changed, 9 insertions(+), 2 deletions(-)
>
> diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
> index c801212ee40e..47c17c3de79a 100644
> --- a/net/core/rtnetlink.c
> +++ b/net/core/rtnetlink.c
> @@ -1332,6 +1332,14 @@ static int nla_put_iflink(struct sk_buff *skb, const struct net_device *dev)
> return nla_put_u32(skb, IFLA_LINK, ifindex);
> }
>
> +static noinline int nla_put_ifalias(struct sk_buff *skb, struct net_device *dev)
Why noinline here ?
This function does not use stack at all (and that would call for
noinline_for_stack )
> +{
> + if (dev->ifalias)
> + return nla_put_string(skb, IFLA_IFALIAS, dev->ifalias);
> +
> + return 0;
> +}
> +
I really do not see the point of not making this RCU aware right away,
or at least make it in the same patch series...
^ permalink raw reply
* [PATCH] au1k_ir.c fix warning: Prefer [subsystem eg: netdev]_info([subsystem]dev, ...
From: Yurii Pavlenko @ 2017-09-23 20:13 UTC (permalink / raw)
To: samuel
Cc: gregkh, davem, manuel.lauss, netdev, devel, linux-kernel,
Yurii Pavlenko
This patch fixes the following checkpatch.pl warning: fix
Prefer [subsystem eg: netdev]_info([subsystem]dev, ... then dev_info(dev, ...
then pr_info(... to printk(KERN_INFO ...
Signed-off-by: Yurii Pavlenko <pyldev@gmail.com>
---
drivers/staging/irda/drivers/au1k_ir.c | 40 +++++++++++++++-------------------
1 file changed, 18 insertions(+), 22 deletions(-)
diff --git a/drivers/staging/irda/drivers/au1k_ir.c b/drivers/staging/irda/drivers/au1k_ir.c
index be4ea6a..73e3e4b 100644
--- a/drivers/staging/irda/drivers/au1k_ir.c
+++ b/drivers/staging/irda/drivers/au1k_ir.c
@@ -290,8 +290,7 @@ static int au1k_irda_set_speed(struct net_device *dev, int speed)
while (irda_read(aup, IR_STATUS) & (IR_RX_STATUS | IR_TX_STATUS)) {
msleep(20);
if (!timeout--) {
- printk(KERN_ERR "%s: rx/tx disable timeout\n",
- dev->name);
+ netdev_err(dev, "rx/tx disable timeout\n");
break;
}
}
@@ -349,7 +348,7 @@ static int au1k_irda_set_speed(struct net_device *dev, int speed)
IR_RX_ENABLE);
break;
default:
- printk(KERN_ERR "%s unsupported speed %x\n", dev->name, speed);
+ netdev_err(dev, "unsupported speed %x\n", speed);
ret = -EINVAL;
break;
}
@@ -361,18 +360,18 @@ static int au1k_irda_set_speed(struct net_device *dev, int speed)
irda_write(aup, IR_RING_PROMPT, 0);
if (control & (1 << 14)) {
- printk(KERN_ERR "%s: configuration error\n", dev->name);
+ netdev_err(dev, "configuration error\n");
} else {
if (control & (1 << 11))
- printk(KERN_DEBUG "%s Valid SIR config\n", dev->name);
+ netdev_debug(dev, "Valid SIR config\n");
if (control & (1 << 12))
- printk(KERN_DEBUG "%s Valid MIR config\n", dev->name);
+ netdev_debug(dev, "Valid MIR config\n");
if (control & (1 << 13))
- printk(KERN_DEBUG "%s Valid FIR config\n", dev->name);
+ netdev_debug(dev, "Valid FIR config\n");
if (control & (1 << 10))
- printk(KERN_DEBUG "%s TX enabled\n", dev->name);
+ netdev_debug(dev, "TX enabled\n");
if (control & (1 << 9))
- printk(KERN_DEBUG "%s RX enabled\n", dev->name);
+ netdev_debug(dev, "RX enabled\n");
}
return ret;
@@ -584,23 +583,21 @@ static int au1k_irda_start(struct net_device *dev)
retval = au1k_init(dev);
if (retval) {
- printk(KERN_ERR "%s: error in au1k_init\n", dev->name);
+ netdev_err(dev, "error in au1k_init\n");
return retval;
}
retval = request_irq(aup->irq_tx, &au1k_irda_interrupt, 0,
dev->name, dev);
if (retval) {
- printk(KERN_ERR "%s: unable to get IRQ %d\n",
- dev->name, dev->irq);
+ netdev_err(dev, "unable to get IRQ %d\n", dev->irq);
return retval;
}
retval = request_irq(aup->irq_rx, &au1k_irda_interrupt, 0,
dev->name, dev);
if (retval) {
free_irq(aup->irq_tx, dev);
- printk(KERN_ERR "%s: unable to get IRQ %d\n",
- dev->name, dev->irq);
+ netdev_err(dev, "unable to get IRQ %d\n", dev->irq);
return retval;
}
@@ -673,12 +670,12 @@ static int au1k_irda_hard_xmit(struct sk_buff *skb, struct net_device *dev)
flags = ptxd->flags;
if (flags & AU_OWN) {
- printk(KERN_DEBUG "%s: tx_full\n", dev->name);
+ netdev_debug(dev, "tx_full\n");
netif_stop_queue(dev);
aup->tx_full = 1;
return 1;
} else if (((aup->tx_head + 1) & (NUM_IR_DESC - 1)) == aup->tx_tail) {
- printk(KERN_DEBUG "%s: tx_full\n", dev->name);
+ netdev_debug(dev, "tx_full\n");
netif_stop_queue(dev);
aup->tx_full = 1;
return 1;
@@ -688,7 +685,7 @@ static int au1k_irda_hard_xmit(struct sk_buff *skb, struct net_device *dev)
#if 0
if (irda_read(aup, IR_RX_BYTE_CNT) != 0) {
- printk(KERN_DEBUG "tx warning: rx byte cnt %x\n",
+ netdev_debug(dev, "tx warning: rx byte cnt %x\n",
irda_read(aup, IR_RX_BYTE_CNT));
}
#endif
@@ -726,7 +723,7 @@ static void au1k_tx_timeout(struct net_device *dev)
u32 speed;
struct au1k_private *aup = netdev_priv(dev);
- printk(KERN_ERR "%s: tx timeout\n", dev->name);
+ netdev_err(dev, "tx timeout\n");
speed = aup->speed;
aup->speed = 0;
au1k_irda_set_speed(dev, speed);
@@ -751,8 +748,7 @@ static int au1k_irda_ioctl(struct net_device *dev, struct ifreq *ifreq, int cmd)
ret = au1k_irda_set_speed(dev,
rq->ifr_baudrate);
else {
- printk(KERN_ERR "%s ioctl: !netif_running\n",
- dev->name);
+ netdev_err(dev, "ioctl: !netif_running\n");
ret = 0;
}
}
@@ -868,7 +864,7 @@ static int au1k_irda_net_init(struct net_device *dev)
out2:
kfree(aup->rx_buff.head);
out1:
- printk(KERN_ERR "au1k_irda_net_init() failed. Returns %d\n", retval);
+ netdev_err(dev, "au1k_irda_net_init() failed. Returns %d\n");
return retval;
}
@@ -934,7 +930,7 @@ static int au1k_irda_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, dev);
- printk(KERN_INFO "IrDA: Registered device %s\n", dev->name);
+ netdev_info(dev, "IrDA: Registered device\n");
return 0;
out4:
--
2.7.4
^ permalink raw reply related
* [PATCH 2/2] neigh: make strucrt neigh_table::entry_size unsigned int
From: Alexey Dobriyan @ 2017-09-23 20:03 UTC (permalink / raw)
To: davem; +Cc: netdev, ganeshgr
In-Reply-To: <20170923200106.GA24928@avx2>
Key length can't be negative.
Leave comparisons against nla_len() signed just in case truncated attribute
can sneak in there.
Space savings:
add/remove: 0/0 grow/shrink: 0/7 up/down: 0/-7 (-7)
function old new delta
pneigh_delete 273 272 -1
mlx5e_rep_netevent_event 1415 1414 -1
mlx5e_create_encap_header_ipv6 1194 1193 -1
mlx5e_create_encap_header_ipv4 1071 1070 -1
cxgb4_l2t_get 1104 1103 -1
__pneigh_lookup 69 68 -1
__neigh_create 2452 2451 -1
Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
---
drivers/net/ethernet/chelsio/cxgb4/l2t.c | 4 ++--
include/net/neighbour.h | 2 +-
net/core/neighbour.c | 18 +++++++++---------
3 files changed, 12 insertions(+), 12 deletions(-)
--- a/drivers/net/ethernet/chelsio/cxgb4/l2t.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/l2t.c
@@ -422,7 +422,7 @@ struct l2t_entry *cxgb4_l2t_get(struct l2t_data *d, struct neighbour *neigh,
u8 lport;
u16 vlan;
struct l2t_entry *e;
- int addr_len = neigh->tbl->key_len;
+ unsigned int addr_len = neigh->tbl->key_len;
u32 *addr = (u32 *)neigh->primary_key;
int ifidx = neigh->dev->ifindex;
int hash = addr_hash(d, addr, addr_len, ifidx);
@@ -536,7 +536,7 @@ void t4_l2t_update(struct adapter *adap, struct neighbour *neigh)
struct l2t_entry *e;
struct sk_buff_head *arpq = NULL;
struct l2t_data *d = adap->l2t;
- int addr_len = neigh->tbl->key_len;
+ unsigned int addr_len = neigh->tbl->key_len;
u32 *addr = (u32 *) neigh->primary_key;
int ifidx = neigh->dev->ifindex;
int hash = addr_hash(d, addr, addr_len, ifidx);
--- a/include/net/neighbour.h
+++ b/include/net/neighbour.h
@@ -191,7 +191,7 @@ struct neigh_hash_table {
struct neigh_table {
int family;
unsigned int entry_size;
- int key_len;
+ unsigned int key_len;
__be16 protocol;
__u32 (*hash)(const void *pkey,
const struct net_device *dev,
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -457,7 +457,7 @@ struct neighbour *neigh_lookup_nodev(struct neigh_table *tbl, struct net *net,
const void *pkey)
{
struct neighbour *n;
- int key_len = tbl->key_len;
+ unsigned int key_len = tbl->key_len;
u32 hash_val;
struct neigh_hash_table *nht;
@@ -488,7 +488,7 @@ struct neighbour *__neigh_create(struct neigh_table *tbl, const void *pkey,
struct net_device *dev, bool want_ref)
{
u32 hash_val;
- int key_len = tbl->key_len;
+ unsigned int key_len = tbl->key_len;
int error;
struct neighbour *n1, *rc, *n = neigh_alloc(tbl, dev);
struct neigh_hash_table *nht;
@@ -572,7 +572,7 @@ struct neighbour *__neigh_create(struct neigh_table *tbl, const void *pkey,
}
EXPORT_SYMBOL(__neigh_create);
-static u32 pneigh_hash(const void *pkey, int key_len)
+static u32 pneigh_hash(const void *pkey, unsigned int key_len)
{
u32 hash_val = *(u32 *)(pkey + key_len - 4);
hash_val ^= (hash_val >> 16);
@@ -585,7 +585,7 @@ static u32 pneigh_hash(const void *pkey, int key_len)
static struct pneigh_entry *__pneigh_lookup_1(struct pneigh_entry *n,
struct net *net,
const void *pkey,
- int key_len,
+ unsigned int key_len,
struct net_device *dev)
{
while (n) {
@@ -601,7 +601,7 @@ static struct pneigh_entry *__pneigh_lookup_1(struct pneigh_entry *n,
struct pneigh_entry *__pneigh_lookup(struct neigh_table *tbl,
struct net *net, const void *pkey, struct net_device *dev)
{
- int key_len = tbl->key_len;
+ unsigned int key_len = tbl->key_len;
u32 hash_val = pneigh_hash(pkey, key_len);
return __pneigh_lookup_1(tbl->phash_buckets[hash_val],
@@ -614,7 +614,7 @@ struct pneigh_entry * pneigh_lookup(struct neigh_table *tbl,
struct net_device *dev, int creat)
{
struct pneigh_entry *n;
- int key_len = tbl->key_len;
+ unsigned int key_len = tbl->key_len;
u32 hash_val = pneigh_hash(pkey, key_len);
read_lock_bh(&tbl->lock);
@@ -659,7 +659,7 @@ int pneigh_delete(struct neigh_table *tbl, struct net *net, const void *pkey,
struct net_device *dev)
{
struct pneigh_entry *n, **np;
- int key_len = tbl->key_len;
+ unsigned int key_len = tbl->key_len;
u32 hash_val = pneigh_hash(pkey, key_len);
write_lock_bh(&tbl->lock);
@@ -1662,7 +1662,7 @@ static int neigh_delete(struct sk_buff *skb, struct nlmsghdr *nlh,
if (tbl == NULL)
return -EAFNOSUPPORT;
- if (nla_len(dst_attr) < tbl->key_len)
+ if (nla_len(dst_attr) < (int)tbl->key_len)
goto out;
if (ndm->ndm_flags & NTF_PROXY) {
@@ -1730,7 +1730,7 @@ static int neigh_add(struct sk_buff *skb, struct nlmsghdr *nlh,
if (tbl == NULL)
return -EAFNOSUPPORT;
- if (nla_len(tb[NDA_DST]) < tbl->key_len)
+ if (nla_len(tb[NDA_DST]) < (int)tbl->key_len)
goto out;
dst = nla_data(tb[NDA_DST]);
lladdr = tb[NDA_LLADDR] ? nla_data(tb[NDA_LLADDR]) : NULL;
^ permalink raw reply
* [PATCH 1/2] neigh: make struct neigh_table::entry_size unsigned int
From: Alexey Dobriyan @ 2017-09-23 20:01 UTC (permalink / raw)
To: davem; +Cc: netdev
Neigh entry size can't be negative.
Space savings:
add/remove: 0/0 grow/shrink: 0/5 up/down: 0/-7 (-7)
function old new delta
lowpan_neigh_construct 25 24 -1
clip_seq_sub_iter 152 151 -1
clip_ioctl 1475 1474 -1
clip_constructor 93 92 -1
__neigh_create 2455 2452 -3
Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
---
include/net/neighbour.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/include/net/neighbour.h
+++ b/include/net/neighbour.h
@@ -190,7 +190,7 @@ struct neigh_hash_table {
struct neigh_table {
int family;
- int entry_size;
+ unsigned int entry_size;
int key_len;
__be16 protocol;
__u32 (*hash)(const void *pkey,
^ permalink raw reply
* [PATCH net-next] net: speed up skb_rbtree_purge()
From: Eric Dumazet @ 2017-09-23 19:39 UTC (permalink / raw)
To: David Miller; +Cc: netdev
From: Eric Dumazet <edumazet@google.com>
As measured in my prior patch ("sch_netem: faster rb tree removal"),
rbtree_postorder_for_each_entry_safe() is nice looking but much slower
than using rb_next() directly, except when tree is small enough
to fit in CPU caches (then the cost is the same)
Also note that there is not even an increase of text size :
$ size net/core/skbuff.o.before net/core/skbuff.o
text data bss dec hex filename
40711 1298 0 42009 a419 net/core/skbuff.o.before
40711 1298 0 42009 a419 net/core/skbuff.o
From: Eric Dumazet <edumazet@google.com>
---
net/core/skbuff.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 16982de649b97b92423a4f9f5eac1e98ca803370..000ce735fa8d649e7abeeef2ebab8501dea96efd 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -2848,12 +2848,15 @@ EXPORT_SYMBOL(skb_queue_purge);
*/
void skb_rbtree_purge(struct rb_root *root)
{
- struct sk_buff *skb, *next;
+ struct rb_node *p = rb_first(root);
- rbtree_postorder_for_each_entry_safe(skb, next, root, rbnode)
- kfree_skb(skb);
+ while (p) {
+ struct sk_buff *skb = rb_entry(p, struct sk_buff, rbnode);
- *root = RB_ROOT;
+ p = rb_next(p);
+ rb_erase(&skb->rbnode, root);
+ kfree_skb(skb);
+ }
}
/**
^ permalink raw reply related
* [RESEND] Re: usb/net/p54: trying to register non-static key in p54_unregister_leds
From: Christian Lamparter @ 2017-09-23 19:37 UTC (permalink / raw)
To: Andrey Konovalov
Cc: Johannes Berg, Kalle Valo, linux-wireless, netdev, LKML,
Dmitry Vyukov, Kostya Serebryany, syzkaller, Stephen Boyd,
Tejun Heo, Yong Zhang
In-Reply-To: <CAAeHK+wWRZuCDNhoZJ0ACDhiNQw8tVRp2HW0j1EDH0HOe523xA@mail.gmail.com>
This got rejected by gmail once. Let's see if it works now.
On Thursday, September 21, 2017 8:22:45 PM CEST Andrey Konovalov wrote:
> On Wed, Sep 20, 2017 at 9:55 PM, Johannes Berg
> <johannes@sipsolutions.net> wrote:
> > On Wed, 2017-09-20 at 21:27 +0200, Christian Lamparter wrote:
> >
> >> It seems this is caused as a result of:
> >> -> lock_map_acquire(&work->lockdep_map);
> >> lock_map_release(&work->lockdep_map);
> >>
> >> in flush_work() [0]
> >
> > Agree.
> >
> >> This was added by:
> >>
> >> commit 0976dfc1d0cd80a4e9dfaf87bd8744612bde475a
> >> Author: Stephen Boyd <sboyd@codeaurora.org>
> >> Date: Fri Apr 20 17:28:50 2012 -0700
> >>
> >> workqueue: Catch more locking problems with flush_work()
> >
> > Yes, but that doesn't matter.
> >
> >> Looking at the Stephen's patch, it's clear that it was made
> >> with "static DECLARE_WORK(work, my_work)" in mind. However
> >> p54's led_work is "per-device", hence it is stored in the
> >> devices context p54_common, which is dynamically allocated.
> >> So, maybe revert Stephen's patch?
> >
> > I disagree - as the lockdep warning says:
> >
> >> > INFO: trying to register non-static key.
> >> > the code is fine but needs lockdep annotation.
> >> > turning off the locking correctness validator.
> >
> > What it needs is to actually correctly go through initializing the work
> > at least once.
> >
> > Without more information, I can't really say what's going on, but I
> > assume that something is failing and p54_unregister_leds() is getting
> > invoked without p54_init_leds() having been invoked, so essentially
> > it's trying to flush a work that was never initialized?
> >
> > INIT_DELAYED_WORK() does, after all, initialize the lockdep map
> > properly via __INIT_WORK().
Ok, thanks. This does indeed explain it.
But this also begs the question: Is this really working then?
>From what I can tell, if CONFIG_LOCKDEP is not set then there's no BUG
no WARN, no other splat or any other odd system behaviour. Does
[cancel | flush]_[delayed_]work[_sync] really "just work" by *accident*,
as long the delayed_work | work_struct is zeroed out?
And should it work in the future as well?
> Since I'm able to reproduce this, please let me know if you need me to
> collect some debug traces to help with the triage.
Do you want to take a shot at making a patch too? At a quick glance, it
should be enough to move the [#ifdef CONFIG_P54_LEDS ... #endif] block
in p54_unregister_common() into the if (priv->registered) { block
(preferably before the ieee80211_unregister_hw(dev).
Regards,
Christian
^ permalink raw reply
* [PATCH net-next v3 6/6] rtnetlink: rtnl_have_link_slave_info doesn't need rtnl
From: Florian Westphal @ 2017-09-23 19:26 UTC (permalink / raw)
To: netdev; +Cc: Florian Westphal
In-Reply-To: <20170923192636.3932-1-fw@strlen.de>
it can be switched to rcu.
Reviewed-by: David Ahern <dsahern@gmail.com>
Signed-off-by: Florian Westphal <fw@strlen.de>
---
Changes since v2: remove ASSERT_RTNL.
net/core/rtnetlink.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index e858a2b48d7e..c69451964a44 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -522,11 +522,15 @@ static size_t rtnl_link_get_af_size(const struct net_device *dev,
static bool rtnl_have_link_slave_info(const struct net_device *dev)
{
struct net_device *master_dev;
+ bool ret = false;
- master_dev = netdev_master_upper_dev_get((struct net_device *) dev);
+ rcu_read_lock();
+
+ master_dev = netdev_master_upper_dev_get_rcu((struct net_device *)dev);
if (master_dev && master_dev->rtnl_link_ops)
- return true;
- return false;
+ ret = true;
+ rcu_read_unlock();
+ return ret;
}
static int rtnl_link_slave_info_fill(struct sk_buff *skb,
--
2.13.5
^ permalink raw reply related
* [PATCH net-next v3 5/6] rtnetlink: add helpers to dump netnsid information
From: Florian Westphal @ 2017-09-23 19:26 UTC (permalink / raw)
To: netdev; +Cc: Florian Westphal
In-Reply-To: <20170923192636.3932-1-fw@strlen.de>
Reviewed-by: David Ahern <dsahern@gmail.com>
Signed-off-by: Florian Westphal <fw@strlen.de>
---
Changes since v2:
this hunk was part of patch #4.
net/core/rtnetlink.c | 30 +++++++++++++++++++-----------
1 file changed, 19 insertions(+), 11 deletions(-)
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 625342d27c44..e858a2b48d7e 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -1370,6 +1370,23 @@ static noinline int nla_put_ifalias(struct sk_buff *skb, struct net_device *dev)
return 0;
}
+static noinline int rtnl_fill_link_netnsid(struct sk_buff *skb,
+ const struct net_device *dev)
+{
+ if (dev->rtnl_link_ops && dev->rtnl_link_ops->get_link_net) {
+ struct net *link_net = dev->rtnl_link_ops->get_link_net(dev);
+
+ if (!net_eq(dev_net(dev), link_net)) {
+ int id = peernet2id_alloc(dev_net(dev), link_net);
+
+ if (nla_put_s32(skb, IFLA_LINK_NETNSID, id))
+ return -EMSGSIZE;
+ }
+ }
+
+ return 0;
+}
+
static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
int type, u32 pid, u32 seq, u32 change,
unsigned int flags, u32 ext_filter_mask,
@@ -1458,17 +1475,8 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
goto nla_put_failure;
}
- if (dev->rtnl_link_ops &&
- dev->rtnl_link_ops->get_link_net) {
- struct net *link_net = dev->rtnl_link_ops->get_link_net(dev);
-
- if (!net_eq(dev_net(dev), link_net)) {
- int id = peernet2id_alloc(dev_net(dev), link_net);
-
- if (nla_put_s32(skb, IFLA_LINK_NETNSID, id))
- goto nla_put_failure;
- }
- }
+ if (rtnl_fill_link_netnsid(skb, dev))
+ goto nla_put_failure;
if (!(af_spec = nla_nest_start(skb, IFLA_AF_SPEC)))
goto nla_put_failure;
--
2.13.5
^ permalink raw reply related
* [PATCH net-next v3 4/6] rtnetlink: add helpers to dump vf information
From: Florian Westphal @ 2017-09-23 19:26 UTC (permalink / raw)
To: netdev; +Cc: Florian Westphal
In-Reply-To: <20170923192636.3932-1-fw@strlen.de>
similar to earlier patches, split out more parts of this function to
better see what is happening and where we assume rtnl is locked.
Reviewed-by: David Ahern <dsahern@gmail.com>
Signed-off-by: Florian Westphal <fw@strlen.de>
---
changes since v2: split this patch into two, last submission also
added netnsid helper, which was moved to next patch.
net/core/rtnetlink.c | 50 +++++++++++++++++++++++++++++++-------------------
1 file changed, 31 insertions(+), 19 deletions(-)
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 47c17c3de79a..625342d27c44 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -1211,6 +1211,36 @@ static noinline_for_stack int rtnl_fill_vfinfo(struct sk_buff *skb,
return -EMSGSIZE;
}
+static noinline_for_stack int rtnl_fill_vf(struct sk_buff *skb,
+ struct net_device *dev,
+ u32 ext_filter_mask)
+{
+ struct nlattr *vfinfo;
+ int i, num_vfs;
+
+ if (!dev->dev.parent || ((ext_filter_mask & RTEXT_FILTER_VF) == 0))
+ return 0;
+
+ num_vfs = dev_num_vf(dev->dev.parent);
+ if (nla_put_u32(skb, IFLA_NUM_VF, num_vfs))
+ return -EMSGSIZE;
+
+ if (!dev->netdev_ops->ndo_get_vf_config)
+ return 0;
+
+ vfinfo = nla_nest_start(skb, IFLA_VFINFO_LIST);
+ if (!vfinfo)
+ return -EMSGSIZE;
+
+ for (i = 0; i < num_vfs; i++) {
+ if (rtnl_fill_vfinfo(skb, dev, i, vfinfo))
+ return -EMSGSIZE;
+ }
+
+ nla_nest_end(skb, vfinfo);
+ return 0;
+}
+
static int rtnl_fill_link_ifmap(struct sk_buff *skb, struct net_device *dev)
{
struct rtnl_link_ifmap map;
@@ -1414,27 +1444,9 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
if (rtnl_fill_stats(skb, dev))
goto nla_put_failure;
- if (dev->dev.parent && (ext_filter_mask & RTEXT_FILTER_VF) &&
- nla_put_u32(skb, IFLA_NUM_VF, dev_num_vf(dev->dev.parent)))
+ if (rtnl_fill_vf(skb, dev, ext_filter_mask))
goto nla_put_failure;
- if (dev->netdev_ops->ndo_get_vf_config && dev->dev.parent &&
- ext_filter_mask & RTEXT_FILTER_VF) {
- int i;
- struct nlattr *vfinfo;
- int num_vfs = dev_num_vf(dev->dev.parent);
-
- vfinfo = nla_nest_start(skb, IFLA_VFINFO_LIST);
- if (!vfinfo)
- goto nla_put_failure;
- for (i = 0; i < num_vfs; i++) {
- if (rtnl_fill_vfinfo(skb, dev, i, vfinfo))
- goto nla_put_failure;
- }
-
- nla_nest_end(skb, vfinfo);
- }
-
if (rtnl_port_fill(skb, dev, ext_filter_mask))
goto nla_put_failure;
--
2.13.5
^ permalink raw reply related
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