Commit 27186dc3 authored by Divy Le Ray's avatar Divy Le Ray Committed by David S. Miller

cxgb3 - use immediate data for offload Tx

Send small TX_DATA work requests as immediate data even when
there are fragments. this avoids doing multiple DMAs for
small fragmented packets.
The driver already implements this optimization for small
contiguous packets.
Signed-off-by: default avatarDivy Le Ray <divy@chelsio.com>
Signed-off-by: default avatarJeff Garzik <jeff@garzik.org>
parent 6e3f03b7
...@@ -1179,8 +1179,8 @@ int t3_eth_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -1179,8 +1179,8 @@ int t3_eth_xmit(struct sk_buff *skb, struct net_device *dev)
* *
* Writes a packet as immediate data into a Tx descriptor. The packet * Writes a packet as immediate data into a Tx descriptor. The packet
* contains a work request at its beginning. We must write the packet * contains a work request at its beginning. We must write the packet
* carefully so the SGE doesn't read accidentally before it's written in * carefully so the SGE doesn't read it accidentally before it's written
* its entirety. * in its entirety.
*/ */
static inline void write_imm(struct tx_desc *d, struct sk_buff *skb, static inline void write_imm(struct tx_desc *d, struct sk_buff *skb,
unsigned int len, unsigned int gen) unsigned int len, unsigned int gen)
...@@ -1188,7 +1188,11 @@ static inline void write_imm(struct tx_desc *d, struct sk_buff *skb, ...@@ -1188,7 +1188,11 @@ static inline void write_imm(struct tx_desc *d, struct sk_buff *skb,
struct work_request_hdr *from = (struct work_request_hdr *)skb->data; struct work_request_hdr *from = (struct work_request_hdr *)skb->data;
struct work_request_hdr *to = (struct work_request_hdr *)d; struct work_request_hdr *to = (struct work_request_hdr *)d;
memcpy(&to[1], &from[1], len - sizeof(*from)); if (likely(!skb->data_len))
memcpy(&to[1], &from[1], len - sizeof(*from));
else
skb_copy_bits(skb, sizeof(*from), &to[1], len - sizeof(*from));
to->wr_hi = from->wr_hi | htonl(F_WR_SOP | F_WR_EOP | to->wr_hi = from->wr_hi | htonl(F_WR_SOP | F_WR_EOP |
V_WR_BCNTLFLT(len & 7)); V_WR_BCNTLFLT(len & 7));
wmb(); wmb();
...@@ -1258,7 +1262,7 @@ static inline void reclaim_completed_tx_imm(struct sge_txq *q) ...@@ -1258,7 +1262,7 @@ static inline void reclaim_completed_tx_imm(struct sge_txq *q)
static inline int immediate(const struct sk_buff *skb) static inline int immediate(const struct sk_buff *skb)
{ {
return skb->len <= WR_LEN && !skb->data_len; return skb->len <= WR_LEN;
} }
/** /**
...@@ -1464,12 +1468,13 @@ static void write_ofld_wr(struct adapter *adap, struct sk_buff *skb, ...@@ -1464,12 +1468,13 @@ static void write_ofld_wr(struct adapter *adap, struct sk_buff *skb,
*/ */
static inline unsigned int calc_tx_descs_ofld(const struct sk_buff *skb) static inline unsigned int calc_tx_descs_ofld(const struct sk_buff *skb)
{ {
unsigned int flits, cnt = skb_shinfo(skb)->nr_frags; unsigned int flits, cnt;
if (skb->len <= WR_LEN && cnt == 0) if (skb->len <= WR_LEN)
return 1; /* packet fits as immediate data */ return 1; /* packet fits as immediate data */
flits = skb_transport_offset(skb) / 8; /* headers */ flits = skb_transport_offset(skb) / 8; /* headers */
cnt = skb_shinfo(skb)->nr_frags;
if (skb->tail != skb->transport_header) if (skb->tail != skb->transport_header)
cnt++; cnt++;
return flits_to_desc(flits + sgl_len(cnt)); return flits_to_desc(flits + sgl_len(cnt));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment