On Wed, Feb 11, 2015 at 09:31:35AM +0800, Chen Jing D(Mark) wrote: > > +uint16_t > +fm10k_recv_scattered_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, > + uint16_t nb_pkts) > +{ > + struct rte_mbuf *mbuf; > + union fm10k_rx_desc desc; > + struct fm10k_rx_queue *q = rx_queue; > + uint16_t count = 0; > + uint16_t nb_rcv, nb_seg; > + int alloc = 0; > + uint16_t next_dd; > + struct rte_mbuf *first_seg = q->pkt_first_seg; > + struct rte_mbuf *last_seg = q->pkt_last_seg; > + > + next_dd = q->next_dd; > + nb_rcv = 0; > + > + nb_seg = RTE_MIN(nb_pkts, q->alloc_thresh); > + for (count = 0; count < nb_seg; count++) { > + mbuf = q->sw_ring[next_dd]; > + desc = q->hw_ring[next_dd]; > + if (!(desc.d.staterr & FM10K_RXD_STATUS_DD)) > + break; > +#ifdef RTE_LIBRTE_FM10K_DEBUG_RX > + dump_rxd(&desc); > +#endif > + > + if (++next_dd == q->nb_desc) { > + next_dd = 0; > + alloc = 1; > + } > + > + /* Prefetch next mbuf while processing current one. */ > + rte_prefetch0(q->sw_ring[next_dd]); > + > + /* > + * When next RX descriptor is on a cache-line boundary, > + * prefetch the next 4 RX descriptors and the next 8 pointers > + * to mbufs. > + */ > + if ((next_dd & 0x3) == 0) { > + rte_prefetch0(&q->hw_ring[next_dd]); > + rte_prefetch0(&q->sw_ring[next_dd]); > + } > + > + /* Fill data length */ > + rte_pktmbuf_data_len(mbuf) = desc.w.length; > + > + /* > + * If this is the first buffer of the received packet, > + * set the pointer to the first mbuf of the packet and > + * initialize its context. > + * Otherwise, update the total length and the number of segments > + * of the current scattered packet, and update the pointer to > + * the last mbuf of the current packet. > + */ > + if (!first_seg) { > + first_seg = mbuf; > + first_seg->pkt_len = desc.w.length; > + } else { > + first_seg->pkt_len = > + (uint16_t)(first_seg->pkt_len + > + rte_pktmbuf_data_len(mbuf)); > + first_seg->nb_segs++; > + last_seg->next = mbuf; > + } > + > + /* > + * If this is not the last buffer of the received packet, > + * update the pointer to the last mbuf of the current scattered > + * packet and continue to parse the RX ring. > + */ > + if (!(desc.d.staterr & FM10K_RXD_STATUS_EOP)) { > + last_seg = mbuf; > + continue; > + } > + > + first_seg->ol_flags = 0; > +#ifdef RTE_LIBRTE_FM10K_RX_OLFLAGS_ENABLE > + rx_desc_to_ol_flags(first_seg, &desc); > +#endif > + first_seg->hash.rss = desc.d.rss; > + > + /* Prefetch data of first segment, if configured to do so. */ > + rte_packet_prefetch((char *)first_seg->buf_addr + > + first_seg->data_off); > + > + /* > + * Store the mbuf address into the next entry of the array > + * of returned packets. > + */ > + rx_pkts[nb_rcv++] = first_seg; > + > + /* > + * Setup receipt context for a new packet. > + */ > + first_seg = NULL; > + } > + > + q->next_dd = next_dd; > + q->pkt_first_seg = first_seg; > + q->pkt_last_seg = last_seg; > + > + if ((q->next_dd > q->next_trigger) || (alloc == 1)) { > + rte_mempool_get_bulk(q->mp, (void **)&q->sw_ring[q->next_alloc], > + q->alloc_thresh);
Same thing here. The return value should be checked in case the mempool runs out of buffers. > + for (; q->next_alloc <= q->next_trigger; ++q->next_alloc) { > + mbuf = q->sw_ring[q->next_alloc]; > + > + /* setup static mbuf fields */ > + fm10k_pktmbuf_reset(mbuf, q->port_id); > + > + /* write descriptor */ > + desc.q.pkt_addr = MBUF_DMA_ADDR_DEFAULT(mbuf); > + desc.q.hdr_addr = MBUF_DMA_ADDR_DEFAULT(mbuf); > + q->hw_ring[q->next_alloc] = desc; > + } > + FM10K_PCI_REG_WRITE(q->tail_ptr, q->next_trigger); > + q->next_trigger += q->alloc_thresh; > + if (q->next_trigger >= q->nb_desc) { > + q->next_trigger = q->alloc_thresh - 1; > + q->next_alloc = 0; > + } > + } > + > + return nb_rcv; > +} > +