Netdev List
 help / color / mirror / Atom feed
* [PATCH net 4/4] net/smc: correct state change for peer closing
From: Ursula Braun @ 2019-02-04 12:44 UTC (permalink / raw)
  To: davem
  Cc: netdev, linux-s390, linux-rdma, schwidefsky, heiko.carstens,
	raspl, ubraun
In-Reply-To: <20190204124447.39816-1-ubraun@linux.ibm.com>

If some kind of closing is received from the peer while still in
state SMC_INIT, it means the peer has had an active connection and
closed the socket quickly before listen_work finished. This should
not result in a shortcut from state SMC_INIT to state SMC_CLOSED.
This patch adds the socket to the accept queue in state
SMC_APPCLOSEWAIT1. The socket reaches state SMC_CLOSED once being
accepted and closed with smc_release().

Signed-off-by: Ursula Braun <ubraun@linux.ibm.com>
---
 net/smc/smc_close.c | 9 +--------
 1 file changed, 1 insertion(+), 8 deletions(-)

diff --git a/net/smc/smc_close.c b/net/smc/smc_close.c
index ea2b87f29469..e39cadda1bf5 100644
--- a/net/smc/smc_close.c
+++ b/net/smc/smc_close.c
@@ -345,14 +345,7 @@ static void smc_close_passive_work(struct work_struct *work)
 
 	switch (sk->sk_state) {
 	case SMC_INIT:
-		if (atomic_read(&conn->bytes_to_rcv) ||
-		    (rxflags->peer_done_writing &&
-		     !smc_cdc_rxed_any_close(conn))) {
-			sk->sk_state = SMC_APPCLOSEWAIT1;
-		} else {
-			sk->sk_state = SMC_CLOSED;
-			sock_put(sk); /* passive closing */
-		}
+		sk->sk_state = SMC_APPCLOSEWAIT1;
 		break;
 	case SMC_ACTIVE:
 		sk->sk_state = SMC_APPCLOSEWAIT1;
-- 
2.16.4


^ permalink raw reply related

* [PATCH net 3/4] net/smc: delete rkey first before switching to unused
From: Ursula Braun @ 2019-02-04 12:44 UTC (permalink / raw)
  To: davem
  Cc: netdev, linux-s390, linux-rdma, schwidefsky, heiko.carstens,
	raspl, ubraun
In-Reply-To: <20190204124447.39816-1-ubraun@linux.ibm.com>

Once RMBs are flagged as unused they are candidates for reuse.
Thus the LLC DELETE RKEY operaton should be made before flagging
the RMB as unused.

Fixes: c7674c001b11 ("net/smc: unregister rkeys of unused buffer")
Signed-off-by: Ursula Braun <ubraun@linux.ibm.com>
---
 net/smc/smc_core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/smc/smc_core.c b/net/smc/smc_core.c
index 097c798983ca..aa1c551cee81 100644
--- a/net/smc/smc_core.c
+++ b/net/smc/smc_core.c
@@ -302,13 +302,13 @@ static void smc_buf_unuse(struct smc_connection *conn,
 		conn->sndbuf_desc->used = 0;
 	if (conn->rmb_desc) {
 		if (!conn->rmb_desc->regerr) {
-			conn->rmb_desc->used = 0;
 			if (!lgr->is_smcd) {
 				/* unregister rmb with peer */
 				smc_llc_do_delete_rkey(
 						&lgr->lnk[SMC_SINGLE_LINK],
 						conn->rmb_desc);
 			}
+			conn->rmb_desc->used = 0;
 		} else {
 			/* buf registration failed, reuse not possible */
 			write_lock_bh(&lgr->rmbs_lock);
-- 
2.16.4


^ permalink raw reply related

* [PATCH net 1/4] net/smc: preallocated memory for rdma work requests
From: Ursula Braun @ 2019-02-04 12:44 UTC (permalink / raw)
  To: davem
  Cc: netdev, linux-s390, linux-rdma, schwidefsky, heiko.carstens,
	raspl, ubraun
In-Reply-To: <20190204124447.39816-1-ubraun@linux.ibm.com>

The work requests for rdma writes are built in local variables within
function smc_tx_rdma_write(). This violates the rule that the work
request storage has to stay till the work request is confirmed by
a completion queue response.
This patch introduces preallocated memory for these work requests.
The storage is allocated, once a link (and thus a queue pair) is
established.

Signed-off-by: Ursula Braun <ubraun@linux.ibm.com>
---
 net/smc/smc_cdc.c  | 11 +++--------
 net/smc/smc_cdc.h  |  8 +++++++-
 net/smc/smc_core.h | 20 ++++++++++++++++++++
 net/smc/smc_llc.c  |  3 ++-
 net/smc/smc_tx.c   | 44 ++++++++++++++++++++++----------------------
 net/smc/smc_wr.c   | 38 +++++++++++++++++++++++++++++++++++++-
 net/smc/smc_wr.h   |  1 +
 7 files changed, 92 insertions(+), 33 deletions(-)

diff --git a/net/smc/smc_cdc.c b/net/smc/smc_cdc.c
index 1c5333d494e9..b80ef104ab4e 100644
--- a/net/smc/smc_cdc.c
+++ b/net/smc/smc_cdc.c
@@ -21,13 +21,6 @@
 
 /********************************** send *************************************/
 
-struct smc_cdc_tx_pend {
-	struct smc_connection	*conn;		/* socket connection */
-	union smc_host_cursor	cursor;	/* tx sndbuf cursor sent */
-	union smc_host_cursor	p_cursor;	/* rx RMBE cursor produced */
-	u16			ctrl_seq;	/* conn. tx sequence # */
-};
-
 /* handler for send/transmission completion of a CDC msg */
 static void smc_cdc_tx_handler(struct smc_wr_tx_pend_priv *pnd_snd,
 			       struct smc_link *link,
@@ -61,12 +54,14 @@ static void smc_cdc_tx_handler(struct smc_wr_tx_pend_priv *pnd_snd,
 
 int smc_cdc_get_free_slot(struct smc_connection *conn,
 			  struct smc_wr_buf **wr_buf,
+			  struct smc_rdma_wr **wr_rdma_buf,
 			  struct smc_cdc_tx_pend **pend)
 {
 	struct smc_link *link = &conn->lgr->lnk[SMC_SINGLE_LINK];
 	int rc;
 
 	rc = smc_wr_tx_get_free_slot(link, smc_cdc_tx_handler, wr_buf,
+				     wr_rdma_buf,
 				     (struct smc_wr_tx_pend_priv **)pend);
 	if (!conn->alert_token_local)
 		/* abnormal termination */
@@ -121,7 +116,7 @@ static int smcr_cdc_get_slot_and_msg_send(struct smc_connection *conn)
 	struct smc_wr_buf *wr_buf;
 	int rc;
 
-	rc = smc_cdc_get_free_slot(conn, &wr_buf, &pend);
+	rc = smc_cdc_get_free_slot(conn, &wr_buf, NULL, &pend);
 	if (rc)
 		return rc;
 
diff --git a/net/smc/smc_cdc.h b/net/smc/smc_cdc.h
index b5bfe38c7f9b..2148da7a26b1 100644
--- a/net/smc/smc_cdc.h
+++ b/net/smc/smc_cdc.h
@@ -270,10 +270,16 @@ static inline void smc_cdc_msg_to_host(struct smc_host_cdc_msg *local,
 		smcr_cdc_msg_to_host(local, peer, conn);
 }
 
-struct smc_cdc_tx_pend;
+struct smc_cdc_tx_pend {
+	struct smc_connection	*conn;		/* socket connection */
+	union smc_host_cursor	cursor;		/* tx sndbuf cursor sent */
+	union smc_host_cursor	p_cursor;	/* rx RMBE cursor produced */
+	u16			ctrl_seq;	/* conn. tx sequence # */
+};
 
 int smc_cdc_get_free_slot(struct smc_connection *conn,
 			  struct smc_wr_buf **wr_buf,
+			  struct smc_rdma_wr **wr_rdma_buf,
 			  struct smc_cdc_tx_pend **pend);
 void smc_cdc_tx_dismiss_slots(struct smc_connection *conn);
 int smc_cdc_msg_send(struct smc_connection *conn, struct smc_wr_buf *wr_buf,
diff --git a/net/smc/smc_core.h b/net/smc/smc_core.h
index b00287989a3d..8806d2afa6ed 100644
--- a/net/smc/smc_core.h
+++ b/net/smc/smc_core.h
@@ -52,6 +52,24 @@ enum smc_wr_reg_state {
 	FAILED		/* ib_wr_reg_mr response: failure */
 };
 
+struct smc_rdma_sge {				/* sges for RDMA writes */
+	struct ib_sge		wr_tx_rdma_sge[SMC_IB_MAX_SEND_SGE];
+};
+
+#define SMC_MAX_RDMA_WRITES	2		/* max. # of RDMA writes per
+						 * message send
+						 */
+
+struct smc_rdma_sges {				/* sges per message send */
+	struct smc_rdma_sge	tx_rdma_sge[SMC_MAX_RDMA_WRITES];
+};
+
+struct smc_rdma_wr {				/* work requests per message
+						 * send
+						 */
+	struct ib_rdma_wr	wr_tx_rdma[SMC_MAX_RDMA_WRITES];
+};
+
 struct smc_link {
 	struct smc_ib_device	*smcibdev;	/* ib-device */
 	u8			ibport;		/* port - values 1 | 2 */
@@ -64,6 +82,8 @@ struct smc_link {
 	struct smc_wr_buf	*wr_tx_bufs;	/* WR send payload buffers */
 	struct ib_send_wr	*wr_tx_ibs;	/* WR send meta data */
 	struct ib_sge		*wr_tx_sges;	/* WR send gather meta data */
+	struct smc_rdma_sges	*wr_tx_rdma_sges;/*RDMA WRITE gather meta data*/
+	struct smc_rdma_wr	*wr_tx_rdmas;	/* WR RDMA WRITE */
 	struct smc_wr_tx_pend	*wr_tx_pends;	/* WR send waiting for CQE */
 	/* above four vectors have wr_tx_cnt elements and use the same index */
 	dma_addr_t		wr_tx_dma_addr;	/* DMA address of wr_tx_bufs */
diff --git a/net/smc/smc_llc.c b/net/smc/smc_llc.c
index a6d3623d06f4..4fd60c522802 100644
--- a/net/smc/smc_llc.c
+++ b/net/smc/smc_llc.c
@@ -166,7 +166,8 @@ static int smc_llc_add_pending_send(struct smc_link *link,
 {
 	int rc;
 
-	rc = smc_wr_tx_get_free_slot(link, smc_llc_tx_handler, wr_buf, pend);
+	rc = smc_wr_tx_get_free_slot(link, smc_llc_tx_handler, wr_buf, NULL,
+				     pend);
 	if (rc < 0)
 		return rc;
 	BUILD_BUG_ON_MSG(
diff --git a/net/smc/smc_tx.c b/net/smc/smc_tx.c
index 36af3de731b9..2fdfaff60cf9 100644
--- a/net/smc/smc_tx.c
+++ b/net/smc/smc_tx.c
@@ -266,27 +266,23 @@ int smcd_tx_ism_write(struct smc_connection *conn, void *data, size_t len,
 
 /* sndbuf consumer: actual data transfer of one target chunk with RDMA write */
 static int smc_tx_rdma_write(struct smc_connection *conn, int peer_rmbe_offset,
-			     int num_sges, struct ib_sge sges[])
+			     int num_sges, struct ib_rdma_wr *rdma_wr)
 {
 	struct smc_link_group *lgr = conn->lgr;
-	struct ib_rdma_wr rdma_wr;
 	struct smc_link *link;
 	int rc;
 
-	memset(&rdma_wr, 0, sizeof(rdma_wr));
 	link = &lgr->lnk[SMC_SINGLE_LINK];
-	rdma_wr.wr.wr_id = smc_wr_tx_get_next_wr_id(link);
-	rdma_wr.wr.sg_list = sges;
-	rdma_wr.wr.num_sge = num_sges;
-	rdma_wr.wr.opcode = IB_WR_RDMA_WRITE;
-	rdma_wr.remote_addr =
+	rdma_wr->wr.wr_id = smc_wr_tx_get_next_wr_id(link);
+	rdma_wr->wr.num_sge = num_sges;
+	rdma_wr->remote_addr =
 		lgr->rtokens[conn->rtoken_idx][SMC_SINGLE_LINK].dma_addr +
 		/* RMBE within RMB */
 		conn->tx_off +
 		/* offset within RMBE */
 		peer_rmbe_offset;
-	rdma_wr.rkey = lgr->rtokens[conn->rtoken_idx][SMC_SINGLE_LINK].rkey;
-	rc = ib_post_send(link->roce_qp, &rdma_wr.wr, NULL);
+	rdma_wr->rkey = lgr->rtokens[conn->rtoken_idx][SMC_SINGLE_LINK].rkey;
+	rc = ib_post_send(link->roce_qp, &rdma_wr->wr, NULL);
 	if (rc) {
 		conn->local_tx_ctrl.conn_state_flags.peer_conn_abort = 1;
 		smc_lgr_terminate(lgr);
@@ -313,24 +309,25 @@ static inline void smc_tx_advance_cursors(struct smc_connection *conn,
 /* SMC-R helper for smc_tx_rdma_writes() */
 static int smcr_tx_rdma_writes(struct smc_connection *conn, size_t len,
 			       size_t src_off, size_t src_len,
-			       size_t dst_off, size_t dst_len)
+			       size_t dst_off, size_t dst_len,
+			       struct smc_rdma_wr *wr_rdma_buf)
 {
 	dma_addr_t dma_addr =
 		sg_dma_address(conn->sndbuf_desc->sgt[SMC_SINGLE_LINK].sgl);
-	struct smc_link *link = &conn->lgr->lnk[SMC_SINGLE_LINK];
 	int src_len_sum = src_len, dst_len_sum = dst_len;
-	struct ib_sge sges[SMC_IB_MAX_SEND_SGE];
 	int sent_count = src_off;
 	int srcchunk, dstchunk;
 	int num_sges;
 	int rc;
 
 	for (dstchunk = 0; dstchunk < 2; dstchunk++) {
+		struct ib_sge *sge =
+			wr_rdma_buf->wr_tx_rdma[dstchunk].wr.sg_list;
+
 		num_sges = 0;
 		for (srcchunk = 0; srcchunk < 2; srcchunk++) {
-			sges[srcchunk].addr = dma_addr + src_off;
-			sges[srcchunk].length = src_len;
-			sges[srcchunk].lkey = link->roce_pd->local_dma_lkey;
+			sge[srcchunk].addr = dma_addr + src_off;
+			sge[srcchunk].length = src_len;
 			num_sges++;
 
 			src_off += src_len;
@@ -343,7 +340,8 @@ static int smcr_tx_rdma_writes(struct smc_connection *conn, size_t len,
 			src_len = dst_len - src_len; /* remainder */
 			src_len_sum += src_len;
 		}
-		rc = smc_tx_rdma_write(conn, dst_off, num_sges, sges);
+		rc = smc_tx_rdma_write(conn, dst_off, num_sges,
+				       &wr_rdma_buf->wr_tx_rdma[dstchunk]);
 		if (rc)
 			return rc;
 		if (dst_len_sum == len)
@@ -402,7 +400,8 @@ static int smcd_tx_rdma_writes(struct smc_connection *conn, size_t len,
 /* sndbuf consumer: prepare all necessary (src&dst) chunks of data transmit;
  * usable snd_wnd as max transmit
  */
-static int smc_tx_rdma_writes(struct smc_connection *conn)
+static int smc_tx_rdma_writes(struct smc_connection *conn,
+			      struct smc_rdma_wr *wr_rdma_buf)
 {
 	size_t len, src_len, dst_off, dst_len; /* current chunk values */
 	union smc_host_cursor sent, prep, prod, cons;
@@ -463,7 +462,7 @@ static int smc_tx_rdma_writes(struct smc_connection *conn)
 					 dst_off, dst_len);
 	else
 		rc = smcr_tx_rdma_writes(conn, len, sent.count, src_len,
-					 dst_off, dst_len);
+					 dst_off, dst_len, wr_rdma_buf);
 	if (rc)
 		return rc;
 
@@ -484,11 +483,12 @@ static int smc_tx_rdma_writes(struct smc_connection *conn)
 static int smcr_tx_sndbuf_nonempty(struct smc_connection *conn)
 {
 	struct smc_cdc_producer_flags *pflags;
+	struct smc_rdma_wr *wr_rdma_buf;
 	struct smc_cdc_tx_pend *pend;
 	struct smc_wr_buf *wr_buf;
 	int rc;
 
-	rc = smc_cdc_get_free_slot(conn, &wr_buf, &pend);
+	rc = smc_cdc_get_free_slot(conn, &wr_buf, &wr_rdma_buf, &pend);
 	if (rc < 0) {
 		if (rc == -EBUSY) {
 			struct smc_sock *smc =
@@ -506,7 +506,7 @@ static int smcr_tx_sndbuf_nonempty(struct smc_connection *conn)
 
 	spin_lock_bh(&conn->send_lock);
 	if (!conn->local_tx_ctrl.prod_flags.urg_data_present) {
-		rc = smc_tx_rdma_writes(conn);
+		rc = smc_tx_rdma_writes(conn, wr_rdma_buf);
 		if (rc) {
 			smc_wr_tx_put_slot(&conn->lgr->lnk[SMC_SINGLE_LINK],
 					   (struct smc_wr_tx_pend_priv *)pend);
@@ -533,7 +533,7 @@ static int smcd_tx_sndbuf_nonempty(struct smc_connection *conn)
 
 	spin_lock_bh(&conn->send_lock);
 	if (!pflags->urg_data_present)
-		rc = smc_tx_rdma_writes(conn);
+		rc = smc_tx_rdma_writes(conn, NULL);
 	if (!rc)
 		rc = smcd_cdc_msg_send(conn);
 
diff --git a/net/smc/smc_wr.c b/net/smc/smc_wr.c
index 1dc88c32d6bb..253aa75dc2b6 100644
--- a/net/smc/smc_wr.c
+++ b/net/smc/smc_wr.c
@@ -160,6 +160,7 @@ static inline int smc_wr_tx_get_free_slot_index(struct smc_link *link, u32 *idx)
  * @link:		Pointer to smc_link used to later send the message.
  * @handler:		Send completion handler function pointer.
  * @wr_buf:		Out value returns pointer to message buffer.
+ * @wr_rdma_buf:	Out value returns pointer to rdma work request.
  * @wr_pend_priv:	Out value returns pointer serving as handler context.
  *
  * Return: 0 on success, or -errno on error.
@@ -167,6 +168,7 @@ static inline int smc_wr_tx_get_free_slot_index(struct smc_link *link, u32 *idx)
 int smc_wr_tx_get_free_slot(struct smc_link *link,
 			    smc_wr_tx_handler handler,
 			    struct smc_wr_buf **wr_buf,
+			    struct smc_rdma_wr **wr_rdma_buf,
 			    struct smc_wr_tx_pend_priv **wr_pend_priv)
 {
 	struct smc_wr_tx_pend *wr_pend;
@@ -204,6 +206,8 @@ int smc_wr_tx_get_free_slot(struct smc_link *link,
 	wr_ib = &link->wr_tx_ibs[idx];
 	wr_ib->wr_id = wr_id;
 	*wr_buf = &link->wr_tx_bufs[idx];
+	if (wr_rdma_buf)
+		*wr_rdma_buf = &link->wr_tx_rdmas[idx];
 	*wr_pend_priv = &wr_pend->priv;
 	return 0;
 }
@@ -465,12 +469,26 @@ static void smc_wr_init_sge(struct smc_link *lnk)
 			lnk->wr_tx_dma_addr + i * SMC_WR_BUF_SIZE;
 		lnk->wr_tx_sges[i].length = SMC_WR_TX_SIZE;
 		lnk->wr_tx_sges[i].lkey = lnk->roce_pd->local_dma_lkey;
+		lnk->wr_tx_rdma_sges[i].tx_rdma_sge[0].wr_tx_rdma_sge[0].lkey =
+			lnk->roce_pd->local_dma_lkey;
+		lnk->wr_tx_rdma_sges[i].tx_rdma_sge[0].wr_tx_rdma_sge[1].lkey =
+			lnk->roce_pd->local_dma_lkey;
+		lnk->wr_tx_rdma_sges[i].tx_rdma_sge[1].wr_tx_rdma_sge[0].lkey =
+			lnk->roce_pd->local_dma_lkey;
+		lnk->wr_tx_rdma_sges[i].tx_rdma_sge[1].wr_tx_rdma_sge[1].lkey =
+			lnk->roce_pd->local_dma_lkey;
 		lnk->wr_tx_ibs[i].next = NULL;
 		lnk->wr_tx_ibs[i].sg_list = &lnk->wr_tx_sges[i];
 		lnk->wr_tx_ibs[i].num_sge = 1;
 		lnk->wr_tx_ibs[i].opcode = IB_WR_SEND;
 		lnk->wr_tx_ibs[i].send_flags =
 			IB_SEND_SIGNALED | IB_SEND_SOLICITED;
+		lnk->wr_tx_rdmas[i].wr_tx_rdma[0].wr.opcode = IB_WR_RDMA_WRITE;
+		lnk->wr_tx_rdmas[i].wr_tx_rdma[1].wr.opcode = IB_WR_RDMA_WRITE;
+		lnk->wr_tx_rdmas[i].wr_tx_rdma[0].wr.sg_list =
+			lnk->wr_tx_rdma_sges[i].tx_rdma_sge[0].wr_tx_rdma_sge;
+		lnk->wr_tx_rdmas[i].wr_tx_rdma[1].wr.sg_list =
+			lnk->wr_tx_rdma_sges[i].tx_rdma_sge[1].wr_tx_rdma_sge;
 	}
 	for (i = 0; i < lnk->wr_rx_cnt; i++) {
 		lnk->wr_rx_sges[i].addr =
@@ -521,8 +539,12 @@ void smc_wr_free_link_mem(struct smc_link *lnk)
 	lnk->wr_tx_mask = NULL;
 	kfree(lnk->wr_tx_sges);
 	lnk->wr_tx_sges = NULL;
+	kfree(lnk->wr_tx_rdma_sges);
+	lnk->wr_tx_rdma_sges = NULL;
 	kfree(lnk->wr_rx_sges);
 	lnk->wr_rx_sges = NULL;
+	kfree(lnk->wr_tx_rdmas);
+	lnk->wr_tx_rdmas = NULL;
 	kfree(lnk->wr_rx_ibs);
 	lnk->wr_rx_ibs = NULL;
 	kfree(lnk->wr_tx_ibs);
@@ -552,10 +574,20 @@ int smc_wr_alloc_link_mem(struct smc_link *link)
 				  GFP_KERNEL);
 	if (!link->wr_rx_ibs)
 		goto no_mem_wr_tx_ibs;
+	link->wr_tx_rdmas = kcalloc(SMC_WR_BUF_CNT,
+				    sizeof(link->wr_tx_rdmas[0]),
+				    GFP_KERNEL);
+	if (!link->wr_tx_rdmas)
+		goto no_mem_wr_rx_ibs;
+	link->wr_tx_rdma_sges = kcalloc(SMC_WR_BUF_CNT,
+					sizeof(link->wr_tx_rdma_sges[0]),
+					GFP_KERNEL);
+	if (!link->wr_tx_rdma_sges)
+		goto no_mem_wr_tx_rdmas;
 	link->wr_tx_sges = kcalloc(SMC_WR_BUF_CNT, sizeof(link->wr_tx_sges[0]),
 				   GFP_KERNEL);
 	if (!link->wr_tx_sges)
-		goto no_mem_wr_rx_ibs;
+		goto no_mem_wr_tx_rdma_sges;
 	link->wr_rx_sges = kcalloc(SMC_WR_BUF_CNT * 3,
 				   sizeof(link->wr_rx_sges[0]),
 				   GFP_KERNEL);
@@ -579,6 +611,10 @@ int smc_wr_alloc_link_mem(struct smc_link *link)
 	kfree(link->wr_rx_sges);
 no_mem_wr_tx_sges:
 	kfree(link->wr_tx_sges);
+no_mem_wr_tx_rdma_sges:
+	kfree(link->wr_tx_rdma_sges);
+no_mem_wr_tx_rdmas:
+	kfree(link->wr_tx_rdmas);
 no_mem_wr_rx_ibs:
 	kfree(link->wr_rx_ibs);
 no_mem_wr_tx_ibs:
diff --git a/net/smc/smc_wr.h b/net/smc/smc_wr.h
index 1d85bb14fd6f..09bf32fd3959 100644
--- a/net/smc/smc_wr.h
+++ b/net/smc/smc_wr.h
@@ -85,6 +85,7 @@ void smc_wr_add_dev(struct smc_ib_device *smcibdev);
 
 int smc_wr_tx_get_free_slot(struct smc_link *link, smc_wr_tx_handler handler,
 			    struct smc_wr_buf **wr_buf,
+			    struct smc_rdma_wr **wrs,
 			    struct smc_wr_tx_pend_priv **wr_pend_priv);
 int smc_wr_tx_put_slot(struct smc_link *link,
 		       struct smc_wr_tx_pend_priv *wr_pend_priv);
-- 
2.16.4


^ permalink raw reply related

* Re: [RFC PATCH net-next 1/6 v2] net/sched: Introduce act_ct
From: Simon Horman @ 2019-02-04 12:48 UTC (permalink / raw)
  To: Paul Blakey
  Cc: Marcelo Leitner, Guy Shattah, Aaron Conole, John Hurley,
	Justin Pettit, Gregory Rose, Eelco Chaudron, Flavio Leitner,
	Florian Westphal, Jiri Pirko, Rashid Khan, Sushil Kulkarni,
	Andy Gospodarek, Roi Dayan, Yossi Kuperman, Or Gerlitz,
	Rony Efraim, davem@davemloft.net, netdev@vger.kernel.org
In-Reply-To: <eea67d27-f09a-df22-090e-f6f121bc55af@mellanox.com>

[Repost without HTML; sorry about that]

On Sun, Feb 03, 2019 at 08:26:23AM +0000, Paul Blakey wrote:
> 
> 
> On 01/02/2019 15:23, Marcelo Leitner wrote:
> > On Tue, Jan 29, 2019 at 10:02:01AM +0200, Paul Blakey wrote:
> > ...
> >> diff --git a/include/uapi/linux/tc_act/tc_ct.h b/include/uapi/linux/tc_act/tc_ct.h
> >> new file mode 100644
> >> index 0000000..6dbd771
> >> --- /dev/null
> >> +++ b/include/uapi/linux/tc_act/tc_ct.h
> >> @@ -0,0 +1,29 @@
> >> +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
> >> +#ifndef __UAPI_TC_CT_H
> >> +#define __UAPI_TC_CT_H
> >> +
> >> +#include <linux/types.h>
> >> +#include <linux/pkt_cls.h>
> >> +
> >> +#define TCA_ACT_CT 18
> >> +
> >> +struct tc_ct {
> >> +	tc_gen;
> >> +	__u16 zone;
> >> +	__u32 labels[4];
> >> +	__u32 labels_mask[4];
> >> +	__u32 mark;
> >> +	__u32 mark_mask;
> >> +	bool commit;
> > 
> > This is one of the points that our implementations differs. You used a
> > struct and wrapped it into TCA_CT_PARMS attribute, while I broke it up
> > into several attributes.
> > 
> > cls_flower and act_bpf, for example, doesn't use structs, but others
> > do.
> > 
> > Both have pros and cons and I imagine this topic probably was already
> > discussed but I'm not aware of a recommendation. Do we have one?
> 
> I guess flower uses a netlink attribute per key attribute because
> a lot of time, most of them won't be used, and you would send less.
> we can have ct, ct + snat, ct + dnat, zone and mark.... a lot of this
> won't be used sometimes.
> 
> Also you can't add nested attributes to the struct easily.
> 
> Also netlink attributes can be tested for existence, while a struct
> would need a special non valid value, or another field to specify which
> fields are used.
> 
> both are hard to test if a requested attribute was ignored, besides
> checking the netlink echo or dumping the action back. if for example a
> older kernel module and newer userspace uses a attribute above
> enum TCA_CT_MAX (struct attributes also don't have max len, in nla_parse).
> 
> 
> All in all, I think mostly netlink attributes would be better.

+1

I believe that Flower uses more attributes because its regarded as being
more flexible and that benefit outweighs the extra cost - f.e. the netlink
messages would tend to be a bit larger if a struct was used.

> 
> > 
> >> +};
> >> +
> >> +enum {
> >> +	TCA_CT_UNSPEC,
> >> +	TCA_CT_PARMS,
> >> +	TCA_CT_TM,
> >> +	TCA_CT_PAD,
> >> +	__TCA_CT_MAX
> >> +};
> >> +#define TCA_CT_MAX (__TCA_CT_MAX - 1)
> >> +
> >> +#endif /* __UAPI_TC_CT_H */
> > ...
> > 

^ permalink raw reply

* Re: [PATCH] selftests/netfilter: fix config fragment CONFIG_NF_TABLES_INET
From: Pablo Neira Ayuso @ 2019-02-04 13:21 UTC (permalink / raw)
  To: Naresh Kamboju; +Cc: netfilter-devel, netdev, fw, davem, linux-kselftest
In-Reply-To: <20190129062835.31122-1-naresh.kamboju@linaro.org>

On Tue, Jan 29, 2019 at 06:28:35AM +0000, Naresh Kamboju wrote:
> In selftests the config fragment for netfilter was added as
> NF_TABLES_INET=y and this patch correct it as CONFIG_NF_TABLES_INET=y

Applied, thanks.

^ permalink raw reply

* Re: [PATCH v2 2/2] netdev/phy: add MDIO bus multiplexer driven by a regmap
From: Andrew Lunn @ 2019-02-04 13:46 UTC (permalink / raw)
  To: Pankaj Bansal; +Cc: Florian Fainelli, netdev@vger.kernel.org
In-Reply-To: <20190204142435.21175-3-pankaj.bansal@nxp.com>

On Mon, Feb 04, 2019 at 08:59:50AM +0000, Pankaj Bansal wrote:
> Add support for an MDIO bus multiplexer controlled by a regmap
> device, like an FPGA.

Hi Pankaj

Thanks for adding the binding documentation.

> diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
> index 5805c0b7d60e..0827a700eb31 100644
> --- a/drivers/net/phy/Makefile
> +++ b/drivers/net/phy/Makefile
> @@ -26,6 +26,7 @@ obj-$(CONFIG_MDIO_BCM_IPROC)	+= mdio-bcm-iproc.o
>  obj-$(CONFIG_MDIO_BCM_UNIMAC)	+= mdio-bcm-unimac.o
>  obj-$(CONFIG_MDIO_BITBANG)	+= mdio-bitbang.o
>  obj-$(CONFIG_MDIO_BUS_MUX)	+= mdio-mux.o
> +obj-$(CONFIG_MDIO_BUS_MUX_REGMAP)	+= mdio-mux-regmap.o
>  obj-$(CONFIG_MDIO_BUS_MUX_BCM_IPROC)	+= mdio-mux-bcm-iproc.o
>  obj-$(CONFIG_MDIO_BUS_MUX_GPIO)	+= mdio-mux-gpio.o
>  obj-$(CONFIG_MDIO_BUS_MUX_MMIOREG) += mdio-mux-mmioreg.o

We try to keep the Makefile sorting in alphabetical order.


> +/**
> + * mdio_mux_regmap_uninit - relinquish the control of MDIO bus muxing using
> + *			    regmap constructs.
> + * @data: address of data allocated by mdio_mux_regmap_init
> + */
> +int mdio_mux_regmap_uninit(void *data)
> +{
> +	struct mdio_mux_regmap_state *s = data;
> +
> +	mdio_mux_uninit(s->mux_handle);
> +
> +	return 0;
> +}

Please make this a void function, since there is nothing to return.

       Andrew

^ permalink raw reply

* pull-request: wireless-drivers 2019-02-04
From: Kalle Valo @ 2019-02-04 13:58 UTC (permalink / raw)
  To: David Miller; +Cc: linux-wireless, netdev, linux-kernel

Hi Dave,

here are fixes to net tree for 5.0, more info below. Please let me know
if there are any problems.

Kalle


The following changes since commit bfeffd155283772bbe78c6a05dec7c0128ee500c:

  Linux 5.0-rc1 (2019-01-06 17:08:20 -0800)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers.git tags/wireless-drivers-for-davem-2019-02-04

for you to fetch changes up to 8c22d81d55353209f8976074ffa9fb1085da0830:

  MAINTAINERS: add entry for redpine wireless driver (2019-02-03 21:41:51 +0200)

----------------------------------------------------------------
wireless-drivers fixes for 5.0

First set of small, but importnat, fixes for 5.0.

iwlwifi

* fix a build regression introduced in 5.0-rc1

wlcore

* fix a firmware regression from v4.18-rc1

mt76x0

* fix for configuring tx power from user space

ath10k

* fix wcn3990 regression from v4.20-rc1

----------------------------------------------------------------
Brian Norris (1):
      ath10k: correct bus type for WCN3990

Lorenzo Bianconi (1):
      mt76x0: eeprom: fix chan_vs_power map in mt76x0_get_power_info

Luca Coelho (1):
      iwlwifi: make IWLWIFI depend on CFG80211

Siva Rebbagondla (1):
      MAINTAINERS: add entry for redpine wireless driver

Ulf Hansson (1):
      wlcore: sdio: Fixup power on/off sequence

 MAINTAINERS                                        |  7 ++++
 drivers/net/wireless/ath/ath10k/core.c             |  2 +-
 drivers/net/wireless/intel/iwlwifi/Kconfig         |  3 +-
 drivers/net/wireless/mediatek/mt76/mt76x0/eeprom.c | 40 ++++++++++------------
 drivers/net/wireless/mediatek/mt76/mt76x0/eeprom.h |  2 +-
 drivers/net/wireless/mediatek/mt76/mt76x0/phy.c    | 10 +++---
 drivers/net/wireless/ti/wlcore/sdio.c              | 15 ++++----
 7 files changed, 42 insertions(+), 37 deletions(-)

^ permalink raw reply

* Re: stmmac / meson8b-dwmac
From: Martin Blumenstingl @ 2019-02-04 14:34 UTC (permalink / raw)
  To: ingrassia, Gpeppe.cavallaro, alexandre.torgue
  Cc: Simon Huelck, linux-amlogic, netdev
In-Reply-To: <e05b7448-cd95-cdeb-c88d-3a324d5f1ddc@gmx.de>

On Thu, Jan 17, 2019 at 10:23 PM Simon Huelck <simonmail@gmx.de> wrote:
[...]
> >> I got problems with my ODROID c2 running on 4.19.16 ( and some releases
> >> earlier ). the stmmac / dwmac driver doesnt provide the 800M/900M
> >> performance that i was used to earlier.
> >>
> >>
> >> Now im stuck near 550M/600M in the same environment. but what really
> >> confuses me that duplex does hurt even more.
> > interesting that you see this on the Odroid-C2 as well.
> > previously I have only observed it on an Odroid-C1
> >
> >> PC --- VLAN3 --> switch --VLAN3--> ODROID
> >>
> >> NAS <-- VLAN1 -- switch <-- VLAN1-- ODROID
> >>
> >>
> >> this means when im doing a iperf from PC to NAS, that my ODROID has load
> >> on RX/TX same time (duplex). this shouldnt be an issue , all is 1GBits
> >> FD. And in the past that wasnt an issue.
+Cc Emiliano who has seen a similar duplex issue on his Odroid-C1: [0]
(please note that all kernels prior to v5.1 with the pending patches
from [1] applied are only receiving data on RXD0 and RXD1 but not on
RXD2 and RXD3)

Emiliano, can you confirm the duplex issue observed by Simon is
similar to the one you see on your Odroid-C1?

> >>
> >>
> >> Now what happens:
> >>
> >> - benchmark between PC - ODROID is roughly 550M
> >>
> >> - benchmark between NAS - ODROID is roughly 550M
> >>
> >> - benchmark between PC - NAS is only around 300M
> >>
> >>
> >> and like i said i was easliy able to hit 800 or even 900M to my NAS
> >> earlier. I applied some .dtb fixes for interrupt levels for the
> >> meson-gx.dtsi and meson-gxbb-odroid-c2.dtb, which will be mainlined ,
> >> but the effect stayed identical.
> > good that you have the interrupt patches already applied
> > I believe it don't fix any performance issues - it's a fix for the
> > Ethernet controller seemingly getting "stuck" (not processing data
> > anymore). however, that already rules out one potential issue
> >
> >> are you aware of this problem ? Earlier kernel versions were all
> >> perfectly fine and i stepped ( self compiled) kernel through all major
> >> releases since odroid c2 was mainlined.
Guiseppe, Alexandre: what kind of data do you need from us if we see
the speeds drop (in both directions) when we send and receive at the
same time?

[...]
> the problem is that i dont have these kernel sources anymore :-(. but i
> can provide some testing and numbers. maybe i dig if i got these kernel
> configs somewhere around but i did not change much during migrating
do you remember the kernel version where it worked fine?

> im using a zyxel gs1900-8 switch and a qnap ts231p , and as i said i
> didnt change my setup. i was able to hit 100MByte/s from my NAS , so
> close to the benchmarks of 900MBit/s
I typically only do small transfers or I have traffic only in one direction.
thus it's likely that I missed this in my own tests


Regards
Martin


[0] http://lists.infradead.org/pipermail/linux-amlogic/2018-December/009679.html
[1] https://patchwork.kernel.org/cover/10744905/

^ permalink raw reply

* [PATCH iproute2-next v3] devlink: add info subcommand
From: Jakub Kicinski @ 2019-02-04 14:43 UTC (permalink / raw)
  To: jiri, dsahern; +Cc: stephen, netdev, oss-drivers, Jakub Kicinski

Add support for reading the device serial number, driver name
and various versions.  Example:

$ devlink dev info pci/0000:82:00.0
pci/0000:82:00.0:
  driver nfp
  serial_number 16240145
  versions:
      fixed:
        board.id AMDA0081-0001
        board.rev 15
        board.vendor SMA
        board.model hydrogen
      running:
        fw.bundle_id -
        fw.mgmt 010181.010181.0101d4
        fw.cpld 0x1030000
        fw.app abm-d372b6
        fw.undi 0.0.0
        fw.ncsi -
        chip.init AMDA-0081-0001  20160318164536
      stored:
        fw.bundle_id -
        fw.mgmt 010181.010181.0101d4
        fw.cpld 0xfeedbeef
        fw.app -
        fw.undi 0.0.0
        fw.ncsi -
        chip.init AMDA-0081-0001  20160318164536

$ devlink -jp dev info pci/0000:82:00.0
{
    "info": {
        "pci/0000:82:00.0": {

            "driver": "nfp",
            "serial_number": "16240145",
            "versions": {
                "fixed": {
                    "board.id": "AMDA0081-0001",
                    "board.rev": "15",
                    "board.vendor": "SMA",
                    "board.model": "hydrogen"
                },
                "running": {
                    "fw.bundle_id": "-",
                    "fw.mgmt": "010181.010181.0101d4",
                    "fw.cpld": "0x1030000",
                    "fw.app": "abm-d372b6",
                    "fw.undi": "0.0.0",
                    "fw.ncsi": "-",
                    "chip.init": "AMDA-0081-0001  20160318164536"
                },
                "stored": {
                    "fw.bundle_id": "-",
                    "fw.mgmt": "010181.010181.0101d4",
                    "fw.cpld": "0xfeedbeef",
                    "fw.app": "-",
                    "fw.undi": "0.0.0",
                    "fw.ncsi": "-",
                    "chip.init": "AMDA-0081-0001  20160318164536"
                }
            }
        }
    }
}

v3:
 - show up-to-date output in the commit message.
v2 (Jiri):
 - remove filtering;
 - add example in the commit message.
RFCv2:
 - make info subcommand of dev.

Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
---
 devlink/devlink.c      | 169 +++++++++++++++++++++++++++++++++++++++++
 man/man8/devlink-dev.8 |  26 +++++++
 2 files changed, 195 insertions(+)

diff --git a/devlink/devlink.c b/devlink/devlink.c
index 3651e90c1159..fc4b18d1b613 100644
--- a/devlink/devlink.c
+++ b/devlink/devlink.c
@@ -383,6 +383,13 @@ static const enum mnl_attr_data_type devlink_policy[DEVLINK_ATTR_MAX + 1] = {
 	[DEVLINK_ATTR_REGION_CHUNK_DATA] = MNL_TYPE_BINARY,
 	[DEVLINK_ATTR_REGION_CHUNK_ADDR] = MNL_TYPE_U64,
 	[DEVLINK_ATTR_REGION_CHUNK_LEN] = MNL_TYPE_U64,
+	[DEVLINK_ATTR_INFO_DRIVER_NAME] = MNL_TYPE_STRING,
+	[DEVLINK_ATTR_INFO_SERIAL_NUMBER] = MNL_TYPE_STRING,
+	[DEVLINK_ATTR_INFO_VERSION_FIXED] = MNL_TYPE_NESTED,
+	[DEVLINK_ATTR_INFO_VERSION_RUNNING] = MNL_TYPE_NESTED,
+	[DEVLINK_ATTR_INFO_VERSION_STORED] = MNL_TYPE_NESTED,
+	[DEVLINK_ATTR_INFO_VERSION_NAME] = MNL_TYPE_STRING,
+	[DEVLINK_ATTR_INFO_VERSION_VALUE] = MNL_TYPE_STRING,
 };
 
 static int attr_cb(const struct nlattr *attr, void *data)
@@ -1443,6 +1450,7 @@ static void cmd_dev_help(void)
 	pr_err("       devlink dev param set DEV name PARAMETER value VALUE cmode { permanent | driverinit | runtime }\n");
 	pr_err("       devlink dev param show [DEV name PARAMETER]\n");
 	pr_err("       devlink dev reload DEV\n");
+	pr_err("       devlink dev info [ DEV ]\n");
 }
 
 static bool cmp_arr_last_handle(struct dl *dl, const char *bus_name,
@@ -1775,6 +1783,30 @@ static void pr_out_array_end(struct dl *dl)
 	}
 }
 
+static void pr_out_object_start(struct dl *dl, const char *name)
+{
+	if (dl->json_output) {
+		jsonw_name(dl->jw, name);
+		jsonw_start_object(dl->jw);
+	} else {
+		__pr_out_indent_inc();
+		__pr_out_newline();
+		pr_out("%s:", name);
+		__pr_out_indent_inc();
+		__pr_out_newline();
+	}
+}
+
+static void pr_out_object_end(struct dl *dl)
+{
+	if (dl->json_output) {
+		jsonw_end_object(dl->jw);
+	} else {
+		__pr_out_indent_dec();
+		__pr_out_indent_dec();
+	}
+}
+
 static void pr_out_entry_start(struct dl *dl)
 {
 	if (dl->json_output)
@@ -2415,6 +2447,140 @@ static int cmd_dev_reload(struct dl *dl)
 	return _mnlg_socket_sndrcv(dl->nlg, nlh, NULL, NULL);
 }
 
+static void pr_out_versions_single(struct dl *dl, const struct nlmsghdr *nlh,
+				   const char *name, int type)
+{
+	struct nlattr *version;
+
+	mnl_attr_for_each(version, nlh, sizeof(struct genlmsghdr)) {
+		struct nlattr *tb[DEVLINK_ATTR_MAX + 1] = {};
+		const char *ver_value;
+		const char *ver_name;
+		int err;
+
+		if (mnl_attr_get_type(version) != type)
+			continue;
+
+		err = mnl_attr_parse_nested(version, attr_cb, tb);
+		if (err != MNL_CB_OK)
+			continue;
+
+		if (!tb[DEVLINK_ATTR_INFO_VERSION_NAME] ||
+		    !tb[DEVLINK_ATTR_INFO_VERSION_VALUE])
+			continue;
+
+		if (name) {
+			pr_out_object_start(dl, name);
+			name = NULL;
+		}
+
+		ver_name = mnl_attr_get_str(tb[DEVLINK_ATTR_INFO_VERSION_NAME]);
+		ver_value = mnl_attr_get_str(tb[DEVLINK_ATTR_INFO_VERSION_VALUE]);
+
+		pr_out_str(dl, ver_name, ver_value);
+		if (!dl->json_output)
+			__pr_out_newline();
+	}
+
+	if (!name)
+		pr_out_object_end(dl);
+}
+
+static void pr_out_info(struct dl *dl, const struct nlmsghdr *nlh,
+			struct nlattr **tb, bool has_versions)
+{
+	__pr_out_handle_start(dl, tb, true, false);
+
+	__pr_out_indent_inc();
+	if (tb[DEVLINK_ATTR_INFO_DRIVER_NAME]) {
+		struct nlattr *nla_drv = tb[DEVLINK_ATTR_INFO_DRIVER_NAME];
+
+		__pr_out_newline();
+		pr_out_str(dl, "driver", mnl_attr_get_str(nla_drv));
+	}
+
+	if (tb[DEVLINK_ATTR_INFO_SERIAL_NUMBER]) {
+		struct nlattr *nla_sn = tb[DEVLINK_ATTR_INFO_SERIAL_NUMBER];
+
+		__pr_out_newline();
+		pr_out_str(dl, "serial_number", mnl_attr_get_str(nla_sn));
+	}
+	__pr_out_indent_dec();
+
+	if (has_versions) {
+		pr_out_object_start(dl, "versions");
+
+		pr_out_versions_single(dl, nlh, "fixed",
+				       DEVLINK_ATTR_INFO_VERSION_FIXED);
+		pr_out_versions_single(dl, nlh, "running",
+				       DEVLINK_ATTR_INFO_VERSION_RUNNING);
+		pr_out_versions_single(dl, nlh, "stored",
+				       DEVLINK_ATTR_INFO_VERSION_STORED);
+
+		pr_out_object_end(dl);
+	}
+
+	pr_out_handle_end(dl);
+}
+
+static int cmd_versions_show_cb(const struct nlmsghdr *nlh, void *data)
+{
+	struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh);
+	struct nlattr *tb[DEVLINK_ATTR_MAX + 1] = {};
+	bool has_versions, has_info;
+	struct dl *dl = data;
+
+	mnl_attr_parse(nlh, sizeof(*genl), attr_cb, tb);
+
+	if (!tb[DEVLINK_ATTR_BUS_NAME] || !tb[DEVLINK_ATTR_DEV_NAME])
+		return MNL_CB_ERROR;
+
+	has_versions = tb[DEVLINK_ATTR_INFO_VERSION_FIXED] ||
+		tb[DEVLINK_ATTR_INFO_VERSION_RUNNING] ||
+		tb[DEVLINK_ATTR_INFO_VERSION_STORED];
+	has_info = tb[DEVLINK_ATTR_INFO_DRIVER_NAME] ||
+		tb[DEVLINK_ATTR_INFO_SERIAL_NUMBER] ||
+		has_versions;
+
+	if (has_info)
+		pr_out_info(dl, nlh, tb, has_versions);
+
+	return MNL_CB_OK;
+}
+
+static void cmd_dev_info_help(void)
+{
+	pr_err("Usage: devlink dev info [ DEV ]\n");
+}
+
+static int cmd_dev_info(struct dl *dl)
+{
+	struct nlmsghdr *nlh;
+	uint16_t flags = NLM_F_REQUEST | NLM_F_ACK;
+	int err;
+
+	if (dl_argv_match(dl, "help")) {
+		cmd_dev_info_help();
+		return 0;
+	}
+
+	if (dl_argc(dl) == 0)
+		flags |= NLM_F_DUMP;
+
+	nlh = mnlg_msg_prepare(dl->nlg, DEVLINK_CMD_INFO_GET, flags);
+
+	if (dl_argc(dl) > 0) {
+		err = dl_argv_parse_put(nlh, dl, DL_OPT_HANDLE, 0);
+		if (err)
+			return err;
+	}
+
+	pr_out_section_start(dl, "info");
+	err = _mnlg_socket_sndrcv(dl->nlg, nlh, cmd_versions_show_cb, dl);
+	pr_out_section_end(dl);
+	return err;
+}
+
 static int cmd_dev(struct dl *dl)
 {
 	if (dl_argv_match(dl, "help")) {
@@ -2433,6 +2599,9 @@ static int cmd_dev(struct dl *dl)
 	} else if (dl_argv_match(dl, "param")) {
 		dl_arg_inc(dl);
 		return cmd_dev_param(dl);
+	} else if (dl_argv_match(dl, "info")) {
+		dl_arg_inc(dl);
+		return cmd_dev_info(dl);
 	}
 	pr_err("Command \"%s\" not found\n", dl_argv(dl));
 	return -ENOENT;
diff --git a/man/man8/devlink-dev.8 b/man/man8/devlink-dev.8
index d985da172aa0..47838371fecd 100644
--- a/man/man8/devlink-dev.8
+++ b/man/man8/devlink-dev.8
@@ -63,6 +63,12 @@ devlink-dev \- devlink device configuration
 .BR "devlink dev reload"
 .IR DEV
 
+.ti -8
+.BR "devlink dev info"
+.RI "[ "
+.IR DEV
+.RI "]"
+
 .SH "DESCRIPTION"
 .SS devlink dev show - display devlink device attributes
 
@@ -151,6 +157,26 @@ If this argument is omitted all parameters supported by devlink devices are list
 .I "DEV"
 - Specifies the devlink device to reload.
 
+.SS devlink dev info - display device information.
+Display device information provided by the driver. This command can be used
+to query versions of the hardware components or device components which
+can't be updated (
+.I fixed
+) as well as device firmware which can be updated. For firmware components
+.I running
+displays the versions of firmware currently loaded into the device, while
+.I stored
+reports the versions in device's flash.
+.I Running
+and
+.I stored
+versions may differ after flash has been updated, but before reboot.
+
+.PP
+.I "DEV"
+- specifies the devlink device to show.
+If this argument is omitted all devices are listed.
+
 .SH "EXAMPLES"
 .PP
 devlink dev show
-- 
2.19.2


^ permalink raw reply related

* [PATCH iproute2-next v2] devlink: report cell size
From: Jakub Kicinski @ 2019-02-04 14:44 UTC (permalink / raw)
  To: idosch, jiri, dsahern; +Cc: stephen, oss-drivers, netdev, Jakub Kicinski

Print the value of DEVLINK_ATTR_SB_POOL_CELL_SIZE, if reported.

Example:
pci/0000:82:00.0:
  sb 1 pool 0 type egress size 40945664 thtype static cell_size 2048
  sb 2 pool 0 type egress size 258867200 thtype static cell_size 10240
...

v2: - fix spelling.

Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Reviewed-by: Quentin Monnet <quentin.monnet@netronome.com>
---
 devlink/devlink.c     |  3 +++
 man/man8/devlink-sb.8 | 10 ++++++++++
 2 files changed, 13 insertions(+)

diff --git a/devlink/devlink.c b/devlink/devlink.c
index fc4b18d1b613..40f6105af109 100644
--- a/devlink/devlink.c
+++ b/devlink/devlink.c
@@ -2891,6 +2891,9 @@ static void pr_out_sb_pool(struct dl *dl, struct nlattr **tb)
 		    mnl_attr_get_u32(tb[DEVLINK_ATTR_SB_POOL_SIZE]));
 	pr_out_str(dl, "thtype",
 		   threshold_type_name(mnl_attr_get_u8(tb[DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE])));
+	if (tb[DEVLINK_ATTR_SB_POOL_CELL_SIZE])
+		pr_out_uint(dl, "cell_size",
+			    mnl_attr_get_u32(tb[DEVLINK_ATTR_SB_POOL_CELL_SIZE]));
 	pr_out_handle_end(dl);
 }
 
diff --git a/man/man8/devlink-sb.8 b/man/man8/devlink-sb.8
index 1882833a3fa7..0deacd9ccd23 100644
--- a/man/man8/devlink-sb.8
+++ b/man/man8/devlink-sb.8
@@ -128,6 +128,16 @@ Behaviour of this argument it the same for every command.
 - specifies the devlink device to show pools.
 If this argument is omitted all pools of all devices are listed.
 
+Display available pools listing their
+.B type, size, thtype
+and
+.B cell_size. cell_size
+is the allocation granularity of memory within the shared buffer.  Drivers
+may round up, round down or reject
+.B size
+passed to the set command if it is not multiple of
+.B cell_size.
+
 .SS devlink sb pool set - set attributes of pool
 
 .PP
-- 
2.19.2


^ permalink raw reply related

* [PATCH net] net: cls_flower: Remove filter from mask before freeing it
From: Petr Machata @ 2019-02-04 14:50 UTC (permalink / raw)
  To: netdev@vger.kernel.org
  Cc: jhs@mojatatu.com, xiyou.wangcong@gmail.com, jiri@resnulli.us,
	Ido Schimmel, Paul Blakey, davem@davemloft.net

In fl_change(), when adding a new rule (i.e. fold == NULL), a driver may
reject the new rule, for example due to resource exhaustion. By that
point, the new rule was already assigned a mask, and it was added to
that mask's hash table. The clean-up path that's invoked as a result of
the rejection however neglects to undo the hash table addition, and
proceeds to free the new rule, thus leaving a dangling pointer in the
hash table.

Fix by removing fnew from the mask's hash table before it is freed.

Fixes: 35cc3cefc4de ("net/sched: cls_flower: Reject duplicated rules
also under skip_sw")
Signed-off-by: Petr Machata <petrm@mellanox.com>
Acked-by: Jiri Pirko <jiri@mellanox.com>
Reviewed-by: Ido Schimmel <idosch@mellanox.com>
---

Notes:
    Note that this is covered by mirror_gre_scale test in
    tools/testing/selftests/drivers/net/mlxsw/spectrum/resource_scale.sh

 net/sched/cls_flower.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/net/sched/cls_flower.c b/net/sched/cls_flower.c
index f6aa57fbbbaf..12ca9d13db83 100644
--- a/net/sched/cls_flower.c
+++ b/net/sched/cls_flower.c
@@ -1371,7 +1371,7 @@ static int fl_change(struct net *net, struct sk_buff *in_skb,
 	if (!tc_skip_hw(fnew->flags)) {
 		err = fl_hw_replace_filter(tp, fnew, extack);
 		if (err)
-			goto errout_mask;
+			goto errout_mask_ht;
 	}
 
 	if (!tc_in_hw(fnew->flags))
@@ -1401,6 +1401,10 @@ static int fl_change(struct net *net, struct sk_buff *in_skb,
 	kfree(mask);
 	return 0;
 
+errout_mask_ht:
+	rhashtable_remove_fast(&fnew->mask->ht, &fnew->ht_node,
+			       fnew->mask->filter_ht_params);
+
 errout_mask:
 	fl_mask_put(head, fnew->mask, false);
 
-- 
2.4.11


^ permalink raw reply related

* Re: [PATCH bpf-next v4 0/3] tools/bpf: changes of libbpf debug interfaces
From: Arnaldo Carvalho de Melo @ 2019-02-04 14:51 UTC (permalink / raw)
  To: Yonghong Song
  Cc: Alexei Starovoitov, Magnus Karlsson, netdev, Alexei Starovoitov,
	Daniel Borkmann, kernel-team, Arnaldo Carvalho de Melo
In-Reply-To: <20190202165228.jrcghbvro4st4thd@ast-mbp>

Em Sat, Feb 02, 2019 at 08:52:30AM -0800, Alexei Starovoitov escreveu:
> On Fri, Feb 01, 2019 at 04:14:13PM -0800, Yonghong Song wrote:
> > These are patches responding to my comments for
> > Magnus's patch (https://patchwork.ozlabs.org/patch/1032848/).
> > The goal is to make pr_* macros available to other C files
> > than libbpf.c, and to simplify API function libbpf_set_print().
> > 
> > Specifically, Patch #1 used global functions
> > to facilitate pr_* macros in the header files so they
> > are available in different C files.
> > Patch #2 removes the global function libbpf_print_level_available()
> > which is added in Patch 1.
> > Patch #3 simplified libbpf_set_print() which takes only one print
> > function with a debug level argument among others.
> > 
> > Changelogs:
> >  v3 -> v4:
> >    . rename libbpf internal header util.h to libbpf_util.h
> >    . rename libbpf internal function libbpf_debug_print() to libbpf_print()
> >  v2 -> v3:
> >    . bailed out earlier in libbpf_debug_print() if __libbpf_pr is NULL
> >    . added missing LIBBPF_DEBUG level check in libbpf.c __base_pr().
> >  v1 -> v2:
> >    . Renamed global function libbpf_dprint() to libbpf_debug_print()
> >      to be more expressive.
> >    . Removed libbpf_dprint_level_available() as it is used only
> >      once in btf.c and we can remove it by optimizing for common cases.
> > 
> > Yonghong Song (3):
> >   tools/bpf: move libbpf pr_* debug print functions to headers
> >   tools/bpf: print out btf log at LIBBPF_WARN level
> >   tools/bpf: simplify libbpf API function libbpf_set_print()
> > 
> >  tools/lib/bpf/btf.c                           | 110 +++++++++---------
> >  tools/lib/bpf/btf.h                           |   7 +-
> >  tools/lib/bpf/libbpf.c                        |  47 ++++----
> >  tools/lib/bpf/libbpf.h                        |  20 ++--
> >  tools/lib/bpf/libbpf_util.h                   |  30 +++++
> >  tools/lib/bpf/test_libbpf.cpp                 |   4 +-
> >  tools/perf/util/bpf-loader.c                  |  32 ++---
> 
> Overall looks good to me.
> Arnaldo, could you ack the set, so we can take it into bpf-next?

LGTM

Acked-by: Arnaldo Carvalho de Melo <acme@redhat.com>

- Arnaldo

^ permalink raw reply

* Re: [PATCH] Bluetooth: Fix decrementing reference count twice in releasing socket
From: Marcel Holtmann @ 2019-02-04 14:53 UTC (permalink / raw)
  To: Myungho Jung
  Cc: Johan Hedberg, David S. Miller, linux-bluetooth, netdev,
	linux-kernel
In-Reply-To: <20190203005634.GA19908@myunghoj-Precision-5530>

Hi Myungho,

> When releasing socket, it is possible to enter hci_sock_release() and
> hci_sock_dev_event(HCI_DEV_UNREG) at the same time in different thread.
> The reference count of hdev should be decremented only once from one of
> them but if storing hdev to local variable in hci_sock_release() before
> detached from socket and setting to NULL in hci_sock_dev_event(),
> hci_dev_put(hdev) is unexpectedly called twice. This is resolved by
> referencing hdev from socket after bt_sock_unlink() in
> hci_sock_release().
> 
> Reported-by: syzbot+fdc00003f4efff43bc5b@syzkaller.appspotmail.com
> Signed-off-by: Myungho Jung <mhjungk@gmail.com>
> ---
> net/bluetooth/hci_sock.c | 3 +--
> 1 file changed, 1 insertion(+), 2 deletions(-)

patch has been applied to bluetooth-next tree.

Regards

Marcel


^ permalink raw reply

* Re: [PATCH v2 2/2] netdev/phy: add MDIO bus multiplexer driven by a regmap
From: kbuild test robot @ 2019-02-04 14:51 UTC (permalink / raw)
  To: Pankaj Bansal
  Cc: kbuild-all, Andrew Lunn, Florian Fainelli, netdev@vger.kernel.org,
	Pankaj Bansal
In-Reply-To: <20190204142435.21175-3-pankaj.bansal@nxp.com>

[-- Attachment #1: Type: text/plain, Size: 5241 bytes --]

Hi Pankaj,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on net/master]
[also build test ERROR on v5.0-rc4]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Pankaj-Bansal/add-MDIO-bus-multiplexer-driven-by-a-regmap-device/20190204-213429
config: sh-allmodconfig (attached as .config)
compiler: sh4-linux-gnu-gcc (Debian 8.2.0-11) 8.2.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        GCC_VERSION=8.2.0 make.cross ARCH=sh 

All errors (new ones prefixed by >>):

>> drivers/net/phy/mdio-mux-regmap.c:72:5: error: redefinition of 'mdio_mux_regmap_init'
    int mdio_mux_regmap_init(struct device *dev,
        ^~~~~~~~~~~~~~~~~~~~
   In file included from drivers/net/phy/mdio-mux-regmap.c:18:
   include/linux/mdio-mux.h:53:19: note: previous definition of 'mdio_mux_regmap_init' was here
    static inline int mdio_mux_regmap_init(struct device *dev,
                      ^~~~~~~~~~~~~~~~~~~~
>> drivers/net/phy/mdio-mux-regmap.c:158:5: error: redefinition of 'mdio_mux_regmap_uninit'
    int mdio_mux_regmap_uninit(void *data)
        ^~~~~~~~~~~~~~~~~~~~~~
   In file included from drivers/net/phy/mdio-mux-regmap.c:18:
   include/linux/mdio-mux.h:60:19: note: previous definition of 'mdio_mux_regmap_uninit' was here
    static inline int mdio_mux_regmap_uninit(void *data)
                      ^~~~~~~~~~~~~~~~~~~~~~

vim +/mdio_mux_regmap_init +72 drivers/net/phy/mdio-mux-regmap.c

    62	
    63	/**
    64	 * mdio_mux_regmap_init - control MDIO bus muxing using regmap constructs.
    65	 * @dev: device with which regmap construct is associated.
    66	 * @mux_node: mdio bus mux node that contains parent mdio bus phandle.
    67	 *	      This node also contains sub nodes, where each subnode denotes
    68	 *	      a child mdio bus. All the child mdio buses are muxed, i.e. at a
    69	 *	      time only one of the child mdio buses can be used.
    70	 * @data: to store the address of data allocated by this function
    71	 */
  > 72	int mdio_mux_regmap_init(struct device *dev,
    73				 struct device_node *mux_node,
    74				 void **data)
    75	{
    76		struct device_node *child;
    77		struct mdio_mux_regmap_state *s;
    78		int ret;
    79		u32 val;
    80	
    81		dev_dbg(dev, "probing node %pOF\n", mux_node);
    82	
    83		s = devm_kzalloc(dev, sizeof(*s), GFP_KERNEL);
    84		if (!s)
    85			return -ENOMEM;
    86	
    87		s->regmap = dev_get_regmap(dev, NULL);
    88		if (IS_ERR(s->regmap)) {
    89			dev_err(dev, "Failed to get parent regmap\n");
    90			return PTR_ERR(s->regmap);
    91		}
    92	
    93		ret = of_property_read_u32(mux_node, "reg", &s->mux_reg);
    94		if (ret) {
    95			dev_err(dev, "missing or invalid reg property\n");
    96			return -ENODEV;
    97		}
    98	
    99		/* Test Register read write */
   100		ret = regmap_read(s->regmap, s->mux_reg, &val);
   101		if (ret) {
   102			dev_err(dev, "error while reading reg\n");
   103			return ret;
   104		}
   105	
   106		ret = regmap_write(s->regmap, s->mux_reg, val);
   107		if (ret) {
   108			dev_err(dev, "error while writing reg\n");
   109			return ret;
   110		}
   111	
   112		ret = of_property_read_u32(mux_node, "mux-mask", &s->mask);
   113		if (ret) {
   114			dev_err(dev, "missing or invalid mux-mask property\n");
   115			return -ENODEV;
   116		}
   117	
   118		/* Verify that the 'reg' property of each child MDIO bus does not
   119		 * set any bits outside of the 'mask'.
   120		 */
   121		for_each_available_child_of_node(mux_node, child) {
   122			ret = of_property_read_u32(child, "reg", &val);
   123			if (ret) {
   124				dev_err(dev, "%pOF is missing a 'reg' property\n",
   125					child);
   126				of_node_put(child);
   127				return -ENODEV;
   128			}
   129			if (val & ~s->mask) {
   130				dev_err(dev,
   131					"%pOF has a 'reg' value with unmasked bits\n",
   132					child);
   133				of_node_put(child);
   134				return -ENODEV;
   135			}
   136		}
   137	
   138		ret = mdio_mux_init(dev, mux_node, mdio_mux_regmap_switch_fn,
   139				    &s->mux_handle, s, NULL);
   140		if (ret) {
   141			if (ret != -EPROBE_DEFER)
   142				dev_err(dev, "failed to register mdio-mux bus %pOF\n",
   143					mux_node);
   144			return ret;
   145		}
   146	
   147		*data = s;
   148	
   149		return 0;
   150	}
   151	EXPORT_SYMBOL_GPL(mdio_mux_regmap_init);
   152	
   153	/**
   154	 * mdio_mux_regmap_uninit - relinquish the control of MDIO bus muxing using
   155	 *			    regmap constructs.
   156	 * @data: address of data allocated by mdio_mux_regmap_init
   157	 */
 > 158	int mdio_mux_regmap_uninit(void *data)
   159	{
   160		struct mdio_mux_regmap_state *s = data;
   161	
   162		mdio_mux_uninit(s->mux_handle);
   163	
   164		return 0;
   165	}
   166	EXPORT_SYMBOL_GPL(mdio_mux_regmap_uninit);
   167	

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 50803 bytes --]

^ permalink raw reply

* Re: [PATCH iproute2-next v3] devlink: add info subcommand
From: Jiri Pirko @ 2019-02-04 14:49 UTC (permalink / raw)
  To: Jakub Kicinski; +Cc: dsahern, stephen, netdev, oss-drivers
In-Reply-To: <20190204144343.5639-1-jakub.kicinski@netronome.com>

Mon, Feb 04, 2019 at 03:43:43PM CET, jakub.kicinski@netronome.com wrote:
>Add support for reading the device serial number, driver name
>and various versions.  Example:
>
>$ devlink dev info pci/0000:82:00.0
>pci/0000:82:00.0:
>  driver nfp
>  serial_number 16240145
>  versions:
>      fixed:
>        board.id AMDA0081-0001
>        board.rev 15
>        board.vendor SMA
>        board.model hydrogen
>      running:
>        fw.bundle_id -

Wait, what are these "-" ?
That looks a bit scarry.


>        fw.mgmt 010181.010181.0101d4
>        fw.cpld 0x1030000
>        fw.app abm-d372b6
>        fw.undi 0.0.0
>        fw.ncsi -
>        chip.init AMDA-0081-0001  20160318164536
>      stored:
>        fw.bundle_id -
>        fw.mgmt 010181.010181.0101d4
>        fw.cpld 0xfeedbeef
>        fw.app -
>        fw.undi 0.0.0
>        fw.ncsi -
>        chip.init AMDA-0081-0001  20160318164536
>
>$ devlink -jp dev info pci/0000:82:00.0
>{
>    "info": {
>        "pci/0000:82:00.0": {
>
>            "driver": "nfp",
>            "serial_number": "16240145",
>            "versions": {
>                "fixed": {
>                    "board.id": "AMDA0081-0001",
>                    "board.rev": "15",
>                    "board.vendor": "SMA",
>                    "board.model": "hydrogen"
>                },
>                "running": {
>                    "fw.bundle_id": "-",
>                    "fw.mgmt": "010181.010181.0101d4",
>                    "fw.cpld": "0x1030000",
>                    "fw.app": "abm-d372b6",
>                    "fw.undi": "0.0.0",
>                    "fw.ncsi": "-",
>                    "chip.init": "AMDA-0081-0001  20160318164536"
>                },
>                "stored": {
>                    "fw.bundle_id": "-",
>                    "fw.mgmt": "010181.010181.0101d4",
>                    "fw.cpld": "0xfeedbeef",
>                    "fw.app": "-",
>                    "fw.undi": "0.0.0",
>                    "fw.ncsi": "-",
>                    "chip.init": "AMDA-0081-0001  20160318164536"
>                }
>            }
>        }
>    }
>}
>
>v3:
> - show up-to-date output in the commit message.
>v2 (Jiri):
> - remove filtering;
> - add example in the commit message.
>RFCv2:
> - make info subcommand of dev.
>
>Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>

[...]

^ permalink raw reply

* Re: [net-next RFC/PATCH] net: nixge: Make mdio child node optional
From: Andrew Lunn @ 2019-02-04 14:58 UTC (permalink / raw)
  To: Moritz Fischer
  Cc: linux-kernel, netdev, devicetree, davem, alex.williams,
	Rob Herring
In-Reply-To: <20190202025048.14772-1-mdf@kernel.org>

On Fri, Feb 01, 2019 at 06:50:48PM -0800, Moritz Fischer wrote:
> Make MDIO child optional and only instantiate the
> MDIO bus if the child is actually present.
> 
> There are currently no (in-tree) users of this
> binding; all (out-of-tree) users use overlays that
> get shipped together with the FPGA images that contain
> the IP.
> 
> This will significantly increase maintainabilty
> of future revisions of this IP.
> 
> Signed-off-by: Moritz Fischer <mdf@kernel.org>
> Cc: Andrew Lunn <andrew@lunn.ch>
> Cc: Rob Herring <robh+dt@kernel.org>

Reviewed-by: Andrew Lunn <andrew@lunn.ch>

    Andrew

^ permalink raw reply

* Re: [PATCH iproute2-next v2] devlink: report cell size
From: Jiri Pirko @ 2019-02-04 14:51 UTC (permalink / raw)
  To: Jakub Kicinski; +Cc: idosch, dsahern, stephen, oss-drivers, netdev
In-Reply-To: <20190204144442.5704-1-jakub.kicinski@netronome.com>

Mon, Feb 04, 2019 at 03:44:42PM CET, jakub.kicinski@netronome.com wrote:
>Print the value of DEVLINK_ATTR_SB_POOL_CELL_SIZE, if reported.
>
>Example:
>pci/0000:82:00.0:
>  sb 1 pool 0 type egress size 40945664 thtype static cell_size 2048
>  sb 2 pool 0 type egress size 258867200 thtype static cell_size 10240
>...
>
>v2: - fix spelling.
>
>Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
>Reviewed-by: Quentin Monnet <quentin.monnet@netronome.com>
>---
> devlink/devlink.c     |  3 +++
> man/man8/devlink-sb.8 | 10 ++++++++++
> 2 files changed, 13 insertions(+)
>
>diff --git a/devlink/devlink.c b/devlink/devlink.c
>index fc4b18d1b613..40f6105af109 100644
>--- a/devlink/devlink.c
>+++ b/devlink/devlink.c
>@@ -2891,6 +2891,9 @@ static void pr_out_sb_pool(struct dl *dl, struct nlattr **tb)
> 		    mnl_attr_get_u32(tb[DEVLINK_ATTR_SB_POOL_SIZE]));
> 	pr_out_str(dl, "thtype",
> 		   threshold_type_name(mnl_attr_get_u8(tb[DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE])));
>+	if (tb[DEVLINK_ATTR_SB_POOL_CELL_SIZE])
>+		pr_out_uint(dl, "cell_size",
>+			    mnl_attr_get_u32(tb[DEVLINK_ATTR_SB_POOL_CELL_SIZE]));
> 	pr_out_handle_end(dl);
> }
> 
>diff --git a/man/man8/devlink-sb.8 b/man/man8/devlink-sb.8
>index 1882833a3fa7..0deacd9ccd23 100644
>--- a/man/man8/devlink-sb.8
>+++ b/man/man8/devlink-sb.8
>@@ -128,6 +128,16 @@ Behaviour of this argument it the same for every command.
> - specifies the devlink device to show pools.
> If this argument is omitted all pools of all devices are listed.
> 
>+Display available pools listing their
>+.B type, size, thtype
>+and
>+.B cell_size. cell_size
>+is the allocation granularity of memory within the shared buffer.  Drivers

Double space. Other than this nit, looks fine to me.


>+may round up, round down or reject
>+.B size
>+passed to the set command if it is not multiple of
>+.B cell_size.
>+
> .SS devlink sb pool set - set attributes of pool
> 
> .PP
>-- 
>2.19.2
>

^ permalink raw reply

* Re: [PATCH iproute2-next v3] devlink: add info subcommand
From: Jakub Kicinski @ 2019-02-04 15:13 UTC (permalink / raw)
  To: Jiri Pirko; +Cc: dsahern, stephen, netdev, oss-drivers
In-Reply-To: <20190204144948.GA2118@nanopsycho>

On Mon, 4 Feb 2019 15:49:48 +0100, Jiri Pirko wrote:
> >      running:
> >        fw.bundle_id -  
> 
> Wait, what are these "-" ?
> That looks a bit scarry.

It's a test build of the FW, I wanted to show you the real output with
all the versions reported...  I can use a FW where those are just not
reported.  Do you want me to respin v4 for this?

^ permalink raw reply

* Re: [PATCH 7/7] sh_eth: offload RX checksum on SH7763
From: Sergei Shtylyov @ 2019-02-04 15:17 UTC (permalink / raw)
  To: Rob Landley, netdev, David S. Miller; +Cc: linux-renesas-soc, linux-sh
In-Reply-To: <2859e252-a900-fdc7-bfd8-d1b7663174f2@landley.net>

Hello!

On 02/04/2019 02:55 PM, Rob Landley wrote:

>> The SH7763 SoC manual describes the Ether MAC's RX checksum offload
>> the same way as it's implemented in the EtherAVB MACs...
>>
>> Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
> 
> I think this is the chip in the JCI N40 on my desk, how would I test this and
> tell it was working? (Is there an existing test program or...?)

   There are programs, yes. I used (rather old) netperf-2.2pl4 (I can send it to
you) running under perf (provided by the Poky rootfs). The details running netperf
on target are in the patch description #2; on host you just run netserver from that
same testsuite. The current netperf is maintained by HP on github but I was unable
to figure out how to build it quickly enough... :-)

> Also, can this be tested under QEMU's r2 board emulation?

   I have no idea, sorry.

> Rob

MBR, Sergei


^ permalink raw reply

* [PATCH iproute2-next v4] devlink: add info subcommand
From: Jakub Kicinski @ 2019-02-04 15:28 UTC (permalink / raw)
  To: jiri, dsahern; +Cc: stephen, netdev, oss-drivers, Jakub Kicinski

Add support for reading the device serial number, driver name
and various versions.  Example:

$ devlink dev info pci/0000:82:00.0
pci/0000:82:00.0:
  driver nfp
  serial_number 16240145
  versions:
      fixed:
        board.id AMDA0081-0001
        board.rev 15
        board.vendor SMA
        board.model hydrogen
      running:
        fw.mgmt 010181.010181.0101d4
        fw.cpld 0x1030000
        fw.app abm-d372b6
        fw.undi 0.0.2
        chip.init AMDA-0081-0001  20160318164536
      stored:
        fw.mgmt 010181.010181.0101d4
        fw.app abm-d372b6
        fw.undi 0.0.2
        chip.init AMDA-0081-0001  20160318164536

$ devlink -jp dev info pci/0000:82:00.0
{
    "info": {
        "pci/0000:82:00.0": {

            "driver": "nfp",
            "serial_number": "16240145",
            "versions": {
                "fixed": {
                    "board.id": "AMDA0081-0001",
                    "board.rev": "15",
                    "board.vendor": "SMA",
                    "board.model": "hydrogen"
                },
                "running": {
                    "fw.mgmt": "010181.010181.0101d4",
                    "fw.cpld": "0x1030000",
                    "fw.app": "abm-d372b6",
                    "fw.undi": "0.0.2",
                    "chip.init": "AMDA-0081-0001  20160318164536"
                },
                "stored": {
                    "fw.mgmt": "010181.010181.0101d4",
                    "fw.app": "abm-d372b6",
                    "fw.undi": "0.0.2",
                    "chip.init": "AMDA-0081-0001  20160318164536"
                }
            }
        }
    }
}

v4:
 - more commit message improvements.
v3:
 - show up-to-date output in the commit message.
v2 (Jiri):
 - remove filtering;
 - add example in the commit message.
RFCv2:
 - make info subcommand of dev.

Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
---
 devlink/devlink.c      | 169 +++++++++++++++++++++++++++++++++++++++++
 man/man8/devlink-dev.8 |  26 +++++++
 2 files changed, 195 insertions(+)

diff --git a/devlink/devlink.c b/devlink/devlink.c
index 3651e90c1159..fc4b18d1b613 100644
--- a/devlink/devlink.c
+++ b/devlink/devlink.c
@@ -383,6 +383,13 @@ static const enum mnl_attr_data_type devlink_policy[DEVLINK_ATTR_MAX + 1] = {
 	[DEVLINK_ATTR_REGION_CHUNK_DATA] = MNL_TYPE_BINARY,
 	[DEVLINK_ATTR_REGION_CHUNK_ADDR] = MNL_TYPE_U64,
 	[DEVLINK_ATTR_REGION_CHUNK_LEN] = MNL_TYPE_U64,
+	[DEVLINK_ATTR_INFO_DRIVER_NAME] = MNL_TYPE_STRING,
+	[DEVLINK_ATTR_INFO_SERIAL_NUMBER] = MNL_TYPE_STRING,
+	[DEVLINK_ATTR_INFO_VERSION_FIXED] = MNL_TYPE_NESTED,
+	[DEVLINK_ATTR_INFO_VERSION_RUNNING] = MNL_TYPE_NESTED,
+	[DEVLINK_ATTR_INFO_VERSION_STORED] = MNL_TYPE_NESTED,
+	[DEVLINK_ATTR_INFO_VERSION_NAME] = MNL_TYPE_STRING,
+	[DEVLINK_ATTR_INFO_VERSION_VALUE] = MNL_TYPE_STRING,
 };
 
 static int attr_cb(const struct nlattr *attr, void *data)
@@ -1443,6 +1450,7 @@ static void cmd_dev_help(void)
 	pr_err("       devlink dev param set DEV name PARAMETER value VALUE cmode { permanent | driverinit | runtime }\n");
 	pr_err("       devlink dev param show [DEV name PARAMETER]\n");
 	pr_err("       devlink dev reload DEV\n");
+	pr_err("       devlink dev info [ DEV ]\n");
 }
 
 static bool cmp_arr_last_handle(struct dl *dl, const char *bus_name,
@@ -1775,6 +1783,30 @@ static void pr_out_array_end(struct dl *dl)
 	}
 }
 
+static void pr_out_object_start(struct dl *dl, const char *name)
+{
+	if (dl->json_output) {
+		jsonw_name(dl->jw, name);
+		jsonw_start_object(dl->jw);
+	} else {
+		__pr_out_indent_inc();
+		__pr_out_newline();
+		pr_out("%s:", name);
+		__pr_out_indent_inc();
+		__pr_out_newline();
+	}
+}
+
+static void pr_out_object_end(struct dl *dl)
+{
+	if (dl->json_output) {
+		jsonw_end_object(dl->jw);
+	} else {
+		__pr_out_indent_dec();
+		__pr_out_indent_dec();
+	}
+}
+
 static void pr_out_entry_start(struct dl *dl)
 {
 	if (dl->json_output)
@@ -2415,6 +2447,140 @@ static int cmd_dev_reload(struct dl *dl)
 	return _mnlg_socket_sndrcv(dl->nlg, nlh, NULL, NULL);
 }
 
+static void pr_out_versions_single(struct dl *dl, const struct nlmsghdr *nlh,
+				   const char *name, int type)
+{
+	struct nlattr *version;
+
+	mnl_attr_for_each(version, nlh, sizeof(struct genlmsghdr)) {
+		struct nlattr *tb[DEVLINK_ATTR_MAX + 1] = {};
+		const char *ver_value;
+		const char *ver_name;
+		int err;
+
+		if (mnl_attr_get_type(version) != type)
+			continue;
+
+		err = mnl_attr_parse_nested(version, attr_cb, tb);
+		if (err != MNL_CB_OK)
+			continue;
+
+		if (!tb[DEVLINK_ATTR_INFO_VERSION_NAME] ||
+		    !tb[DEVLINK_ATTR_INFO_VERSION_VALUE])
+			continue;
+
+		if (name) {
+			pr_out_object_start(dl, name);
+			name = NULL;
+		}
+
+		ver_name = mnl_attr_get_str(tb[DEVLINK_ATTR_INFO_VERSION_NAME]);
+		ver_value = mnl_attr_get_str(tb[DEVLINK_ATTR_INFO_VERSION_VALUE]);
+
+		pr_out_str(dl, ver_name, ver_value);
+		if (!dl->json_output)
+			__pr_out_newline();
+	}
+
+	if (!name)
+		pr_out_object_end(dl);
+}
+
+static void pr_out_info(struct dl *dl, const struct nlmsghdr *nlh,
+			struct nlattr **tb, bool has_versions)
+{
+	__pr_out_handle_start(dl, tb, true, false);
+
+	__pr_out_indent_inc();
+	if (tb[DEVLINK_ATTR_INFO_DRIVER_NAME]) {
+		struct nlattr *nla_drv = tb[DEVLINK_ATTR_INFO_DRIVER_NAME];
+
+		__pr_out_newline();
+		pr_out_str(dl, "driver", mnl_attr_get_str(nla_drv));
+	}
+
+	if (tb[DEVLINK_ATTR_INFO_SERIAL_NUMBER]) {
+		struct nlattr *nla_sn = tb[DEVLINK_ATTR_INFO_SERIAL_NUMBER];
+
+		__pr_out_newline();
+		pr_out_str(dl, "serial_number", mnl_attr_get_str(nla_sn));
+	}
+	__pr_out_indent_dec();
+
+	if (has_versions) {
+		pr_out_object_start(dl, "versions");
+
+		pr_out_versions_single(dl, nlh, "fixed",
+				       DEVLINK_ATTR_INFO_VERSION_FIXED);
+		pr_out_versions_single(dl, nlh, "running",
+				       DEVLINK_ATTR_INFO_VERSION_RUNNING);
+		pr_out_versions_single(dl, nlh, "stored",
+				       DEVLINK_ATTR_INFO_VERSION_STORED);
+
+		pr_out_object_end(dl);
+	}
+
+	pr_out_handle_end(dl);
+}
+
+static int cmd_versions_show_cb(const struct nlmsghdr *nlh, void *data)
+{
+	struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh);
+	struct nlattr *tb[DEVLINK_ATTR_MAX + 1] = {};
+	bool has_versions, has_info;
+	struct dl *dl = data;
+
+	mnl_attr_parse(nlh, sizeof(*genl), attr_cb, tb);
+
+	if (!tb[DEVLINK_ATTR_BUS_NAME] || !tb[DEVLINK_ATTR_DEV_NAME])
+		return MNL_CB_ERROR;
+
+	has_versions = tb[DEVLINK_ATTR_INFO_VERSION_FIXED] ||
+		tb[DEVLINK_ATTR_INFO_VERSION_RUNNING] ||
+		tb[DEVLINK_ATTR_INFO_VERSION_STORED];
+	has_info = tb[DEVLINK_ATTR_INFO_DRIVER_NAME] ||
+		tb[DEVLINK_ATTR_INFO_SERIAL_NUMBER] ||
+		has_versions;
+
+	if (has_info)
+		pr_out_info(dl, nlh, tb, has_versions);
+
+	return MNL_CB_OK;
+}
+
+static void cmd_dev_info_help(void)
+{
+	pr_err("Usage: devlink dev info [ DEV ]\n");
+}
+
+static int cmd_dev_info(struct dl *dl)
+{
+	struct nlmsghdr *nlh;
+	uint16_t flags = NLM_F_REQUEST | NLM_F_ACK;
+	int err;
+
+	if (dl_argv_match(dl, "help")) {
+		cmd_dev_info_help();
+		return 0;
+	}
+
+	if (dl_argc(dl) == 0)
+		flags |= NLM_F_DUMP;
+
+	nlh = mnlg_msg_prepare(dl->nlg, DEVLINK_CMD_INFO_GET, flags);
+
+	if (dl_argc(dl) > 0) {
+		err = dl_argv_parse_put(nlh, dl, DL_OPT_HANDLE, 0);
+		if (err)
+			return err;
+	}
+
+	pr_out_section_start(dl, "info");
+	err = _mnlg_socket_sndrcv(dl->nlg, nlh, cmd_versions_show_cb, dl);
+	pr_out_section_end(dl);
+	return err;
+}
+
 static int cmd_dev(struct dl *dl)
 {
 	if (dl_argv_match(dl, "help")) {
@@ -2433,6 +2599,9 @@ static int cmd_dev(struct dl *dl)
 	} else if (dl_argv_match(dl, "param")) {
 		dl_arg_inc(dl);
 		return cmd_dev_param(dl);
+	} else if (dl_argv_match(dl, "info")) {
+		dl_arg_inc(dl);
+		return cmd_dev_info(dl);
 	}
 	pr_err("Command \"%s\" not found\n", dl_argv(dl));
 	return -ENOENT;
diff --git a/man/man8/devlink-dev.8 b/man/man8/devlink-dev.8
index d985da172aa0..47838371fecd 100644
--- a/man/man8/devlink-dev.8
+++ b/man/man8/devlink-dev.8
@@ -63,6 +63,12 @@ devlink-dev \- devlink device configuration
 .BR "devlink dev reload"
 .IR DEV
 
+.ti -8
+.BR "devlink dev info"
+.RI "[ "
+.IR DEV
+.RI "]"
+
 .SH "DESCRIPTION"
 .SS devlink dev show - display devlink device attributes
 
@@ -151,6 +157,26 @@ If this argument is omitted all parameters supported by devlink devices are list
 .I "DEV"
 - Specifies the devlink device to reload.
 
+.SS devlink dev info - display device information.
+Display device information provided by the driver. This command can be used
+to query versions of the hardware components or device components which
+can't be updated (
+.I fixed
+) as well as device firmware which can be updated. For firmware components
+.I running
+displays the versions of firmware currently loaded into the device, while
+.I stored
+reports the versions in device's flash.
+.I Running
+and
+.I stored
+versions may differ after flash has been updated, but before reboot.
+
+.PP
+.I "DEV"
+- specifies the devlink device to show.
+If this argument is omitted all devices are listed.
+
 .SH "EXAMPLES"
 .PP
 devlink dev show
-- 
2.19.2


^ permalink raw reply related

* [PATCH iproute2-next v3] devlink: report cell size
From: Jakub Kicinski @ 2019-02-04 15:28 UTC (permalink / raw)
  To: idosch, jiri, dsahern; +Cc: stephen, oss-drivers, netdev, Jakub Kicinski

Print the value of DEVLINK_ATTR_SB_POOL_CELL_SIZE, if reported.

Example:
pci/0000:82:00.0:
  sb 1 pool 0 type egress size 40945664 thtype static cell_size 2048
  sb 2 pool 0 type egress size 258867200 thtype static cell_size 10240
...

v3: - don't double space.
v2: - fix spelling.

Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Reviewed-by: Quentin Monnet <quentin.monnet@netronome.com>
---
 devlink/devlink.c     |  3 +++
 man/man8/devlink-sb.8 | 10 ++++++++++
 2 files changed, 13 insertions(+)

diff --git a/devlink/devlink.c b/devlink/devlink.c
index fc4b18d1b613..40f6105af109 100644
--- a/devlink/devlink.c
+++ b/devlink/devlink.c
@@ -2891,6 +2891,9 @@ static void pr_out_sb_pool(struct dl *dl, struct nlattr **tb)
 		    mnl_attr_get_u32(tb[DEVLINK_ATTR_SB_POOL_SIZE]));
 	pr_out_str(dl, "thtype",
 		   threshold_type_name(mnl_attr_get_u8(tb[DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE])));
+	if (tb[DEVLINK_ATTR_SB_POOL_CELL_SIZE])
+		pr_out_uint(dl, "cell_size",
+			    mnl_attr_get_u32(tb[DEVLINK_ATTR_SB_POOL_CELL_SIZE]));
 	pr_out_handle_end(dl);
 }
 
diff --git a/man/man8/devlink-sb.8 b/man/man8/devlink-sb.8
index 1882833a3fa7..91b681897d01 100644
--- a/man/man8/devlink-sb.8
+++ b/man/man8/devlink-sb.8
@@ -128,6 +128,16 @@ Behaviour of this argument it the same for every command.
 - specifies the devlink device to show pools.
 If this argument is omitted all pools of all devices are listed.
 
+Display available pools listing their
+.B type, size, thtype
+and
+.B cell_size. cell_size
+is the allocation granularity of memory within the shared buffer. Drivers
+may round up, round down or reject
+.B size
+passed to the set command if it is not multiple of
+.B cell_size.
+
 .SS devlink sb pool set - set attributes of pool
 
 .PP
-- 
2.19.2


^ permalink raw reply related

* Re: [PATCH net-next v3 01/16] net: sched: protect block state with mutex
From: Jiri Pirko @ 2019-02-04 15:23 UTC (permalink / raw)
  To: Vlad Buslov; +Cc: netdev, jhs, xiyou.wangcong, davem, ast, daniel
In-Reply-To: <20190204123301.4223-2-vladbu@mellanox.com>

Mon, Feb 04, 2019 at 01:32:46PM CET, vladbu@mellanox.com wrote:
>Currently, tcf_block doesn't use any synchronization mechanisms to protect
>critical sections that manage lifetime of its chains. block->chain_list and
>multiple variables in tcf_chain that control its lifetime assume external
>synchronization provided by global rtnl lock. Converting chain reference
>counting to atomic reference counters is not possible because cls API uses
>multiple counters and flags to control chain lifetime, so all of them must
>be synchronized in chain get/put code.
>
>Use single per-block lock to protect block data and manage lifetime of all
>chains on the block. Always take block->lock when accessing chain_list.
>Chain get and put modify chain lifetime-management data and parent block's
>chain_list, so take the lock in these functions. Verify block->lock state
>with assertions in functions that expect to be called with the lock taken
>and are called from multiple places. Take block->lock when accessing
>filter_chain_list.
>
>In order to allow parallel update of rules on single block, move all calls
>to classifiers outside of critical sections protected by new block->lock.
>Rearrange chain get and put functions code to only access protected chain
>data while holding block lock:
>- Check if chain was explicitly created inside put function while holding
>  block lock. Add additional argument to __tcf_chain_put() to only put
>  explicitly created chain.
>- Rearrange code to only access chain reference counter and chain action
>  reference counter while holding block lock.
>- Extract code that requires block->lock from tcf_chain_destroy() into
>  standalone tcf_chain_destroy() function that is called by
>  __tcf_chain_put() in same critical section that changes chain reference
>  counters.
>
>Signed-off-by: Vlad Buslov <vladbu@mellanox.com>
>---
>
>Changes from V2 to V3:
>  - Change block->lock type to mutex.
>  - Implement tcf_block_destroy() helper function that destroys
>    block->lock mutex before deallocating the block.
>  - Revert GFP_KERNEL->GFP_ATOMIC memory allocation flags of tcf_chain
>    which is no longer needed after block->lock type change.
>
> include/net/sch_generic.h |   5 +++
> net/sched/cls_api.c       | 102 ++++++++++++++++++++++++++++++++++++++--------
> 2 files changed, 89 insertions(+), 18 deletions(-)
>
>diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
>index 7a4957599874..31b8ea66a47d 100644
>--- a/include/net/sch_generic.h
>+++ b/include/net/sch_generic.h
>@@ -12,6 +12,7 @@
> #include <linux/list.h>
> #include <linux/refcount.h>
> #include <linux/workqueue.h>
>+#include <linux/mutex.h>
> #include <net/gen_stats.h>
> #include <net/rtnetlink.h>
> 
>@@ -352,6 +353,10 @@ struct tcf_chain {
> };
> 
> struct tcf_block {
>+	/* Lock protects tcf_block and lifetime-management data of chains
>+	 * attached to the block (refcnt, action_refcnt, explicitly_created).
>+	 */
>+	struct mutex lock;
> 	struct list_head chain_list;
> 	u32 index; /* block index for shared blocks */
> 	refcount_t refcnt;
>diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
>index e2b5cb2eb34e..cc416b6a3aa2 100644
>--- a/net/sched/cls_api.c
>+++ b/net/sched/cls_api.c
>@@ -193,6 +193,9 @@ static void tcf_proto_destroy(struct tcf_proto *tp,
> 	kfree_rcu(tp, rcu);
> }
> 
>+#define ASSERT_BLOCK_LOCKED(block)					\
>+	lockdep_assert_held(&(block)->lock)
>+
> struct tcf_filter_chain_list_item {
> 	struct list_head list;
> 	tcf_chain_head_change_t *chain_head_change;
>@@ -204,6 +207,8 @@ static struct tcf_chain *tcf_chain_create(struct tcf_block *block,
> {
> 	struct tcf_chain *chain;
> 
>+	ASSERT_BLOCK_LOCKED(block);
>+
> 	chain = kzalloc(sizeof(*chain), GFP_KERNEL);
> 	if (!chain)
> 		return NULL;
>@@ -235,25 +240,51 @@ static void tcf_chain0_head_change(struct tcf_chain *chain,
> 		tcf_chain_head_change_item(item, tp_head);
> }
> 
>-static void tcf_chain_destroy(struct tcf_chain *chain)
>+/* Returns true if block can be safely freed. */
>+
>+static bool tcf_chain_detach(struct tcf_chain *chain)
> {
> 	struct tcf_block *block = chain->block;
> 
>+	ASSERT_BLOCK_LOCKED(block);
>+
> 	list_del(&chain->list);
> 	if (!chain->index)
> 		block->chain0.chain = NULL;
>+
>+	if (list_empty(&block->chain_list) &&
>+	    refcount_read(&block->refcnt) == 0)
>+		return true;
>+
>+	return false;
>+}
>+
>+static void tcf_block_destroy(struct tcf_block *block)
>+{
>+	mutex_destroy(&block->lock);
>+	kfree_rcu(block, rcu);
>+}
>+
>+static void tcf_chain_destroy(struct tcf_chain *chain, bool free_block)
>+{
>+	struct tcf_block *block = chain->block;
>+
> 	kfree(chain);
>-	if (list_empty(&block->chain_list) && !refcount_read(&block->refcnt))
>-		kfree_rcu(block, rcu);
>+	if (free_block)
>+		tcf_block_destroy(block);
> }
> 
> static void tcf_chain_hold(struct tcf_chain *chain)
> {
>+	ASSERT_BLOCK_LOCKED(chain->block);
>+
> 	++chain->refcnt;
> }
> 
> static bool tcf_chain_held_by_acts_only(struct tcf_chain *chain)
> {
>+	ASSERT_BLOCK_LOCKED(chain->block);
>+
> 	/* In case all the references are action references, this
> 	 * chain should not be shown to the user.
> 	 */
>@@ -265,6 +296,8 @@ static struct tcf_chain *tcf_chain_lookup(struct tcf_block *block,
> {
> 	struct tcf_chain *chain;
> 
>+	ASSERT_BLOCK_LOCKED(block);
>+
> 	list_for_each_entry(chain, &block->chain_list, list) {
> 		if (chain->index == chain_index)
> 			return chain;
>@@ -279,31 +312,40 @@ static struct tcf_chain *__tcf_chain_get(struct tcf_block *block,
> 					 u32 chain_index, bool create,
> 					 bool by_act)
> {
>-	struct tcf_chain *chain = tcf_chain_lookup(block, chain_index);
>+	struct tcf_chain *chain = NULL;
>+	bool is_first_reference;
> 
>+	mutex_lock(&block->lock);
>+	chain = tcf_chain_lookup(block, chain_index);
> 	if (chain) {
> 		tcf_chain_hold(chain);
> 	} else {
> 		if (!create)
>-			return NULL;
>+			goto errout;
> 		chain = tcf_chain_create(block, chain_index);
> 		if (!chain)
>-			return NULL;
>+			goto errout;
> 	}
> 
> 	if (by_act)
> 		++chain->action_refcnt;
>+	is_first_reference = chain->refcnt - chain->action_refcnt == 1;
>+	mutex_unlock(&block->lock);
> 
> 	/* Send notification only in case we got the first
> 	 * non-action reference. Until then, the chain acts only as
> 	 * a placeholder for actions pointing to it and user ought
> 	 * not know about them.
> 	 */
>-	if (chain->refcnt - chain->action_refcnt == 1 && !by_act)
>+	if (is_first_reference && !by_act)
> 		tc_chain_notify(chain, NULL, 0, NLM_F_CREATE | NLM_F_EXCL,
> 				RTM_NEWCHAIN, false);
> 
> 	return chain;
>+
>+errout:
>+	mutex_unlock(&block->lock);
>+	return chain;
> }
> 
> static struct tcf_chain *tcf_chain_get(struct tcf_block *block, u32 chain_index,
>@@ -320,37 +362,59 @@ EXPORT_SYMBOL(tcf_chain_get_by_act);
> 
> static void tc_chain_tmplt_del(struct tcf_chain *chain);
> 
>-static void __tcf_chain_put(struct tcf_chain *chain, bool by_act)
>+static void __tcf_chain_put(struct tcf_chain *chain, bool by_act,
>+			    bool explicitly_created)
> {
>+	struct tcf_block *block = chain->block;
>+	bool is_last, free_block = false;
>+	unsigned int refcnt;
>+
>+	mutex_lock(&block->lock);
>+	if (explicitly_created) {
>+		if (!chain->explicitly_created) {
>+			mutex_unlock(&block->lock);
>+			return;
>+		}
>+		chain->explicitly_created = false;

Hmm, I think that you left "chain->explicitly_created = false" at the
original location (tc_ctl_chain()). I think it would be better to do
the chain->explicitly_created management move in a separate patch.


>+	}
>+
> 	if (by_act)
> 		chain->action_refcnt--;
>-	chain->refcnt--;
>+
>+	/* tc_chain_notify_delete can't be called while holding block lock.
>+	 * However, when block is unlocked chain can be changed concurrently, so
>+	 * save these to temporary variables.
>+	 */
>+	refcnt = --chain->refcnt;
>+	is_last = refcnt - chain->action_refcnt == 0;
>+	if (refcnt == 0)
>+		free_block = tcf_chain_detach(chain);
>+	mutex_unlock(&block->lock);
> 
> 	/* The last dropped non-action reference will trigger notification. */
>-	if (chain->refcnt - chain->action_refcnt == 0 && !by_act)
>+	if (is_last && !by_act)
> 		tc_chain_notify(chain, NULL, 0, 0, RTM_DELCHAIN, false);
> 
>-	if (chain->refcnt == 0) {
>+	if (refcnt == 0) {
> 		tc_chain_tmplt_del(chain);
>-		tcf_chain_destroy(chain);
>+		tcf_chain_destroy(chain, free_block);
> 	}
> }
> 
> static void tcf_chain_put(struct tcf_chain *chain)
> {
>-	__tcf_chain_put(chain, false);
>+	__tcf_chain_put(chain, false, false);
> }
> 
> void tcf_chain_put_by_act(struct tcf_chain *chain)
> {
>-	__tcf_chain_put(chain, true);
>+	__tcf_chain_put(chain, true, false);
> }
> EXPORT_SYMBOL(tcf_chain_put_by_act);
> 
> static void tcf_chain_put_explicitly_created(struct tcf_chain *chain)
> {
>-	if (chain->explicitly_created)
>-		tcf_chain_put(chain);
>+	__tcf_chain_put(chain, false, true);
> }
> 
> static void tcf_chain_flush(struct tcf_chain *chain)
>@@ -764,6 +828,7 @@ static struct tcf_block *tcf_block_create(struct net *net, struct Qdisc *q,
> 		NL_SET_ERR_MSG(extack, "Memory allocation for block failed");
> 		return ERR_PTR(-ENOMEM);
> 	}
>+	mutex_init(&block->lock);
> 	INIT_LIST_HEAD(&block->chain_list);
> 	INIT_LIST_HEAD(&block->cb_list);
> 	INIT_LIST_HEAD(&block->owner_list);
>@@ -827,7 +892,7 @@ static void tcf_block_put_all_chains(struct tcf_block *block)
> static void __tcf_block_put(struct tcf_block *block, struct Qdisc *q,
> 			    struct tcf_block_ext_info *ei)
> {
>-	if (refcount_dec_and_test(&block->refcnt)) {
>+	if (refcount_dec_and_mutex_lock(&block->refcnt, &block->lock)) {
> 		/* Flushing/putting all chains will cause the block to be
> 		 * deallocated when last chain is freed. However, if chain_list
> 		 * is empty, block has to be manually deallocated. After block
>@@ -836,6 +901,7 @@ static void __tcf_block_put(struct tcf_block *block, struct Qdisc *q,
> 		 */
> 		bool free_block = list_empty(&block->chain_list);
> 
>+		mutex_unlock(&block->lock);
> 		if (tcf_block_shared(block))
> 			tcf_block_remove(block, block->net);
> 		if (!free_block)
>@@ -845,7 +911,7 @@ static void __tcf_block_put(struct tcf_block *block, struct Qdisc *q,
> 			tcf_block_offload_unbind(block, q, ei);
> 
> 		if (free_block)
>-			kfree_rcu(block, rcu);
>+			tcf_block_destroy(block);
> 		else
> 			tcf_block_put_all_chains(block);
> 	} else if (q) {
>-- 
>2.13.6
>

^ permalink raw reply

* Re: [PATCH iproute2-next v3] devlink: add info subcommand
From: Jiri Pirko @ 2019-02-04 15:24 UTC (permalink / raw)
  To: Jakub Kicinski; +Cc: dsahern, stephen, netdev, oss-drivers
In-Reply-To: <20190204071302.7a844b0a@cakuba.hsd1.ca.comcast.net>

Mon, Feb 04, 2019 at 04:13:02PM CET, jakub.kicinski@netronome.com wrote:
>On Mon, 4 Feb 2019 15:49:48 +0100, Jiri Pirko wrote:
>> >      running:
>> >        fw.bundle_id -  
>> 
>> Wait, what are these "-" ?
>> That looks a bit scarry.
>
>It's a test build of the FW, I wanted to show you the real output with
>all the versions reported...  I can use a FW where those are just not
>reported.  Do you want me to respin v4 for this?

No problem :)

Acked-by: Jiri Pirko <jiri@mellanox.com>


Thanks!

^ permalink raw reply

* Re: [PATCH iproute2-next v4] devlink: add info subcommand
From: Jiri Pirko @ 2019-02-04 15:25 UTC (permalink / raw)
  To: Jakub Kicinski; +Cc: dsahern, stephen, netdev, oss-drivers
In-Reply-To: <20190204152820.6607-1-jakub.kicinski@netronome.com>

Mon, Feb 04, 2019 at 04:28:20PM CET, jakub.kicinski@netronome.com wrote:
>Add support for reading the device serial number, driver name
>and various versions.  Example:
>
>$ devlink dev info pci/0000:82:00.0
>pci/0000:82:00.0:
>  driver nfp
>  serial_number 16240145
>  versions:
>      fixed:
>        board.id AMDA0081-0001
>        board.rev 15
>        board.vendor SMA
>        board.model hydrogen
>      running:
>        fw.mgmt 010181.010181.0101d4
>        fw.cpld 0x1030000
>        fw.app abm-d372b6
>        fw.undi 0.0.2
>        chip.init AMDA-0081-0001  20160318164536
>      stored:
>        fw.mgmt 010181.010181.0101d4
>        fw.app abm-d372b6
>        fw.undi 0.0.2
>        chip.init AMDA-0081-0001  20160318164536
>
>$ devlink -jp dev info pci/0000:82:00.0
>{
>    "info": {
>        "pci/0000:82:00.0": {
>

I just noticed, this extra line should not be here.


>            "driver": "nfp",
>            "serial_number": "16240145",
>            "versions": {
>                "fixed": {
>                    "board.id": "AMDA0081-0001",
>                    "board.rev": "15",
>                    "board.vendor": "SMA",
>                    "board.model": "hydrogen"
>                },
>                "running": {
>                    "fw.mgmt": "010181.010181.0101d4",
>                    "fw.cpld": "0x1030000",
>                    "fw.app": "abm-d372b6",
>                    "fw.undi": "0.0.2",
>                    "chip.init": "AMDA-0081-0001  20160318164536"
>                },
>                "stored": {
>                    "fw.mgmt": "010181.010181.0101d4",
>                    "fw.app": "abm-d372b6",
>                    "fw.undi": "0.0.2",
>                    "chip.init": "AMDA-0081-0001  20160318164536"
>                }
>            }
>        }
>    }
>}

[...]

^ permalink raw reply

* Re: [PATCH iproute2-next v3] devlink: report cell size
From: Jiri Pirko @ 2019-02-04 15:25 UTC (permalink / raw)
  To: Jakub Kicinski; +Cc: idosch, dsahern, stephen, oss-drivers, netdev
In-Reply-To: <20190204152859.6667-1-jakub.kicinski@netronome.com>

Mon, Feb 04, 2019 at 04:28:59PM CET, jakub.kicinski@netronome.com wrote:
>Print the value of DEVLINK_ATTR_SB_POOL_CELL_SIZE, if reported.
>
>Example:
>pci/0000:82:00.0:
>  sb 1 pool 0 type egress size 40945664 thtype static cell_size 2048
>  sb 2 pool 0 type egress size 258867200 thtype static cell_size 10240
>...
>
>v3: - don't double space.
>v2: - fix spelling.
>
>Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
>Reviewed-by: Quentin Monnet <quentin.monnet@netronome.com>

Acked-by: Jiri Pirko <jiri@mellanox.com>

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox