Message ID | 1508261816-3145-2-git-send-email-tlfalcon@linux.vnet.ibm.com |
---|---|
State | Accepted, archived |
Delegated to: | David Miller |
Headers | show |
Series | ibmvnic: Enable SG and TSO feature support | expand |
From: Thomas Falcon > Sent: 17 October 2017 18:37 > This patch enables scatter gather support. Since there is no > HW/FW scatter-gather support at this time, the driver needs to > loop through each fragment and copy it to a contiguous, pre-mapped > buffer entry. ... > offset = index * adapter->req_mtu; > dst = tx_pool->long_term_buff.buff + offset; You should be able to treat the pre-allocated data area as a big ring buffer. So it can hold a lot of small frames or a few big ones. This slightly complicates the 'is there enough space for this packet' check since you need buffer space as well as a ring entry. You also really want to align each tx buffer on a 4n+2 boundary so that most of the copy is aligned. > memset(dst, 0, adapter->req_mtu); Seems unnecessary. David
On 10/18/2017 06:04 AM, David Laight wrote: > From: Thomas Falcon >> Sent: 17 October 2017 18:37 >> This patch enables scatter gather support. Since there is no >> HW/FW scatter-gather support at this time, the driver needs to >> loop through each fragment and copy it to a contiguous, pre-mapped >> buffer entry. > ... >> offset = index * adapter->req_mtu; >> dst = tx_pool->long_term_buff.buff + offset; > You should be able to treat the pre-allocated data area as a > big ring buffer. > So it can hold a lot of small frames or a few big ones. > This slightly complicates the 'is there enough space for > this packet' check since you need buffer space as well > as a ring entry. > > You also really want to align each tx buffer on a 4n+2 > boundary so that most of the copy is aligned. Thanks for your comments. I'll try to address that in a future patch. > >> memset(dst, 0, adapter->req_mtu); > Seems unnecessary. I removed that bit, and so far you seem to be right :) . Thanks, Tom > > David >
From: Thomas Falcon > Sent: 26 October 2017 18:52 ... > >> memset(dst, 0, adapter->req_mtu); > > Seems unnecessary. > > I removed that bit, and so far you seem to be right :) . I'd check that short frames are padded with zeros. David
diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c index 4bc14a9..b508877 100644 --- a/drivers/net/ethernet/ibm/ibmvnic.c +++ b/drivers/net/ethernet/ibm/ibmvnic.c @@ -1204,9 +1204,28 @@ static int ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev) offset = index * adapter->req_mtu; dst = tx_pool->long_term_buff.buff + offset; memset(dst, 0, adapter->req_mtu); - skb_copy_from_linear_data(skb, dst, skb->len); data_dma_addr = tx_pool->long_term_buff.addr + offset; + if (skb_shinfo(skb)->nr_frags) { + int cur, i; + + /* Copy the head */ + skb_copy_from_linear_data(skb, dst, skb_headlen(skb)); + cur = skb_headlen(skb); + + /* Copy the frags */ + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { + const skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; + + memcpy(dst + cur, + page_address(skb_frag_page(frag)) + + frag->page_offset, skb_frag_size(frag)); + cur += skb_frag_size(frag); + } + } else { + skb_copy_from_linear_data(skb, dst, skb->len); + } + tx_pool->consumer_index = (tx_pool->consumer_index + 1) % adapter->req_tx_entries_per_subcrq; @@ -2948,7 +2967,7 @@ static void handle_query_ip_offload_rsp(struct ibmvnic_adapter *adapter) adapter->ip_offload_ctrl.large_rx_ipv4 = 0; adapter->ip_offload_ctrl.large_rx_ipv6 = 0; - adapter->netdev->features = NETIF_F_GSO; + adapter->netdev->features = NETIF_F_SG | NETIF_F_GSO; if (buf->tcp_ipv4_chksum || buf->udp_ipv4_chksum) adapter->netdev->features |= NETIF_F_IP_CSUM;
This patch enables scatter gather support. Since there is no HW/FW scatter-gather support at this time, the driver needs to loop through each fragment and copy it to a contiguous, pre-mapped buffer entry. Signed-off-by: Thomas Falcon <tlfalcon@linux.vnet.ibm.com> --- drivers/net/ethernet/ibm/ibmvnic.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-)