From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from smtp3.iitd.ac.in (smtp3.iitd.ac.in [103.27.11.44]) by dpdk.org (Postfix) with ESMTP id 267A87CBE for ; Wed, 18 Apr 2018 18:44:16 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by smtp3.iitd.ac.in (Postfix) with ESMTP id 0DDAA4001F for ; Wed, 18 Apr 2018 22:14:15 +0530 (IST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=iitd.ac.in; h= content-language:content-type:content-type:mime-version :user-agent:date:date:message-id:subject:subject:from:from :received:received; s=iitd; t=1524069850; x=1525884251; bh=ynNKT 4VXxUYaXE5Ux1BUKjQi4JMJV+Ql5As/UNoYJaY=; b=F9LISVBux8uFV/xwtp7Us ngEpzG3s1+kliB0ln9yzFDNO/Xag4B3Rrma+ORThpdcBjJmi5yOoRGm4jSLRzmeJ DZ4JP9Vnisa9k+JFieOZNYsGwgYAnQ2NlWCavuTDqxyPSAWlto0OqAJGWAzUszUS BLkm4zCEDhMPeQWmPYwcGU= X-Virus-Scanned: Debian amavisd-new at smtp2.iitd.ernet.in Received: from smtp3.iitd.ac.in ([127.0.0.1]) by localhost (smtp3.iitd.ac.in [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id 3SXFohuvw5wd for ; Wed, 18 Apr 2018 22:14:10 +0530 (IST) Received: from [10.207.164.111] (unknown [10.207.164.111]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: csz168117) by smtp3.iitd.ac.in (Postfix) with ESMTPSA id 7FDC940021 for ; Wed, 18 Apr 2018 22:14:10 +0530 (IST) To: dev@dpdk.org From: Shailja Pandey Message-ID: <598ada8c-194d-e07e-6121-5dc74cf208a1@iitd.ac.in> Date: Wed, 18 Apr 2018 22:13:17 +0530 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.3.0 MIME-Version: 1.0 Content-Language: en-US Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: quoted-printable X-Content-Filtered-By: Mailman/MimeDel 2.1.15 Subject: [dpdk-dev] Why packet replication is more efficient when done using memcpy( ) as compared to rte_mbuf_refcnt_update() function? X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 18 Apr 2018 16:44:16 -0000 Hello, I am doing packet replication and I=C2=A0need to change the ethernet and = IP=20 header field for each replicated packet. I did it in two different ways: 1. Share payload from the original packet using rte_mbuf_refcnt_update and allocate new mbuf for L2-L4 headers. 2. memcpy() payload from the original packet to newly created mbuf and prepend L2-L4 headers to the mbuf. I performed experiments with varying replication factor as well as=20 varying packet size and found that memcpy() is performing way better=20 than using=C2=A0rte_mbuf_refcnt_update(). But I am not sure why it is=20 happening and what is making=C2=A0rte_mbuf_refcnt_update() even worse tha= n=20 memcpy(). Here is the sample code for both implementations: *1. Using=C2=A0rte_mbuf_refcnt_update:* **struct rte_mbuf *pkt =3D original packet;** ** ******rte_pktmbuf_adj(pkt, (uint16_t)sizeof(struct=20 ether_hdr)+sizeof(struct ipv4_hdr)); =C2=A0 =C2=A0 =C2=A0 =C2=A0=C2=A0rte_pktmbuf_refcnt_update(pkt, replicat= ion_factor); =C2=A0 =C2=A0 =C2=A0 =C2=A0 for(int i =3D 0; i < replication_factor; i++= ) { =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 struct rte_mbuf *hdr; =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if (unlikely ((hdr =3D = rte_pktmbuf_alloc(header_pool)) =3D=3D=20 NULL)) { =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 printf("Failed w= hile cloning $$$\n"); =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return NULL; =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0} =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0hdr->next =3D pkt; =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0hdr->pkt_len =3D (uint16_t)(hdr= ->data_len + pkt->pkt_len); =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0hdr->nb_segs =3D (uint8_t)(pkt-= >nb_segs + 1); =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0//*Update more metadate fields* * * **rte_pktmbuf_prepend(hdr, (uint16_t)sizeof(struct ether_hdr)); =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 //*modify L2 fields* =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=C2=A0rte_pktmbuf_prepend(hdr, = (uint16_t)sizeof(struct ipv4_hdr)); =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 //Modify L3 fields =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 . =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 . =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 . =C2=A0 =C2=A0 =C2=A0 =C2=A0 } * * * * *2. Using memcpy():* **struct rte_mbuf *pkt =3D original packet **struct rte_mbuf *hdr;** =C2=A0 =C2=A0 =C2=A0 =C2=A0 if (unlikely ((hdr =3D rte_pktmbuf_alloc(hea= der_pool)) =3D=3D NULL)) { =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 printf("Failed w= hile cloning $$$\n"); =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return NULL; =C2=A0 =C2=A0 =C2=A0 =C2=A0 } =C2=A0 =C2=A0 =C2=A0 =C2=A0 /* prepend new header */ =C2=A0 =C2=A0 =C2=A0 =C2=A0 char *eth_hdr =3D (char *)rte_pktmbuf_prepen= d(hdr, pkt->pkt_len); =C2=A0 =C2=A0 =C2=A0 =C2=A0 if(eth_hdr =3D=3D NULL) { =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 printf("panic\n"= ); =C2=A0 =C2=A0 =C2=A0 =C2=A0 } =C2=A0 =C2=A0 =C2=A0 =C2=A0 char *b =3D rte_pktmbuf_mtod((struct rte_mbu= f*)pkt, char *); =C2=A0 =C2=A0 =C2=A0 =C2=A0 memcpy(eth_hdr, b, pkt->pkt_len); =C2=A0 =C2=A0 =C2=A0 =C2=A0 Change L2-L4 header fields in new packet The throughput becomes roughly half when the packet size is increased=20 from 64 bytes to 128 bytes and replication is done using=20 *rte_mbuf_refcnt_update(). *The throughput remains more or less same=20 when packet size increases and replication is done using *memcpy()*. Any help would be appreciated. ** -- Thanks, Shailja