* [PATCH net v5 4/7] cxgb4i: additional types of negative advice
From: Karen Xie @ 2014-12-10 1:43 UTC (permalink / raw)
To: linux-scsi, netdev
Cc: kxie, hariprasad, anish, hch, James.Bottomley, michaelc, davem
[PATCH net v5 4/7] cxgb4i: additional types of negative advice
From: Karen Xie <kxie@chelsio.com>
Treat both CPL_ERR_KEEPALV_NEG_ADVICE and CPL_ERR_PERSIST_NEG_ADVICE as negative advice.
Signed-off-by: Karen Xie <kxie@chelsio.com>
---
drivers/scsi/cxgbi/cxgb4i/cxgb4i.c | 12 +++++++++---
1 files changed, 9 insertions(+), 3 deletions(-)
diff --git a/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c b/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c
index 86b9bbc..c4a22e9 100644
--- a/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c
+++ b/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c
@@ -846,6 +846,13 @@ static void csk_act_open_retry_timer(unsigned long data)
}
+static inline bool is_neg_adv(unsigned int status)
+{
+ return status == CPL_ERR_RTX_NEG_ADVICE ||
+ status == CPL_ERR_KEEPALV_NEG_ADVICE ||
+ status == CPL_ERR_PERSIST_NEG_ADVICE;
+}
+
static void do_act_open_rpl(struct cxgbi_device *cdev, struct sk_buff *skb)
{
struct cxgbi_sock *csk;
@@ -867,7 +874,7 @@ static void do_act_open_rpl(struct cxgbi_device *cdev, struct sk_buff *skb)
"csk 0x%p,%u,0x%lx. ", (&csk->saddr), (&csk->daddr),
atid, tid, status, csk, csk->state, csk->flags);
- if (status == CPL_ERR_RTX_NEG_ADVICE)
+ if (is_neg_adv(status))
goto rel_skb;
module_put(THIS_MODULE);
@@ -973,8 +980,7 @@ static void do_abort_req_rss(struct cxgbi_device *cdev, struct sk_buff *skb)
(&csk->saddr), (&csk->daddr),
csk, csk->state, csk->flags, csk->tid, req->status);
- if (req->status == CPL_ERR_RTX_NEG_ADVICE ||
- req->status == CPL_ERR_PERSIST_NEG_ADVICE)
+ if (is_neg_adv(req->status))
goto rel_skb;
cxgbi_sock_get(csk);
^ permalink raw reply related
* RE: [PATCH net v3 1/6] cxgb4i: fix tx credit calculation
From: Karen Xie @ 2014-12-10 1:44 UTC (permalink / raw)
To: Sergei Shtylyov, linux-scsi@vger.kernel.org,
netdev@vger.kernel.org
Cc: Hariprasad S, Anish Bhatt, hch@infradead.org,
James.Bottomley@HansenPartnership.com, michaelc@cs.wisc.edu,
davem@davemloft.net
In-Reply-To: <54875385.80708@cogentembedded.com>
Please ignore v4, and use v5. Thanks!
-----Original Message-----
From: Karen Xie
Sent: Tuesday, December 09, 2014 5:39 PM
To: 'Sergei Shtylyov'; linux-scsi@vger.kernel.org; netdev@vger.kernel.org
Cc: Hariprasad S; Anish Bhatt; hch@infradead.org; James.Bottomley@HansenPartnership.com; michaelc@cs.wisc.edu; davem@davemloft.net
Subject: RE: [PATCH net v3 1/6] cxgb4i: fix tx credit calculation
Thanks for the review comment, have sent the v4 set to incorporate your comments.
-----Original Message-----
From: Sergei Shtylyov [mailto:sergei.shtylyov@cogentembedded.com]
Sent: Tuesday, December 09, 2014 11:55 AM
To: Karen Xie; linux-scsi@vger.kernel.org; netdev@vger.kernel.org
Cc: Hariprasad S; Anish Bhatt; hch@infradead.org; James.Bottomley@HansenPartnership.com; michaelc@cs.wisc.edu; davem@davemloft.net
Subject: Re: [PATCH net v3 1/6] cxgb4i: fix tx credit calculation
Hello.
On 12/09/2014 08:32 PM, Karen Xie wrote:
> [PATCH net v3 1/6] cxgb4i: fix tx credit calculation
> From: Karen Xie <kxie@chelsio.com>
> - Only data skbs need the wr header added while control skbs do not. Make sure they are treated differently.
> - Any credit related checking should be done before adding the wr header.
Looks like a spearate issue deserving its own patch?
> - Fixed compiler warning resulted from added cxgbi_skb_test_flag() call in is_ofld_imm().
Isn't it called cxgbi_skcb_test_flag()?
> Signed-off-by: Karen Xie <kxie@chelsio.com>
> ---
> drivers/scsi/cxgbi/cxgb4i/cxgb4i.c | 26 +++++++++++++++++---------
> drivers/scsi/cxgbi/libcxgbi.h | 4 ++--
> 2 files changed, 19 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c
> b/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c
> index 1508125..5c3f15d 100644
> --- a/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c
> +++ b/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c
[...]
> @@ -544,15 +548,17 @@ static inline void make_tx_data_wr(struct cxgbi_sock *csk, struct sk_buff *skb,
> unsigned int submode = cxgbi_skcb_ulp_mode(skb) & 3;
> unsigned int wr_ulp_mode = 0;
>
> - req = (struct fw_ofld_tx_data_wr *)__skb_push(skb, sizeof(*req));
> -
Perhaps it makes sense to store the result of is_ofld_imm() before
__skb_push() call
instead of duplicating the same call in 2 branches?
> if (is_ofld_imm(skb)) {
> + req = (struct fw_ofld_tx_data_wr *)__skb_push(skb,
> + sizeof(*req));
The continuation line should start right under 'skb' on the previous line.
> req->op_to_immdlen = htonl(FW_WR_OP(FW_OFLD_TX_DATA_WR) |
> FW_WR_COMPL(1) |
> FW_WR_IMMDLEN(dlen));
> req->flowid_len16 = htonl(FW_WR_FLOWID(csk->tid) |
> FW_WR_LEN16(credits));
> } else {
> + req = (struct fw_ofld_tx_data_wr *)__skb_push(skb,
> + sizeof(*req));
Likewise.
> req->op_to_immdlen =
> cpu_to_be32(FW_WR_OP(FW_OFLD_TX_DATA_WR) |
> FW_WR_COMPL(1) |
> @@ -597,12 +603,14 @@ static int push_tx_frames(struct cxgbi_sock
> *csk, int req_completion)
>
> skb_reset_transport_header(skb);
> if (is_ofld_imm(skb))
> - credits_needed = DIV_ROUND_UP(dlen +
> - sizeof(struct fw_ofld_tx_data_wr), 16);
> + credits_needed = DIV_ROUND_UP(dlen, 16);
> else
> - credits_needed = DIV_ROUND_UP(8*calc_tx_flits_ofld(skb)
> - + sizeof(struct fw_ofld_tx_data_wr),
> - 16);
> + credits_needed = DIV_ROUND_UP(8*calc_tx_flits_ofld(skb),
It would have been good if you added spaces around *, while at it, to keep it consistent with the general kernel coding style...
[...]
WBR, Sergei
^ permalink raw reply
* RE: [PATCH net v4 0/7] cxgb4/cxgbi: misc. fixes for cxgb4i
From: Karen Xie @ 2014-12-10 1:46 UTC (permalink / raw)
To: Karen Xie, linux-scsi@vger.kernel.org, netdev@vger.kernel.org
Cc: Hariprasad S, Anish Bhatt, hch@infradead.org,
James.Bottomley@HansenPartnership.com, michaelc@cs.wisc.edu,
davem@davemloft.net
In-Reply-To: <201412100132.sBA1WpsR024833@localhost6.localdomain6>
Please ignore v4. Sent v5 already.
-----Original Message-----
From: Karen Xie [mailto:kxie@chelsio.com]
Sent: Tuesday, December 09, 2014 5:33 PM
To: linux-scsi@vger.kernel.org; netdev@vger.kernel.org
Cc: Karen Xie; Hariprasad S; Anish Bhatt; hch@infradead.org; James.Bottomley@HansenPartnership.com; michaelc@cs.wisc.edu; davem@davemloft.net
Subject: [PATCH net v4 0/7] cxgb4/cxgbi: misc. fixes for cxgb4i
[PATCH net v4 0/7] cxgb4/cxgbi: misc. fixes for cxgb4i
This patch set fixes cxgb4i's tx credit calculation and adds handling of additional rx message and negative advice types. It also removes the duplicate code in cxgb4i to set the outgoing queues of a packet.
Karen Xie (7):
cxgb4i: fix tx immediate data credit check
cxgb4i: fix credit check for tx_data_wr
cxgb4/cxgb4i: set max. outgoing pdu length in the f/w
cxgb4i: add more types of negative advice
cxgb4i: handle non pdu-aligned rx data
cxgb4i: use cxgb4's set_wr_txq() for setting outgoing queues
libcxgbi: fix the debug print accessing skb after it is freed
Sending to net as the fixes are mostly in the network area and it touches cxgb4's header file (t4fw_api.h).
v2 corrects the "CHECK"s flagged by checkpatch.pl --strict.
v3 splits the 3rd patch from v2 to two seperate patches. Adds detailed commit messages and makes subject more concise. Patch 3/6 also changes the return value of is_neg_adv() from int to bool.
v4 splits the 1st patch from v3 to two seperate patches and reduces code duplication in make_tx_data_wr().
^ permalink raw reply
* [PATCH net v5 5/7] cxgb4i: handle non-pdu-aligned rx data
From: Karen Xie @ 2014-12-10 1:43 UTC (permalink / raw)
To: linux-scsi, netdev
Cc: kxie, hariprasad, anish, hch, James.Bottomley, michaelc, davem
[PATCH net v5 5/7] cxgb4i: handle non-pdu-aligned rx data
From: Karen Xie <kxie@chelsio.com>
Abort the connection upon receiving of cpl_rx_data, which means the pdu cannot be recovered from the tcp stream. This generally is due to pdu header corruption.
Signed-off-by: Karen Xie <kxie@chelsio.com>
---
drivers/scsi/cxgbi/cxgb4i/cxgb4i.c | 22 ++++++++++++++++++++++
1 files changed, 22 insertions(+), 0 deletions(-)
diff --git a/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c b/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c
index c4a22e9..bc66308 100644
--- a/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c
+++ b/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c
@@ -1034,6 +1034,27 @@ rel_skb:
__kfree_skb(skb);
}
+static void do_rx_data(struct cxgbi_device *cdev, struct sk_buff *skb)
+{
+ struct cxgbi_sock *csk;
+ struct cpl_rx_data *cpl = (struct cpl_rx_data *)skb->data;
+ unsigned int tid = GET_TID(cpl);
+ struct cxgb4_lld_info *lldi = cxgbi_cdev_priv(cdev);
+ struct tid_info *t = lldi->tids;
+
+ csk = lookup_tid(t, tid);
+ if (!csk) {
+ pr_err("can't find connection for tid %u.\n", tid);
+ } else {
+ /* not expecting this, reset the connection. */
+ pr_err("csk 0x%p, tid %u, rcv cpl_rx_data.\n", csk, tid);
+ spin_lock_bh(&csk->lock);
+ send_abort_req(csk);
+ spin_unlock_bh(&csk->lock);
+ }
+ __kfree_skb(skb);
+}
+
static void do_rx_iscsi_hdr(struct cxgbi_device *cdev, struct sk_buff *skb)
{
struct cxgbi_sock *csk;
@@ -1453,6 +1474,7 @@ cxgb4i_cplhandler_func cxgb4i_cplhandlers[NUM_CPL_CMDS] = {
[CPL_SET_TCB_RPL] = do_set_tcb_rpl,
[CPL_RX_DATA_DDP] = do_rx_data_ddp,
[CPL_RX_ISCSI_DDP] = do_rx_data_ddp,
+ [CPL_RX_DATA] = do_rx_data,
};
int cxgb4i_ofld_init(struct cxgbi_device *cdev)
^ permalink raw reply related
* Re: [PATCH v2] net: introduce helper macro for_each_cmsghdr
From: Gu Zheng @ 2014-12-10 1:56 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, linux-kernel, Joe Perches
In-Reply-To: <5487A455.1090907@cn.fujitsu.com>
There's a mistake in this patch, please ignore it.
Sorry for the noise.
Regards,
Gu
On 12/10/2014 09:39 AM, Gu Zheng wrote:
> Introduce helper macro for_each_cmsghdr as a wrapper of the enumerating
> cmsghdr from msghdr, just cleanup.
>
>
> Signed-off-by: Gu Zheng <guz.fnst@cn.fujitsu.com>
> ---
> v2: use the lower-case macro name as Joe suggested.
> ---
> .../networking/timestamping/timestamping.c | 4 +---
> .../networking/timestamping/txtimestamp.c | 4 +---
> crypto/af_alg.c | 2 +-
> include/linux/socket.h | 4 ++++
> net/core/scm.c | 3 +--
> net/dccp/proto.c | 5 ++---
> net/ipv4/ip_sockglue.c | 2 +-
> net/ipv6/datagram.c | 2 +-
> net/iucv/af_iucv.c | 4 +---
> net/rds/send.c | 4 ++--
> net/rxrpc/ar-output.c | 2 +-
> net/sctp/socket.c | 3 +--
> 12 files changed, 17 insertions(+), 22 deletions(-)
>
> diff --git a/Documentation/networking/timestamping/timestamping.c b/Documentation/networking/timestamping/timestamping.c
> index 5cdfd74..3106e88 100644
> --- a/Documentation/networking/timestamping/timestamping.c
> +++ b/Documentation/networking/timestamping/timestamping.c
> @@ -169,9 +169,7 @@ static void printpacket(struct msghdr *msg, int res,
> res,
> inet_ntoa(from_addr->sin_addr),
> msg->msg_controllen);
> - for (cmsg = CMSG_FIRSTHDR(msg);
> - cmsg;
> - cmsg = CMSG_NXTHDR(msg, cmsg)) {
> + for_each_cmsghdr(cmsg, msg) {
> printf(" cmsg len %zu: ", cmsg->cmsg_len);
> switch (cmsg->cmsg_level) {
> case SOL_SOCKET:
> diff --git a/Documentation/networking/timestamping/txtimestamp.c b/Documentation/networking/timestamping/txtimestamp.c
> index b32fc2a..e44ef35 100644
> --- a/Documentation/networking/timestamping/txtimestamp.c
> +++ b/Documentation/networking/timestamping/txtimestamp.c
> @@ -149,9 +149,7 @@ static void __recv_errmsg_cmsg(struct msghdr *msg, int payload_len)
> struct scm_timestamping *tss = NULL;
> struct cmsghdr *cm;
>
> - for (cm = CMSG_FIRSTHDR(msg);
> - cm && cm->cmsg_len;
> - cm = CMSG_NXTHDR(msg, cm)) {
> + for_each_cmsghdr(cmsg, msg) {
> if (cm->cmsg_level == SOL_SOCKET &&
> cm->cmsg_type == SCM_TIMESTAMPING) {
> tss = (void *) CMSG_DATA(cm);
> diff --git a/crypto/af_alg.c b/crypto/af_alg.c
> index 6a3ad80..3df7d53 100644
> --- a/crypto/af_alg.c
> +++ b/crypto/af_alg.c
> @@ -399,7 +399,7 @@ int af_alg_cmsg_send(struct msghdr *msg, struct af_alg_control *con)
> {
> struct cmsghdr *cmsg;
>
> - for (cmsg = CMSG_FIRSTHDR(msg); cmsg; cmsg = CMSG_NXTHDR(msg, cmsg)) {
> + for_each_cmsghdr(cmsg, msg) {
> if (!CMSG_OK(msg, cmsg))
> return -EINVAL;
> if (cmsg->cmsg_level != SOL_ALG)
> diff --git a/include/linux/socket.h b/include/linux/socket.h
> index bb9b836..d4b592f 100644
> --- a/include/linux/socket.h
> +++ b/include/linux/socket.h
> @@ -94,6 +94,10 @@ struct cmsghdr {
> (cmsg)->cmsg_len <= (unsigned long) \
> ((mhdr)->msg_controllen - \
> ((char *)(cmsg) - (char *)(mhdr)->msg_control)))
> +#define for_each_cmsg_hdr(cmsg, msg) \
> + for (cmsg = CMSG_FIRSTHDR(msg); \
> + cmsg; \
> + cmsg = CMSG_NXTHDR(msg, cmsg))
>
> /*
> * Get the next cmsg header
> diff --git a/net/core/scm.c b/net/core/scm.c
> index b442e7e..e938c49 100644
> --- a/net/core/scm.c
> +++ b/net/core/scm.c
> @@ -129,8 +129,7 @@ int __scm_send(struct socket *sock, struct msghdr *msg, struct scm_cookie *p)
> struct cmsghdr *cmsg;
> int err;
>
> - for (cmsg = CMSG_FIRSTHDR(msg); cmsg; cmsg = CMSG_NXTHDR(msg, cmsg))
> - {
> + for_each_cmsghdr(cmsg, msg) {
> err = -EINVAL;
>
> /* Verify that cmsg_len is at least sizeof(struct cmsghdr) */
> diff --git a/net/dccp/proto.c b/net/dccp/proto.c
> index 5ab6627..d449cc5 100644
> --- a/net/dccp/proto.c
> +++ b/net/dccp/proto.c
> @@ -703,7 +703,7 @@ EXPORT_SYMBOL_GPL(compat_dccp_getsockopt);
>
> static int dccp_msghdr_parse(struct msghdr *msg, struct sk_buff *skb)
> {
> - struct cmsghdr *cmsg = CMSG_FIRSTHDR(msg);
> + struct cmsghdr *cmsg;
>
> /*
> * Assign an (opaque) qpolicy priority value to skb->priority.
> @@ -717,8 +717,7 @@ static int dccp_msghdr_parse(struct msghdr *msg, struct sk_buff *skb)
> */
> skb->priority = 0;
>
> - for (; cmsg != NULL; cmsg = CMSG_NXTHDR(msg, cmsg)) {
> -
> + for_each_cmsghdr(cmsg, msg) {
> if (!CMSG_OK(msg, cmsg))
> return -EINVAL;
>
> diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
> index 9daf217..14a6f71 100644
> --- a/net/ipv4/ip_sockglue.c
> +++ b/net/ipv4/ip_sockglue.c
> @@ -192,7 +192,7 @@ int ip_cmsg_send(struct net *net, struct msghdr *msg, struct ipcm_cookie *ipc,
> int err, val;
> struct cmsghdr *cmsg;
>
> - for (cmsg = CMSG_FIRSTHDR(msg); cmsg; cmsg = CMSG_NXTHDR(msg, cmsg)) {
> + for_each_cmsghdr(cmsg, msg) {
> if (!CMSG_OK(msg, cmsg))
> return -EINVAL;
> #if IS_ENABLED(CONFIG_IPV6)
> diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c
> index 2cdc383..9895b98 100644
> --- a/net/ipv6/datagram.c
> +++ b/net/ipv6/datagram.c
> @@ -640,7 +640,7 @@ int ip6_datagram_send_ctl(struct net *net, struct sock *sk,
> int len;
> int err = 0;
>
> - for (cmsg = CMSG_FIRSTHDR(msg); cmsg; cmsg = CMSG_NXTHDR(msg, cmsg)) {
> + for_each_cmsghdr(cmsg, msg) {
> int addr_type;
>
> if (!CMSG_OK(msg, cmsg)) {
> diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c
> index a089b6b..eae4e08 100644
> --- a/net/iucv/af_iucv.c
> +++ b/net/iucv/af_iucv.c
> @@ -1070,9 +1070,7 @@ static int iucv_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
> txmsg.class = 0;
>
> /* iterate over control messages */
> - for (cmsg = CMSG_FIRSTHDR(msg); cmsg;
> - cmsg = CMSG_NXTHDR(msg, cmsg)) {
> -
> + for_each_cmsghdr(cmsg, msg) {
> if (!CMSG_OK(msg, cmsg)) {
> err = -EINVAL;
> goto out;
> diff --git a/net/rds/send.c b/net/rds/send.c
> index 0a64541..1accb3e 100644
> --- a/net/rds/send.c
> +++ b/net/rds/send.c
> @@ -826,7 +826,7 @@ static int rds_rm_size(struct msghdr *msg, int data_len)
> int cmsg_groups = 0;
> int retval;
>
> - for (cmsg = CMSG_FIRSTHDR(msg); cmsg; cmsg = CMSG_NXTHDR(msg, cmsg)) {
> + for_each_cmsghdr(cmsg, msg) {
> if (!CMSG_OK(msg, cmsg))
> return -EINVAL;
>
> @@ -878,7 +878,7 @@ static int rds_cmsg_send(struct rds_sock *rs, struct rds_message *rm,
> struct cmsghdr *cmsg;
> int ret = 0;
>
> - for (cmsg = CMSG_FIRSTHDR(msg); cmsg; cmsg = CMSG_NXTHDR(msg, cmsg)) {
> + for_each_cmsghdr(cmsg, msg) {
> if (!CMSG_OK(msg, cmsg))
> return -EINVAL;
>
> diff --git a/net/rxrpc/ar-output.c b/net/rxrpc/ar-output.c
> index 0b4b9a7..f915e7e 100644
> --- a/net/rxrpc/ar-output.c
> +++ b/net/rxrpc/ar-output.c
> @@ -45,7 +45,7 @@ static int rxrpc_sendmsg_cmsg(struct rxrpc_sock *rx, struct msghdr *msg,
> if (msg->msg_controllen == 0)
> return -EINVAL;
>
> - for (cmsg = CMSG_FIRSTHDR(msg); cmsg; cmsg = CMSG_NXTHDR(msg, cmsg)) {
> + for_each_cmsghdr(cmsg, msg) {
> if (!CMSG_OK(msg, cmsg))
> return -EINVAL;
>
> diff --git a/net/sctp/socket.c b/net/sctp/socket.c
> index 634a2ab..58834d7 100644
> --- a/net/sctp/socket.c
> +++ b/net/sctp/socket.c
> @@ -6592,8 +6592,7 @@ static int sctp_msghdr_parse(const struct msghdr *msg, sctp_cmsgs_t *cmsgs)
> struct cmsghdr *cmsg;
> struct msghdr *my_msg = (struct msghdr *)msg;
>
> - for (cmsg = CMSG_FIRSTHDR(msg); cmsg != NULL;
> - cmsg = CMSG_NXTHDR(my_msg, cmsg)) {
> + for_each_cmsghdr(cmsg, my_msg) {
> if (!CMSG_OK(my_msg, cmsg))
> return -EINVAL;
>
^ permalink raw reply
* Re: [PATCH v2] net: introduce helper macro for_each_cmsghdr
From: Joe Perches @ 2014-12-10 2:01 UTC (permalink / raw)
To: Gu Zheng; +Cc: David S. Miller, netdev, linux-kernel
In-Reply-To: <5487A455.1090907@cn.fujitsu.com>
On Wed, 2014-12-10 at 09:39 +0800, Gu Zheng wrote:
> Introduce helper macro for_each_cmsghdr as a wrapper of the enumerating
> cmsghdr from msghdr, just cleanup.
Does this even compile?
So which is it?
for_each_cmsghdr
or
for_each_cmsg_hdr?
The .h #defines for_each_cmsg_hdr
but all the uses are for_each_cmsghdr
> diff --git a/Documentation/networking/timestamping/timestamping.c b/Documentation/networking/timestamping/timestamping.c
[]
> @@ -169,9 +169,7 @@ static void printpacket(struct msghdr *msg, int res,
> res,
> inet_ntoa(from_addr->sin_addr),
> msg->msg_controllen);
> - for (cmsg = CMSG_FIRSTHDR(msg);
> - cmsg;
> - cmsg = CMSG_NXTHDR(msg, cmsg)) {
> + for_each_cmsghdr(cmsg, msg) {
> printf(" cmsg len %zu: ", cmsg->cmsg_len);
> switch (cmsg->cmsg_level) {
> case SOL_SOCKET:
> diff --git a/crypto/af_alg.c b/crypto/af_alg.c
[]
> @@ -399,7 +399,7 @@ int af_alg_cmsg_send(struct msghdr *msg, struct af_alg_control *con)
> {
> struct cmsghdr *cmsg;
>
> - for (cmsg = CMSG_FIRSTHDR(msg); cmsg; cmsg = CMSG_NXTHDR(msg, cmsg)) {
> + for_each_cmsghdr(cmsg, msg) {
> if (!CMSG_OK(msg, cmsg))
> return -EINVAL;
> if (cmsg->cmsg_level != SOL_ALG)
> diff --git a/include/linux/socket.h b/include/linux/socket.h
[]
> @@ -94,6 +94,10 @@ struct cmsghdr {
> (cmsg)->cmsg_len <= (unsigned long) \
> ((mhdr)->msg_controllen - \
> ((char *)(cmsg) - (char *)(mhdr)->msg_control)))
> +#define for_each_cmsg_hdr(cmsg, msg) \
> + for (cmsg = CMSG_FIRSTHDR(msg); \
> + cmsg; \
> + cmsg = CMSG_NXTHDR(msg, cmsg))
^ permalink raw reply
* Re: [PATCH v2] net: introduce helper macro for_each_cmsghdr
From: Gu Zheng @ 2014-12-10 2:02 UTC (permalink / raw)
To: Joe Perches; +Cc: David S. Miller, netdev, linux-kernel
In-Reply-To: <1418176864.1047.6.camel@perches.com>
Hi Joe,
On 12/10/2014 10:01 AM, Joe Perches wrote:
> On Wed, 2014-12-10 at 09:39 +0800, Gu Zheng wrote:
>> Introduce helper macro for_each_cmsghdr as a wrapper of the enumerating
>> cmsghdr from msghdr, just cleanup.
>
> Does this even compile?
>
> So which is it?
>
> for_each_cmsghdr
> or
> for_each_cmsg_hdr?
>
> The .h #defines for_each_cmsg_hdr
> but all the uses are for_each_cmsghdr
Thanks for your quick feedback.
There seems some problems with my send-patch script, it sent out the patch
before the test completed.
Thanks,
Gu
>
>> diff --git a/Documentation/networking/timestamping/timestamping.c b/Documentation/networking/timestamping/timestamping.c
> []
>> @@ -169,9 +169,7 @@ static void printpacket(struct msghdr *msg, int res,
>> res,
>> inet_ntoa(from_addr->sin_addr),
>> msg->msg_controllen);
>> - for (cmsg = CMSG_FIRSTHDR(msg);
>> - cmsg;
>> - cmsg = CMSG_NXTHDR(msg, cmsg)) {
>> + for_each_cmsghdr(cmsg, msg) {
>> printf(" cmsg len %zu: ", cmsg->cmsg_len);
>> switch (cmsg->cmsg_level) {
>> case SOL_SOCKET:
>> diff --git a/crypto/af_alg.c b/crypto/af_alg.c
> []
>> @@ -399,7 +399,7 @@ int af_alg_cmsg_send(struct msghdr *msg, struct af_alg_control *con)
>> {
>> struct cmsghdr *cmsg;
>>
>> - for (cmsg = CMSG_FIRSTHDR(msg); cmsg; cmsg = CMSG_NXTHDR(msg, cmsg)) {
>> + for_each_cmsghdr(cmsg, msg) {
>> if (!CMSG_OK(msg, cmsg))
>> return -EINVAL;
>> if (cmsg->cmsg_level != SOL_ALG)
>> diff --git a/include/linux/socket.h b/include/linux/socket.h
> []
>> @@ -94,6 +94,10 @@ struct cmsghdr {
>> (cmsg)->cmsg_len <= (unsigned long) \
>> ((mhdr)->msg_controllen - \
>> ((char *)(cmsg) - (char *)(mhdr)->msg_control)))
>> +#define for_each_cmsg_hdr(cmsg, msg) \
>> + for (cmsg = CMSG_FIRSTHDR(msg); \
>> + cmsg; \
>> + cmsg = CMSG_NXTHDR(msg, cmsg))
>
>
>
> .
>
^ permalink raw reply
* Re: [PATCH net] tcp: fix more NULL deref after prequeue changes
From: David Miller @ 2014-12-10 2:39 UTC (permalink / raw)
To: eric.dumazet; +Cc: dann.frazier, netdev
In-Reply-To: <1418147768.27198.7.camel@edumazet-glaptop2.roam.corp.google.com>
From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Tue, 09 Dec 2014 09:56:08 -0800
> From: Eric Dumazet <edumazet@google.com>
>
> When I cooked commit c3658e8d0f1 ("tcp: fix possible NULL dereference in
> tcp_vX_send_reset()") I missed other spots we could deref a NULL
> skb_dst(skb)
>
> Again, if a socket is provided, we do not need skb_dst() to get a
> pointer to network namespace : sock_net(sk) is good enough.
>
> Reported-by: Dann Frazier <dann.frazier@canonical.com>
> Bisected-by: Dann Frazier <dann.frazier@canonical.com>
> Tested-by: Dann Frazier <dann.frazier@canonical.com>
> Signed-off-by: Eric Dumazet <edumazet@google.com>
> Fixes: ca777eff51f7 ("tcp: remove dst refcount false sharing for prequeue mode")
Applied and queued up for 3.18-stable.
^ permalink raw reply
* Re: [PATCHv1 net] xen-netfront: use correct linear area after linearizing an skb
From: David Miller @ 2014-12-10 2:41 UTC (permalink / raw)
To: david.vrabel; +Cc: netdev, xen-devel, konrad.wilk, boris.ostrovsky
In-Reply-To: <1418150608-26180-1-git-send-email-david.vrabel@citrix.com>
From: David Vrabel <david.vrabel@citrix.com>
Date: Tue, 9 Dec 2014 18:43:28 +0000
> Commit 97a6d1bb2b658ac85ed88205ccd1ab809899884d (xen-netfront: Fix
> handling packets on compound pages with skb_linearize) attempted to
> fix a problem where an skb that would have required too many slots
> would be dropped causing TCP connections to stall.
>
> However, it filled in the first slot using the original buffer and not
> the new one and would use the wrong offset and grant access to the
> wrong page.
>
> Netback would notice the malformed request and stop all traffic on the
> VIF, reporting:
>
> vif vif-3-0 vif3.0: txreq.offset: 85e, size: 4002, end: 6144
> vif vif-3-0 vif3.0: fatal error; disabling device
>
> Reported-by: Anthony Wright <anthony@overnetdata.com>
> Tested-by: Anthony Wright <anthony@overnetdata.com>
> Signed-off-by: David Vrabel <david.vrabel@citrix.com>
Applied and queued up for -stable, thanks.
^ permalink raw reply
* [PATCH net-next] bridge: Add ability to always enable TSO/UFO
From: Toshiaki Makita @ 2014-12-10 2:43 UTC (permalink / raw)
To: David S . Miller, Stephen Hemminger; +Cc: netdev, bridge
In-Reply-To: <1418179394-4470-1-git-send-email-makita.toshiaki@lab.ntt.co.jp>
Currently a bridge device turns off TSO/UFO features if no bridge ports
support it. We can always enable them, since packets can be segmented
on ports by software as well as on the bridge device.
This will reduce the number of packets processed in the bridge.
Signed-off-by: Toshiaki Makita <makita.toshiaki@lab.ntt.co.jp>
---
net/bridge/br_if.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c
index ed307db..e93bf17 100644
--- a/net/bridge/br_if.c
+++ b/net/bridge/br_if.c
@@ -418,7 +418,7 @@ netdev_features_t br_features_recompute(struct net_bridge *br,
return features;
mask = features;
- features &= ~NETIF_F_ONE_FOR_ALL;
+ features &= ~NETIF_F_ONE_FOR_ALL | NETIF_F_GSO_SOFTWARE;
list_for_each_entry(p, &br->port_list, list) {
features = netdev_increment_features(features,
--
1.8.1.2
^ permalink raw reply related
* [PATCH net-next] vlan: Add ability to always enable TSO/UFO
From: Toshiaki Makita @ 2014-12-10 2:43 UTC (permalink / raw)
To: David S . Miller, Patrick McHardy; +Cc: Toshiaki Makita, netdev
Since the real device can segment packets by software, a vlan device
can set TSO/UFO even when the real device doesn't have those features.
Unlike GSO, this allows packets to be segmented after Qdisc.
Signed-off-by: Toshiaki Makita <makita.toshiaki@lab.ntt.co.jp>
---
net/8021q/vlan_dev.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c
index 3768050..1189564 100644
--- a/net/8021q/vlan_dev.c
+++ b/net/8021q/vlan_dev.c
@@ -579,11 +579,12 @@ static int vlan_dev_init(struct net_device *dev)
(1<<__LINK_STATE_PRESENT);
dev->hw_features = NETIF_F_ALL_CSUM | NETIF_F_SG |
- NETIF_F_FRAGLIST | NETIF_F_ALL_TSO |
+ NETIF_F_FRAGLIST | NETIF_F_GSO_SOFTWARE |
NETIF_F_HIGHDMA | NETIF_F_SCTP_CSUM |
NETIF_F_ALL_FCOE;
- dev->features |= real_dev->vlan_features | NETIF_F_LLTX;
+ dev->features |= real_dev->vlan_features | NETIF_F_LLTX |
+ NETIF_F_GSO_SOFTWARE;
dev->gso_max_size = real_dev->gso_max_size;
if (dev->features & NETIF_F_VLAN_FEATURES)
netdev_warn(real_dev, "VLAN features are set incorrectly. Q-in-Q configurations may not work correctly.\n");
@@ -648,7 +649,7 @@ static netdev_features_t vlan_dev_fix_features(struct net_device *dev,
features |= NETIF_F_RXCSUM;
features = netdev_intersect_features(features, real_dev->features);
- features |= old_features & NETIF_F_SOFT_FEATURES;
+ features |= old_features & (NETIF_F_SOFT_FEATURES | NETIF_F_GSO_SOFTWARE);
features |= NETIF_F_LLTX;
return features;
--
1.8.1.2
^ permalink raw reply related
* Re: [RFC PATCH net-next 00/11] net: remove disable_irq() from ->ndo_poll_controller
From: David Miller @ 2014-12-10 2:44 UTC (permalink / raw)
To: sd; +Cc: netdev, peterz, tglx
In-Reply-To: <1418135842-21389-1-git-send-email-sd@queasysnail.net>
Adding a new spinlock to every interrupt service routine is
simply a non-starter.
You will certainly have to find a way to fix this in a way
that doesn't involve adding any new overhead to the normal
operational paths of these drivers.
Thanks.
^ permalink raw reply
* Re: [PATCH net-next] amd-xgbe: Use disable_irq_nosync when in IRQ context
From: David Miller @ 2014-12-10 2:48 UTC (permalink / raw)
To: thomas.lendacky; +Cc: netdev
In-Reply-To: <20141209205408.26097.70441.stgit@tlendack-t1.amdoffice.net>
From: Tom Lendacky <thomas.lendacky@amd.com>
Date: Tue, 9 Dec 2014 14:54:08 -0600
> The disable_irq_nosync function, not the disable_irq function, must be
> used to disable the DMA channel interrupt from within the interrupt
> service routine. Change the disable_irq call to disable_irq_nosync.
>
> Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
Applied, thanks Tom.
^ permalink raw reply
* Re: [PATCH] fix suspicious rcu_dereference_check in net/sched/sch_fq_codel.c
From: David Miller @ 2014-12-10 2:49 UTC (permalink / raw)
To: Valdis.Kletnieks; +Cc: edumazet, john.r.fastabend, linux-kernel, netdev
In-Reply-To: <58905.1418159750@turing-police.cc.vt.edu>
From: Valdis Kletnieks <Valdis.Kletnieks@vt.edu>
Date: Tue, 09 Dec 2014 16:15:50 -0500
> commit 46e5da40ae (net: qdisc: use rcu prefix and silence
> sparse warnings) triggers a spurious warning:
>
> net/sched/sch_fq_codel.c:97 suspicious rcu_dereference_check() usage!
>
> The code should be using the _bh variant of rcu_dereference.
>
> Signed-off-by: Valdis Kletnieks <valdis.kletnieks@vt.edu>
Applied and queued up for -stable, thanks.
^ permalink raw reply
* Re: [patch net-next v2] net: sched: cls: use nla_nest_cancel instead of nlmsg_trim
From: David Miller @ 2014-12-10 2:51 UTC (permalink / raw)
To: jiri; +Cc: netdev, jhs
In-Reply-To: <1418160209-20001-1-git-send-email-jiri@resnulli.us>
From: Jiri Pirko <jiri@resnulli.us>
Date: Tue, 9 Dec 2014 22:23:29 +0100
> To cancel nesting, this function is more convenient.
>
> Signed-off-by: Jiri Pirko <jiri@resnulli.us>
> ---
> v1->v2:
> - removed remaining use of b in tcindex pointed out by DaveM
This one compiles! :-)
Applied, thanks.
^ permalink raw reply
* Re: [net-next] dummy: use MODULE_VERSION
From: David Miller @ 2014-12-10 2:52 UTC (permalink / raw)
To: fbl; +Cc: netdev
In-Reply-To: <1418172108-10522-1-git-send-email-fbl@redhat.com>
From: Flavio Leitner <fbl@redhat.com>
Date: Tue, 9 Dec 2014 22:41:48 -0200
> Use MODULE_VERSION() now that dummy driver has a version.
>
> Signed-off-by: Flavio Leitner <fbl@redhat.com>
Applied, thanks a lot Flavio.
^ permalink raw reply
* Re: [PATCH 0/20] fix misspelling of current function in string
From: Julian Calaby @ 2014-12-10 2:56 UTC (permalink / raw)
To: Julia Lawall
Cc: devel@driverdev.osuosl.org, linux-samsung-soc, linux-scsi,
linux-pci, linux-wireless, intel-gfx, linux-usb, kernel-janitors,
linux-kernel@vger.kernel.org, dri-devel, netdev, linux-mtd, linux,
Joe Perches, Mailing List, Arm
In-Reply-To: <alpine.DEB.2.02.1412080738210.2100@localhost6.localdomain6>
Hi Julia,
On Mon, Dec 8, 2014 at 5:43 PM, Julia Lawall <julia.lawall@lip6.fr> wrote:
> On Mon, 8 Dec 2014, Julian Calaby wrote:
>
>> Hi Julia,
>>
>> On Mon, Dec 8, 2014 at 6:20 AM, Julia Lawall <Julia.Lawall@lip6.fr> wrote:
>> > These patches replace what appears to be a reference to the name of the
>> > current function but is misspelled in some way by either the name of the
>> > function itself, or by %s and then __func__ in an argument list.
>>
>> Would there be any value in doing this for _all_ cases where the
>> function name is written in a format string?
>
> Probably. But there are a lot of them. Even for the misspellings, I have
> only don about 1/3 of the cases.
>
> On the other hand, the misspelling have to be checked carefully, because a
> misspelling of one thing could be the correct spelling of the thing thst
> was actually intended.
>
> Joe, however, points out that a lot of these prints are just for function
> tracing, and could be removed. I worked on another semantic patch that
> tries to do that. It might be better to remove those prints completely,
> rather than sending one patch to transform them and then one patch to
> remove them after that. That is why for this series I did only the ones
> where there was actually a problem.
Ok, that makes sense.
Either way though, this is a really interesting application of the
semantic patching. Nice work!
Thanks,
--
Julian Calaby
Email: julian.calaby@gmail.com
Profile: http://www.google.com/profiles/julian.calaby/
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply
* [PATCH net-next] tipc: fix RCU sparse error
From: Ying Xue @ 2014-12-10 3:00 UTC (permalink / raw)
To: davem; +Cc: jon.maloy, kbuild-all, erik.hugne, netdev, tipc-discussion
The commit 97ede29e80ee ("tipc: convert name table read-write lock to
RCU") involves the following sparse when using
make ARCH=x86_64 allmodconfig
make C=1 CF=-D__CHECK_ENDIAN__
net/tipc/name_table.c:1136:17: sparse: incompatible types in comparison expression (different address spaces)
net/tipc/name_table.c:1136:17: sparse: incompatible types in comparison expression (different address spaces)
To silence above spare complaint, an RCU annotation should be added
to next pointer of hlist_node structure through hlist_next_rcu() macro
when iterating over a hlist with hlist_for_each_entry_from_rcu().
By the way, this commit also simplifies the way of dereferencing
the first element of a hlist_head list by replacing
hlist_for_each_entry_rcu() with hlist_entry_safe().
Reported-by: Kbuild test robot <kbuild-all@01.org>
Cc: Kbuild test robot <kbuild-all@01.org>
Signed-off-by: Ying Xue <ying.xue@windriver.com>
---
include/linux/rculist.h | 4 ++--
net/tipc/name_table.c | 6 +++---
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/include/linux/rculist.h b/include/linux/rculist.h
index aa79b3c..866d9c9 100644
--- a/include/linux/rculist.h
+++ b/include/linux/rculist.h
@@ -549,8 +549,8 @@ static inline void hlist_add_behind_rcu(struct hlist_node *n,
*/
#define hlist_for_each_entry_from_rcu(pos, member) \
for (; pos; \
- pos = hlist_entry_safe(rcu_dereference((pos)->member.next),\
- typeof(*(pos)), member))
+ pos = hlist_entry_safe(rcu_dereference_raw(hlist_next_rcu( \
+ &(pos)->member)), typeof(*(pos)), member))
#endif /* __KERNEL__ */
#endif
diff --git a/net/tipc/name_table.c b/net/tipc/name_table.c
index c8df022..fa4341f 100644
--- a/net/tipc/name_table.c
+++ b/net/tipc/name_table.c
@@ -1110,7 +1110,7 @@ static int __tipc_nl_seq_list(struct tipc_nl_msg *msg, u32 *last_type,
u32 *last_lower, u32 *last_publ)
{
struct hlist_head *seq_head;
- struct name_seq *seq = NULL;
+ struct name_seq *seq;
int err;
int i;
@@ -1127,8 +1127,8 @@ static int __tipc_nl_seq_list(struct tipc_nl_msg *msg, u32 *last_type,
if (!seq)
return -EPIPE;
} else {
- hlist_for_each_entry_rcu(seq, seq_head, ns_list)
- break;
+ seq = hlist_entry_safe(rcu_dereference_raw(
+ hlist_first_rcu(seq_head)), struct name_seq, ns_list);
if (!seq)
continue;
}
--
1.7.9.5
^ permalink raw reply related
* Re: [PATCH 1/1] net: dsa: Fix of kernel panic in case of missing PHY.
From: Florian Fainelli @ 2014-12-10 3:23 UTC (permalink / raw)
To: Andrey Volkov, netdev, Brian Norris
In-Reply-To: <54873205.30401@nexvision.fr>
On 09/12/14 09:31, Andrey Volkov wrote:
> Fix of kernel panic in case of missing PHY.
>
> Signed-off-by: Andrey Volkov <andrey.volkov@nexvision.fr>
Brian has actually been able to reproduce such a crash in this code-path
today:
if (!p->phy) {
p->phy = ds->slave_mii_bus->phy_map[p->port];
phy_connect_direct(slave_dev, p->phy,
dsa_slave_adjust_link,
p->phy_interface);
}
we basically assume here that we have a valid phy pointer out of
ds->slave_mii_bus->phy_map[p->port] which is not true in all cases,
especially not if the device is not there.
I will come up with a fix for that, as for propagating the error code
down to the caller, this can be a separate patch.
Thanks!
> ---
> net/dsa/slave.c | 19 +++++++++++++++----
> 1 file changed, 15 insertions(+), 4 deletions(-)
>
> diff --git a/net/dsa/slave.c b/net/dsa/slave.c
> index 528380a..6f89caa 100644
> --- a/net/dsa/slave.c
> +++ b/net/dsa/slave.c
> @@ -512,7 +512,7 @@ static int dsa_slave_fixed_link_update(struct net_device *dev,
> }
>
> /* slave device setup *******************************************************/
> -static void dsa_slave_phy_setup(struct dsa_slave_priv *p,
> +static int dsa_slave_phy_setup(struct dsa_slave_priv *p,
> struct net_device *slave_dev)
> {
> struct dsa_switch *ds = p->parent;
> @@ -533,7 +533,7 @@ static void dsa_slave_phy_setup(struct dsa_slave_priv *p,
> ret = of_phy_register_fixed_link(port_dn);
> if (ret) {
> netdev_err(slave_dev, "failed to register fixed PHY\n");
> - return;
> + return ret;
> }
> phy_is_fixed = true;
> phy_dn = port_dn;
> @@ -555,12 +555,17 @@ static void dsa_slave_phy_setup(struct dsa_slave_priv *p,
> */
> if (!p->phy) {
> p->phy = ds->slave_mii_bus->phy_map[p->port];
> - phy_connect_direct(slave_dev, p->phy, dsa_slave_adjust_link,
> + if(p->phy)
> + phy_connect_direct(slave_dev, p->phy, dsa_slave_adjust_link,
> p->phy_interface);
> + else
> + return -ENODEV;
> +
> } else {
> netdev_info(slave_dev, "attached PHY at address %d [%s]\n",
> p->phy->addr, p->phy->drv->name);
> }
> + return 0;
> }
>
> int dsa_slave_suspend(struct net_device *slave_dev)
> @@ -653,7 +658,13 @@ dsa_slave_create(struct dsa_switch *ds, struct device *parent,
> p->old_link = -1;
> p->old_duplex = -1;
>
> - dsa_slave_phy_setup(p, slave_dev);
> + ret = dsa_slave_phy_setup(p, slave_dev);
> + if (ret) {
> + netdev_err(master, "error %d registering interface %s\n",
> + ret, slave_dev->name);
> + free_netdev(slave_dev);
> + return NULL;
> + }
>
> ret = register_netdev(slave_dev);
> if (ret) {
>
^ permalink raw reply
* [PATCH net-next] ipv6: fix sparse warning
From: Ying Xue @ 2014-12-10 3:28 UTC (permalink / raw)
To: davem; +Cc: netdev
This fixes the following sparse warning when using
make C=1 CF=-D__CHECK_ENDIAN__ net/ipv6/addrconf.o
net/ipv6/addrconf.c:3495:9: error: incompatible types in comparison expression (different address spaces)
net/ipv6/addrconf.c:3495:9: error: incompatible types in comparison expression (different address spaces)
net/ipv6/addrconf.c:3495:9: error: incompatible types in comparison expression (different address spaces)
net/ipv6/addrconf.c:3495:9: error: incompatible types in comparison expression (different address spaces)
To silence above spare complaint, an RCU annotation should be added
to next pointer of hlist_node structure through hlist_next_rcu() macro
when iterating over a hlist with hlist_for_each_entry_continue_rcu_bh().
By the way, this commit also resolves the same error appearing in
hlist_for_each_entry_continue_rcu().
Signed-off-by: Ying Xue <ying.xue@windriver.com>
---
include/linux/rculist.h | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/include/linux/rculist.h b/include/linux/rculist.h
index 866d9c9..32bd4ad 100644
--- a/include/linux/rculist.h
+++ b/include/linux/rculist.h
@@ -524,11 +524,11 @@ static inline void hlist_add_behind_rcu(struct hlist_node *n,
* @member: the name of the hlist_node within the struct.
*/
#define hlist_for_each_entry_continue_rcu(pos, member) \
- for (pos = hlist_entry_safe(rcu_dereference((pos)->member.next),\
- typeof(*(pos)), member); \
+ for (pos = hlist_entry_safe(rcu_dereference_raw(hlist_next_rcu( \
+ &(pos)->member)), typeof(*(pos)), member); \
pos; \
- pos = hlist_entry_safe(rcu_dereference((pos)->member.next),\
- typeof(*(pos)), member))
+ pos = hlist_entry_safe(rcu_dereference_raw(hlist_next_rcu( \
+ &(pos)->member)), typeof(*(pos)), member))
/**
* hlist_for_each_entry_continue_rcu_bh - iterate over a hlist continuing after current point
@@ -536,11 +536,11 @@ static inline void hlist_add_behind_rcu(struct hlist_node *n,
* @member: the name of the hlist_node within the struct.
*/
#define hlist_for_each_entry_continue_rcu_bh(pos, member) \
- for (pos = hlist_entry_safe(rcu_dereference_bh((pos)->member.next),\
- typeof(*(pos)), member); \
+ for (pos = hlist_entry_safe(rcu_dereference_bh(hlist_next_rcu( \
+ &(pos)->member)), typeof(*(pos)), member); \
pos; \
- pos = hlist_entry_safe(rcu_dereference_bh((pos)->member.next),\
- typeof(*(pos)), member))
+ pos = hlist_entry_safe(rcu_dereference_bh(hlist_next_rcu( \
+ &(pos)->member)), typeof(*(pos)), member))
/**
* hlist_for_each_entry_from_rcu - iterate over a hlist continuing from current point
--
1.7.9.5
^ permalink raw reply related
* [net-next PATCH 0/6] net: Alloc NAPI page frags from their own pool
From: Alexander Duyck @ 2014-12-10 3:40 UTC (permalink / raw)
To: netdev; +Cc: ast, davem, eric.dumazet, brouer
This patch series implements a means of allocating page fragments without
the need for the local_irq_save/restore in __netdev_alloc_frag. By doing
this I am able to decrease packet processing time by 11ns per packet in my
test environment.
---
Alexander Duyck (6):
net: Split netdev_alloc_frag into __alloc_page_frag and add __napi_alloc_frag
net: Pull out core bits of __netdev_alloc_skb and add __napi_alloc_skb
ethernet/intel: Use napi_alloc_skb
cxgb: Use napi_alloc_skb instead of netdev_alloc_skb_ip_align
ethernet/realtek: use napi_alloc_skb instead of netdev_alloc_skb_ip_align
ethernet/broadcom: Use napi_alloc_skb instead of netdev_alloc_skb_ip_align
drivers/net/ethernet/broadcom/b44.c | 2
drivers/net/ethernet/broadcom/bcm63xx_enet.c | 2
drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 2
drivers/net/ethernet/chelsio/cxgb/sge.c | 11 +
drivers/net/ethernet/intel/e1000/e1000_main.c | 2
drivers/net/ethernet/intel/e1000e/netdev.c | 2
drivers/net/ethernet/intel/fm10k/fm10k_main.c | 4
drivers/net/ethernet/intel/igb/igb_main.c | 3
drivers/net/ethernet/intel/ixgb/ixgb_main.c | 6 -
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 4
drivers/net/ethernet/realtek/8139cp.c | 2
drivers/net/ethernet/realtek/8139too.c | 2
drivers/net/ethernet/realtek/r8169.c | 2
include/linux/skbuff.h | 11 +
net/core/dev.c | 2
net/core/skbuff.c | 191 +++++++++++++++++------
16 files changed, 178 insertions(+), 70 deletions(-)
--
^ permalink raw reply
* [net-next PATCH 1/6] net: Split netdev_alloc_frag into __alloc_page_frag and add __napi_alloc_frag
From: Alexander Duyck @ 2014-12-10 3:40 UTC (permalink / raw)
To: netdev; +Cc: ast, davem, eric.dumazet, brouer
In-Reply-To: <20141210033902.2114.68658.stgit@ahduyck-vm-fedora20>
This patch splits the netdev_alloc_frag function up so that it can be used
on one of two page frag pools instead of being fixed on the
netdev_alloc_cache. By doing this we can add a NAPI specific function
__napi_alloc_frag that accesses a pool that is only used from softirq
context. The advantage to this is that we do not need to call
local_irq_save/restore which can be a significant savings.
I also took the opportunity to refactor the core bits that were placed in
__alloc_page_frag. First I updated the allocation to do either a 32K
allocation or an order 0 page. This is based on the changes in commmit
d9b2938aa where it was found that latencies could be reduced in case of
failures. Then I also rewrote the logic to work from the end of the page to
the start. By doing this the size value doesn't have to be used unless we
have run out of space for page fragments. Finally I cleaned up the atomic
bits so that we just do an atomic_sub_and_test and if that returns true then
we set the page->_count via an atomic_set. This way we can remove the extra
conditional for the atomic_read since it would have led to an atomic_inc in
the case of success anyway.
Signed-off-by: Alexander Duyck <alexander.h.duyck@redhat.com>
---
include/linux/skbuff.h | 2 +
net/core/skbuff.c | 117 ++++++++++++++++++++++++++++++++----------------
2 files changed, 79 insertions(+), 40 deletions(-)
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index ef64cec..b2b53b0 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -2164,6 +2164,8 @@ static inline struct sk_buff *netdev_alloc_skb_ip_align(struct net_device *dev,
return __netdev_alloc_skb_ip_align(dev, length, GFP_ATOMIC);
}
+void *napi_alloc_frag(unsigned int fragsz);
+
/**
* __dev_alloc_pages - allocate page for network Rx
* @gfp_mask: allocation priority. Set __GFP_NOMEMALLOC if not for network Rx
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 7a338fb..56ed17c 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -336,59 +336,85 @@ struct netdev_alloc_cache {
unsigned int pagecnt_bias;
};
static DEFINE_PER_CPU(struct netdev_alloc_cache, netdev_alloc_cache);
+static DEFINE_PER_CPU(struct netdev_alloc_cache, napi_alloc_cache);
-static void *__netdev_alloc_frag(unsigned int fragsz, gfp_t gfp_mask)
+static struct page *__page_frag_refill(struct netdev_alloc_cache *nc,
+ gfp_t gfp_mask)
{
- struct netdev_alloc_cache *nc;
- void *data = NULL;
- int order;
- unsigned long flags;
+ const unsigned int order = NETDEV_FRAG_PAGE_MAX_ORDER;
+ struct page *page = NULL;
+ gfp_t gfp = gfp_mask;
+
+ if (order) {
+ gfp_mask |= __GFP_COMP | __GFP_NOWARN | __GFP_NORETRY;
+ page = alloc_pages_node(NUMA_NO_NODE, gfp_mask, order);
+ nc->frag.size = PAGE_SIZE << (page ? order : 0);
+ }
- local_irq_save(flags);
- nc = this_cpu_ptr(&netdev_alloc_cache);
- if (unlikely(!nc->frag.page)) {
+ if (unlikely(!page))
+ page = alloc_pages_node(NUMA_NO_NODE, gfp, 0);
+
+ nc->frag.page = page;
+
+ return page;
+}
+
+static void *__alloc_page_frag(struct netdev_alloc_cache __percpu *cache,
+ unsigned int fragsz, gfp_t gfp_mask)
+{
+ struct netdev_alloc_cache *nc = this_cpu_ptr(cache);
+ struct page *page = nc->frag.page;
+ unsigned int size;
+ int offset;
+
+ if (unlikely(!page)) {
refill:
- for (order = NETDEV_FRAG_PAGE_MAX_ORDER; ;) {
- gfp_t gfp = gfp_mask;
+ page = __page_frag_refill(nc, gfp_mask);
+ if (!page)
+ return NULL;
+
+ /* if size can vary use frag.size else just use PAGE_SIZE */
+ size = NETDEV_FRAG_PAGE_MAX_ORDER ? nc->frag.size : PAGE_SIZE;
- if (order)
- gfp |= __GFP_COMP | __GFP_NOWARN;
- nc->frag.page = alloc_pages(gfp, order);
- if (likely(nc->frag.page))
- break;
- if (--order < 0)
- goto end;
- }
- nc->frag.size = PAGE_SIZE << order;
/* Even if we own the page, we do not use atomic_set().
* This would break get_page_unless_zero() users.
*/
- atomic_add(NETDEV_PAGECNT_MAX_BIAS - 1,
- &nc->frag.page->_count);
- nc->pagecnt_bias = NETDEV_PAGECNT_MAX_BIAS;
- nc->frag.offset = 0;
+ atomic_add(size - 1, &page->_count);
+
+ /* reset page count bias and offset to start of new frag */
+ nc->pagecnt_bias = size;
+ nc->frag.offset = size;
}
- if (nc->frag.offset + fragsz > nc->frag.size) {
- if (atomic_read(&nc->frag.page->_count) != nc->pagecnt_bias) {
- if (!atomic_sub_and_test(nc->pagecnt_bias,
- &nc->frag.page->_count))
- goto refill;
- /* OK, page count is 0, we can safely set it */
- atomic_set(&nc->frag.page->_count,
- NETDEV_PAGECNT_MAX_BIAS);
- } else {
- atomic_add(NETDEV_PAGECNT_MAX_BIAS - nc->pagecnt_bias,
- &nc->frag.page->_count);
- }
- nc->pagecnt_bias = NETDEV_PAGECNT_MAX_BIAS;
- nc->frag.offset = 0;
+ offset = nc->frag.offset - fragsz;
+ if (unlikely(offset < 0)) {
+ if (!atomic_sub_and_test(nc->pagecnt_bias, &page->_count))
+ goto refill;
+
+ /* if size can vary use frag.size else just use PAGE_SIZE */
+ size = NETDEV_FRAG_PAGE_MAX_ORDER ? nc->frag.size : PAGE_SIZE;
+
+ /* OK, page count is 0, we can safely set it */
+ atomic_set(&page->_count, size);
+
+ /* reset page count bias and offset to start of new frag */
+ nc->pagecnt_bias = size;
+ offset = size - fragsz;
}
- data = page_address(nc->frag.page) + nc->frag.offset;
- nc->frag.offset += fragsz;
nc->pagecnt_bias--;
-end:
+ nc->frag.offset = offset;
+
+ return page_address(page) + offset;
+}
+
+static void *__netdev_alloc_frag(unsigned int fragsz, gfp_t gfp_mask)
+{
+ unsigned long flags;
+ void *data;
+
+ local_irq_save(flags);
+ data = __alloc_page_frag(&netdev_alloc_cache, fragsz, gfp_mask);
local_irq_restore(flags);
return data;
}
@@ -406,6 +432,17 @@ void *netdev_alloc_frag(unsigned int fragsz)
}
EXPORT_SYMBOL(netdev_alloc_frag);
+static void *__napi_alloc_frag(unsigned int fragsz, gfp_t gfp_mask)
+{
+ return __alloc_page_frag(&napi_alloc_cache, fragsz, gfp_mask);
+}
+
+void *napi_alloc_frag(unsigned int fragsz)
+{
+ return __napi_alloc_frag(fragsz, GFP_ATOMIC | __GFP_COLD);
+}
+EXPORT_SYMBOL(napi_alloc_frag);
+
/**
* __netdev_alloc_skb - allocate an skbuff for rx on a specific device
* @dev: network device to receive on
^ permalink raw reply related
* [net-next PATCH 2/6] net: Pull out core bits of __netdev_alloc_skb and add __napi_alloc_skb
From: Alexander Duyck @ 2014-12-10 3:40 UTC (permalink / raw)
To: netdev; +Cc: ast, davem, eric.dumazet, brouer
In-Reply-To: <20141210033902.2114.68658.stgit@ahduyck-vm-fedora20>
This change pulls the core functionality out of __netdev_alloc_skb and
places them in a new function named __alloc_rx_skb. The reason for doing
this is to make these bits accessible to a new function __napi_alloc_skb.
In addition __alloc_rx_skb now has a new flags value that is used to
determine which page frag pool to allocate from. If the SKB_ALLOC_NAPI
flag is set then the NAPI pool is used. The advantage of this is that we
do not have to use local_irq_save/restore when accessing the NAPI pool from
NAPI context.
In my test setup I saw at least 11ns of savings using the napi_alloc_skb
function versus the netdev_alloc_skb function, most of this being due to
the fact that we didn't have to call local_irq_save/restore.
The main use case for napi_alloc_skb would be for things such as copybreak
or page fragment based receive paths where an skb is allocated after the
data has been received instead of before.
Signed-off-by: Alexander Duyck <alexander.h.duyck@redhat.com>
---
include/linux/skbuff.h | 9 ++++++
net/core/dev.c | 2 +
net/core/skbuff.c | 74 +++++++++++++++++++++++++++++++++++++++++++-----
3 files changed, 77 insertions(+), 8 deletions(-)
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index b2b53b0..af79302 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -151,6 +151,7 @@ struct net_device;
struct scatterlist;
struct pipe_inode_info;
struct iov_iter;
+struct napi_struct;
#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
struct nf_conntrack {
@@ -673,6 +674,7 @@ struct sk_buff {
#define SKB_ALLOC_FCLONE 0x01
#define SKB_ALLOC_RX 0x02
+#define SKB_ALLOC_NAPI 0x04
/* Returns true if the skb was allocated from PFMEMALLOC reserves */
static inline bool skb_pfmemalloc(const struct sk_buff *skb)
@@ -2165,6 +2167,13 @@ static inline struct sk_buff *netdev_alloc_skb_ip_align(struct net_device *dev,
}
void *napi_alloc_frag(unsigned int fragsz);
+struct sk_buff *__napi_alloc_skb(struct napi_struct *napi,
+ unsigned int length, gfp_t gfp_mask);
+static inline struct sk_buff *napi_alloc_skb(struct napi_struct *napi,
+ unsigned int length)
+{
+ return __napi_alloc_skb(napi, length, GFP_ATOMIC);
+}
/**
* __dev_alloc_pages - allocate page for network Rx
diff --git a/net/core/dev.c b/net/core/dev.c
index 3f191da..80f798d 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -4172,7 +4172,7 @@ struct sk_buff *napi_get_frags(struct napi_struct *napi)
struct sk_buff *skb = napi->skb;
if (!skb) {
- skb = netdev_alloc_skb_ip_align(napi->dev, GRO_MAX_HEAD);
+ skb = napi_alloc_skb(napi, GRO_MAX_HEAD);
napi->skb = skb;
}
return skb;
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 56ed17c..ae13ef6 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -444,10 +444,13 @@ void *napi_alloc_frag(unsigned int fragsz)
EXPORT_SYMBOL(napi_alloc_frag);
/**
- * __netdev_alloc_skb - allocate an skbuff for rx on a specific device
- * @dev: network device to receive on
+ * __alloc_rx_skb - allocate an skbuff for rx
* @length: length to allocate
* @gfp_mask: get_free_pages mask, passed to alloc_skb
+ * @flags: If SKB_ALLOC_RX is set, __GFP_MEMALLOC will be used for
+ * allocations in case we have to fallback to __alloc_skb()
+ * If SKB_ALLOC_NAPI is set, page fragment will be allocated
+ * from napi_cache instead of netdev_cache.
*
* Allocate a new &sk_buff and assign it a usage count of one. The
* buffer has unspecified headroom built in. Users should allocate
@@ -456,11 +459,11 @@ EXPORT_SYMBOL(napi_alloc_frag);
*
* %NULL is returned if there is no free memory.
*/
-struct sk_buff *__netdev_alloc_skb(struct net_device *dev,
- unsigned int length, gfp_t gfp_mask)
+static struct sk_buff *__alloc_rx_skb(unsigned int length, gfp_t gfp_mask,
+ int flags)
{
struct sk_buff *skb = NULL;
- unsigned int fragsz = SKB_DATA_ALIGN(length + NET_SKB_PAD) +
+ unsigned int fragsz = SKB_DATA_ALIGN(length) +
SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
if (fragsz <= PAGE_SIZE && !(gfp_mask & (__GFP_WAIT | GFP_DMA))) {
@@ -469,7 +472,9 @@ struct sk_buff *__netdev_alloc_skb(struct net_device *dev,
if (sk_memalloc_socks())
gfp_mask |= __GFP_MEMALLOC;
- data = __netdev_alloc_frag(fragsz, gfp_mask);
+ data = (flags & SKB_ALLOC_NAPI) ?
+ __napi_alloc_frag(fragsz, gfp_mask) :
+ __netdev_alloc_frag(fragsz, gfp_mask);
if (likely(data)) {
skb = build_skb(data, fragsz);
@@ -477,17 +482,72 @@ struct sk_buff *__netdev_alloc_skb(struct net_device *dev,
put_page(virt_to_head_page(data));
}
} else {
- skb = __alloc_skb(length + NET_SKB_PAD, gfp_mask,
+ skb = __alloc_skb(length, gfp_mask,
SKB_ALLOC_RX, NUMA_NO_NODE);
}
+ return skb;
+}
+
+/**
+ * __netdev_alloc_skb - allocate an skbuff for rx on a specific device
+ * @dev: network device to receive on
+ * @length: length to allocate
+ * @gfp_mask: get_free_pages mask, passed to alloc_skb
+ *
+ * Allocate a new &sk_buff and assign it a usage count of one. The
+ * buffer has NET_SKB_PAD headroom built in. Users should allocate
+ * the headroom they think they need without accounting for the
+ * built in space. The built in space is used for optimisations.
+ *
+ * %NULL is returned if there is no free memory.
+ */
+struct sk_buff *__netdev_alloc_skb(struct net_device *dev,
+ unsigned int length, gfp_t gfp_mask)
+{
+ struct sk_buff *skb;
+
+ length += NET_SKB_PAD;
+ skb = __alloc_rx_skb(length, gfp_mask, 0);
+
if (likely(skb)) {
skb_reserve(skb, NET_SKB_PAD);
skb->dev = dev;
}
+
return skb;
}
EXPORT_SYMBOL(__netdev_alloc_skb);
+/**
+ * __napi_alloc_skb - allocate skbuff for rx in a specific NAPI instance
+ * @napi: napi instance this buffer was allocated for
+ * @length: length to allocate
+ * @gfp_mask: get_free_pages mask, passed to alloc_skb and alloc_pages
+ *
+ * Allocate a new sk_buff for use in NAPI receive. This buffer will
+ * attempt to allocate the head from a special reserved region used
+ * only for NAPI Rx allocation. By doing this we can save several
+ * CPU cycles by avoiding having to disable and re-enable IRQs.
+ *
+ * %NULL is returned if there is no free memory.
+ */
+struct sk_buff *__napi_alloc_skb(struct napi_struct *napi,
+ unsigned int length, gfp_t gfp_mask)
+{
+ struct sk_buff *skb;
+
+ length += NET_SKB_PAD + NET_IP_ALIGN;
+ skb = __alloc_rx_skb(length, gfp_mask, SKB_ALLOC_NAPI);
+
+ if (likely(skb)) {
+ skb_reserve(skb, NET_SKB_PAD + NET_IP_ALIGN);
+ skb->dev = napi->dev;
+ }
+
+ return skb;
+}
+EXPORT_SYMBOL(__napi_alloc_skb);
+
void skb_add_rx_frag(struct sk_buff *skb, int i, struct page *page, int off,
int size, unsigned int truesize)
{
^ permalink raw reply related
* [net-next PATCH 3/6] ethernet/intel: Use napi_alloc_skb
From: Alexander Duyck @ 2014-12-10 3:40 UTC (permalink / raw)
To: netdev; +Cc: brouer, ast, Jeff Kirsher, eric.dumazet, davem
In-Reply-To: <20141210033902.2114.68658.stgit@ahduyck-vm-fedora20>
This change replaces calls to netdev_alloc_skb_ip_align with
napi_alloc_skb. The advantage of napi_alloc_skb is currently the fact that
the page allocation doesn't make use of any irq disable calls.
There are few spots where I couldn't replace the calls as the buffer
allocation routine is called as a part of init which is outside of the
softirq context.
Cc: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: Alexander Duyck <alexander.h.duyck@redhat.com>
---
drivers/net/ethernet/intel/e1000/e1000_main.c | 2 +-
drivers/net/ethernet/intel/e1000e/netdev.c | 2 +-
drivers/net/ethernet/intel/fm10k/fm10k_main.c | 4 ++--
drivers/net/ethernet/intel/igb/igb_main.c | 3 +--
drivers/net/ethernet/intel/ixgb/ixgb_main.c | 6 +++---
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 4 ++--
6 files changed, 10 insertions(+), 11 deletions(-)
diff --git a/drivers/net/ethernet/intel/e1000/e1000_main.c b/drivers/net/ethernet/intel/e1000/e1000_main.c
index 862d198..83140cb 100644
--- a/drivers/net/ethernet/intel/e1000/e1000_main.c
+++ b/drivers/net/ethernet/intel/e1000/e1000_main.c
@@ -4100,7 +4100,7 @@ static bool e1000_tbi_should_accept(struct e1000_adapter *adapter,
static struct sk_buff *e1000_alloc_rx_skb(struct e1000_adapter *adapter,
unsigned int bufsz)
{
- struct sk_buff *skb = netdev_alloc_skb_ip_align(adapter->netdev, bufsz);
+ struct sk_buff *skb = napi_alloc_skb(&adapter->napi, bufsz);
if (unlikely(!skb))
adapter->alloc_rx_buff_failed++;
diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c
index 88936aa..5c82c80 100644
--- a/drivers/net/ethernet/intel/e1000e/netdev.c
+++ b/drivers/net/ethernet/intel/e1000e/netdev.c
@@ -1016,7 +1016,7 @@ static bool e1000_clean_rx_irq(struct e1000_ring *rx_ring, int *work_done,
*/
if (length < copybreak) {
struct sk_buff *new_skb =
- netdev_alloc_skb_ip_align(netdev, length);
+ napi_alloc_skb(&adapter->napi, length);
if (new_skb) {
skb_copy_to_linear_data_offset(new_skb,
-NET_IP_ALIGN,
diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_main.c b/drivers/net/ethernet/intel/fm10k/fm10k_main.c
index f0d9d6c..3418665 100644
--- a/drivers/net/ethernet/intel/fm10k/fm10k_main.c
+++ b/drivers/net/ethernet/intel/fm10k/fm10k_main.c
@@ -308,8 +308,8 @@ static struct sk_buff *fm10k_fetch_rx_buffer(struct fm10k_ring *rx_ring,
#endif
/* allocate a skb to store the frags */
- skb = netdev_alloc_skb_ip_align(rx_ring->netdev,
- FM10K_RX_HDR_LEN);
+ skb = napi_alloc_skb(&rx_ring->q_vector->napi,
+ FM10K_RX_HDR_LEN);
if (unlikely(!skb)) {
rx_ring->rx_stats.alloc_failed++;
return NULL;
diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
index bfd60577..675a330 100644
--- a/drivers/net/ethernet/intel/igb/igb_main.c
+++ b/drivers/net/ethernet/intel/igb/igb_main.c
@@ -6641,8 +6641,7 @@ static struct sk_buff *igb_fetch_rx_buffer(struct igb_ring *rx_ring,
#endif
/* allocate a skb to store the frags */
- skb = netdev_alloc_skb_ip_align(rx_ring->netdev,
- IGB_RX_HDR_LEN);
+ skb = napi_alloc_skb(&rx_ring->q_vector->napi, IGB_RX_HDR_LEN);
if (unlikely(!skb)) {
rx_ring->rx_stats.alloc_failed++;
return NULL;
diff --git a/drivers/net/ethernet/intel/ixgb/ixgb_main.c b/drivers/net/ethernet/intel/ixgb/ixgb_main.c
index 055961b..aa87605 100644
--- a/drivers/net/ethernet/intel/ixgb/ixgb_main.c
+++ b/drivers/net/ethernet/intel/ixgb/ixgb_main.c
@@ -1963,7 +1963,7 @@ ixgb_rx_checksum(struct ixgb_adapter *adapter,
* this should improve performance for small packets with large amounts
* of reassembly being done in the stack
*/
-static void ixgb_check_copybreak(struct net_device *netdev,
+static void ixgb_check_copybreak(struct napi_struct *napi,
struct ixgb_buffer *buffer_info,
u32 length, struct sk_buff **skb)
{
@@ -1972,7 +1972,7 @@ static void ixgb_check_copybreak(struct net_device *netdev,
if (length > copybreak)
return;
- new_skb = netdev_alloc_skb_ip_align(netdev, length);
+ new_skb = napi_alloc_skb(napi, length);
if (!new_skb)
return;
@@ -2064,7 +2064,7 @@ ixgb_clean_rx_irq(struct ixgb_adapter *adapter, int *work_done, int work_to_do)
goto rxdesc_done;
}
- ixgb_check_copybreak(netdev, buffer_info, length, &skb);
+ ixgb_check_copybreak(&adapter->napi, buffer_info, length, &skb);
/* Good Receive */
skb_put(skb, length);
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index 94feddf..d75d01b 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -1909,8 +1909,8 @@ static struct sk_buff *ixgbe_fetch_rx_buffer(struct ixgbe_ring *rx_ring,
#endif
/* allocate a skb to store the frags */
- skb = netdev_alloc_skb_ip_align(rx_ring->netdev,
- IXGBE_RX_HDR_SIZE);
+ skb = napi_alloc_skb(&rx_ring->q_vector->napi,
+ IXGBE_RX_HDR_SIZE);
if (unlikely(!skb)) {
rx_ring->rx_stats.alloc_rx_buff_failed++;
return NULL;
^ permalink raw reply related
* [net-next PATCH 4/6] cxgb: Use napi_alloc_skb instead of netdev_alloc_skb_ip_align
From: Alexander Duyck @ 2014-12-10 3:41 UTC (permalink / raw)
To: netdev; +Cc: ast, davem, eric.dumazet, brouer
In-Reply-To: <20141210033902.2114.68658.stgit@ahduyck-vm-fedora20>
In order to use napi_alloc_skb I needed to pass a pointer to struct adapter
instead of struct pci_dev. This allowed me to access &adapter->napi.
Signed-off-by: Alexander Duyck <alexander.h.duyck@redhat.com>
---
drivers/net/ethernet/chelsio/cxgb/sge.c | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/chelsio/cxgb/sge.c b/drivers/net/ethernet/chelsio/cxgb/sge.c
index 86222a1..babe2a9 100644
--- a/drivers/net/ethernet/chelsio/cxgb/sge.c
+++ b/drivers/net/ethernet/chelsio/cxgb/sge.c
@@ -1025,7 +1025,7 @@ MODULE_PARM_DESC(copybreak, "Receive copy threshold");
/**
* get_packet - return the next ingress packet buffer
- * @pdev: the PCI device that received the packet
+ * @adapter: the adapter that received the packet
* @fl: the SGE free list holding the packet
* @len: the actual packet length, excluding any SGE padding
*
@@ -1037,14 +1037,15 @@ MODULE_PARM_DESC(copybreak, "Receive copy threshold");
* threshold and the packet is too big to copy, or (b) the packet should
* be copied but there is no memory for the copy.
*/
-static inline struct sk_buff *get_packet(struct pci_dev *pdev,
+static inline struct sk_buff *get_packet(struct adapter *adapter,
struct freelQ *fl, unsigned int len)
{
- struct sk_buff *skb;
const struct freelQ_ce *ce = &fl->centries[fl->cidx];
+ struct pci_dev *pdev = adapter->pdev;
+ struct sk_buff *skb;
if (len < copybreak) {
- skb = netdev_alloc_skb_ip_align(NULL, len);
+ skb = napi_alloc_skb(&adapter->napi, len);
if (!skb)
goto use_orig_buf;
@@ -1357,7 +1358,7 @@ static void sge_rx(struct sge *sge, struct freelQ *fl, unsigned int len)
struct sge_port_stats *st;
struct net_device *dev;
- skb = get_packet(adapter->pdev, fl, len - sge->rx_pkt_pad);
+ skb = get_packet(adapter, fl, len - sge->rx_pkt_pad);
if (unlikely(!skb)) {
sge->stats.rx_drops++;
return;
^ 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