OSDN Git Service

net: hns3: avoid mult + div op in critical data path
authorYunsheng Lin <linyunsheng@huawei.com>
Sat, 23 Feb 2019 09:22:09 +0000 (17:22 +0800)
committerDavid S. Miller <davem@davemloft.net>
Mon, 25 Feb 2019 04:27:50 +0000 (20:27 -0800)
This patch uses shift offset to avoid doing mult and div operation.

Signed-off-by: Yunsheng Lin <linyunsheng@huawei.com>
Signed-off-by: Huazhong Tan <tanhuazhong@huawei.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
drivers/net/ethernet/hisilicon/hns3/hns3_enet.h

index d75977c..14c3aa7 100644 (file)
@@ -658,7 +658,7 @@ static int hns3_set_tso(struct sk_buff *skb, u32 *paylen,
 
        /* normal or tunnel packet*/
        l4_offset = l4.hdr - skb->data;
-       hdr_len = (l4.tcp->doff * 4) + l4_offset;
+       hdr_len = (l4.tcp->doff << 2) + l4_offset;
 
        /* remove payload length from inner pseudo checksum when tso*/
        l4_paylen = skb->len - l4_offset;
@@ -1100,8 +1100,8 @@ static int hns3_fill_desc(struct hns3_enet_ring *ring, void *priv,
 
        desc_cb->length = size;
 
-       frag_buf_num = (size + HNS3_MAX_BD_SIZE - 1) / HNS3_MAX_BD_SIZE;
-       sizeoflast = size % HNS3_MAX_BD_SIZE;
+       frag_buf_num = (size + HNS3_MAX_BD_SIZE - 1) >> HNS3_MAX_BD_SIZE_OFFSET;
+       sizeoflast = size & HNS3_TX_LAST_SIZE_M;
        sizeoflast = sizeoflast ? sizeoflast : HNS3_MAX_BD_SIZE;
 
        /* When frag size is bigger than hardware limit, split this frag */
@@ -1145,14 +1145,14 @@ static int hns3_nic_maybe_stop_tso(struct sk_buff **out_skb, int *bnum,
        int i;
 
        size = skb_headlen(skb);
-       buf_num = (size + HNS3_MAX_BD_SIZE - 1) / HNS3_MAX_BD_SIZE;
+       buf_num = (size + HNS3_MAX_BD_SIZE - 1) >> HNS3_MAX_BD_SIZE_OFFSET;
 
        frag_num = skb_shinfo(skb)->nr_frags;
        for (i = 0; i < frag_num; i++) {
                frag = &skb_shinfo(skb)->frags[i];
                size = skb_frag_size(frag);
-               bdnum_for_frag =
-                       (size + HNS3_MAX_BD_SIZE - 1) / HNS3_MAX_BD_SIZE;
+               bdnum_for_frag = (size + HNS3_MAX_BD_SIZE - 1) >>
+                                HNS3_MAX_BD_SIZE_OFFSET;
                if (bdnum_for_frag > HNS3_MAX_BD_PER_FRAG)
                        return -ENOMEM;
 
@@ -1160,7 +1160,8 @@ static int hns3_nic_maybe_stop_tso(struct sk_buff **out_skb, int *bnum,
        }
 
        if (unlikely(buf_num > HNS3_MAX_BD_PER_FRAG)) {
-               buf_num = (skb->len + HNS3_MAX_BD_SIZE - 1) / HNS3_MAX_BD_SIZE;
+               buf_num = (skb->len + HNS3_MAX_BD_SIZE - 1) >>
+                         HNS3_MAX_BD_SIZE_OFFSET;
                if (ring_space(ring) < buf_num)
                        return -EBUSY;
                /* manual split the send packet */
index 71ff8f4..5c41465 100644 (file)
@@ -184,6 +184,8 @@ enum hns3_nic_state {
 #define HNS3_TXD_MSS_S                         0
 #define HNS3_TXD_MSS_M                         (0x3fff << HNS3_TXD_MSS_S)
 
+#define HNS3_TX_LAST_SIZE_M                    0xffff
+
 #define HNS3_VECTOR_TX_IRQ                     BIT_ULL(0)
 #define HNS3_VECTOR_RX_IRQ                     BIT_ULL(1)
 
@@ -191,6 +193,7 @@ enum hns3_nic_state {
 #define HNS3_VECTOR_INITED                     1
 
 #define HNS3_MAX_BD_SIZE                       65535
+#define HNS3_MAX_BD_SIZE_OFFSET                16
 #define HNS3_MAX_BD_PER_FRAG                   8
 #define HNS3_MAX_BD_PER_PKT                    MAX_SKB_FRAGS