set larger than the MTU, then all packets smaller than the chunk size
     of the VMBus send buffer will be copied; larger packets always have to
     go as a single direct request. The default value is 512 (bytes).
+
+#.  ``rx_extmbuf_enable``:
+    The rx_extmbuf_enable is used to control if netvsc should use external
+    mbuf for receiving packets. The default value is 0. (netvsc doesn't use
+    external mbuf, it always allocates mbuf and copy received data to mbuf)
+    A non-zero value tells netvsc to attach external buffers to mbuf on
+    receiving packets, thus avoid copying memory. Use of external buffers
+    requires the application is able to read data from external mbuf.
 
 #define NETVSC_ARG_LATENCY "latency"
 #define NETVSC_ARG_RXBREAK "rx_copybreak"
 #define NETVSC_ARG_TXBREAK "tx_copybreak"
+#define NETVSC_ARG_RX_EXTMBUF_ENABLE "rx_extmbuf_enable"
 
 struct hn_xstats_name_off {
        char name[RTE_ETH_XSTATS_NAME_SIZE];
                hv->tx_copybreak = v;
                PMD_DRV_LOG(DEBUG, "tx copy break set to %u",
                            hv->tx_copybreak);
+       } else if (!strcmp(key, NETVSC_ARG_RX_EXTMBUF_ENABLE)) {
+               hv->rx_extmbuf_enable = v;
+               PMD_DRV_LOG(DEBUG, "rx extmbuf enable set to %u",
+                           hv->rx_extmbuf_enable);
        }
 
        return 0;
                NETVSC_ARG_LATENCY,
                NETVSC_ARG_RXBREAK,
                NETVSC_ARG_TXBREAK,
+               NETVSC_ARG_RX_EXTMBUF_ENABLE,
                NULL
        };
        struct rte_kvargs *kvlist;
        hv->latency = HN_CHAN_LATENCY_NS;
        hv->rx_copybreak = HN_RXCOPY_THRESHOLD;
        hv->tx_copybreak = HN_TXCOPY_THRESHOLD;
+       hv->rx_extmbuf_enable = HN_RX_EXTMBUF_ENABLE;
        hv->max_queues = 1;
 
        rte_rwlock_init(&hv->vf_lock);
 RTE_PMD_REGISTER_PARAM_STRING(net_netvsc,
                              NETVSC_ARG_LATENCY "=<uint32> "
                              NETVSC_ARG_RXBREAK "=<uint32> "
-                             NETVSC_ARG_TXBREAK "=<uint32>");
+                             NETVSC_ARG_TXBREAK "=<uint32> "
+                             NETVSC_ARG_RX_EXTMBUF_ENABLE "=<0|1>");
 
         * For large packets, avoid copy if possible but need to keep
         * some space available in receive area for later packets.
         */
-       if (dlen > hv->rx_copybreak &&
+       if (hv->rx_extmbuf_enable && dlen > hv->rx_copybreak &&
            (uint32_t)rte_atomic32_read(&rxq->rxbuf_outstanding) <
                        hv->rxbuf_section_cnt / 2) {
                struct rte_mbuf_ext_shared_info *shinfo;
 
 #define HN_TXCOPY_THRESHOLD    512
 #define HN_RXCOPY_THRESHOLD    256
 
+#define HN_RX_EXTMBUF_ENABLE   0
+
 /* Buffers need to be aligned */
 #ifndef PAGE_SIZE
 #define PAGE_SIZE 4096
        struct rte_mem_resource *rxbuf_res;     /* UIO resource for Rx */
        uint32_t        rxbuf_section_cnt;      /* # of Rx sections */
        uint32_t        rx_copybreak;
+       uint32_t        rx_extmbuf_enable;
        uint16_t        max_queues;             /* Max available queues */
        uint16_t        num_queues;
        uint64_t        rss_offloads;