|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [UNIKRAFT PATCH v4 11/12] plat/xen/drivers/net: Add receive operation
On 10/22/20 4:40 PM, Sharan Santhanam wrote:
> Hello Costin,
>
> Please find the review comment inline:
>
> Thanks & Regards
> Sharan
>
> On 8/13/20 10:53 AM, Costin Lupu wrote:
>> Incoming packets are written in pages allocated by the netfront. Such
>> pages are
>> allocated and registered to the shared ring after completion of receiving
>> operations.
>>
>> Signed-off-by: Costin Lupu <costin.lupu@xxxxxxxxx>
>> Signed-off-by: Razvan Cojocaru <razvan.cojocaru93@xxxxxxxxx>
>> ---
>> plat/xen/drivers/net/netfront.c | 100 ++++++++++++++++++++++++++++++++
>> 1 file changed, 100 insertions(+)
>>
>> diff --git a/plat/xen/drivers/net/netfront.c
>> b/plat/xen/drivers/net/netfront.c
>> index f2b81329..101e38c8 100644
>> --- a/plat/xen/drivers/net/netfront.c
>> +++ b/plat/xen/drivers/net/netfront.c
>> @@ -221,6 +221,49 @@ static int netfront_rxq_enqueue(struct
>> uk_netdev_rx_queue *rxq,
>> return 0;
>> }
>> +static int netfront_rxq_dequeue(struct uk_netdev_rx_queue *rxq,
>> + struct uk_netbuf **netbuf)
>> +{
>> + RING_IDX prod, cons;
>> + netif_rx_response_t *rx_rsp;
>> + uint16_t len, id;
>> + struct uk_netbuf *buf = NULL;
>> + int count = 0;
>> +
>> + UK_ASSERT(rxq != NULL);
>> + UK_ASSERT(netbuf != NULL);
>> +
>> + prod = rxq->ring.sring->rsp_prod;
>> + rmb(); /* Ensure we see queued responses up to 'rp'. */
>> + cons = rxq->ring.rsp_cons;
>> + /* No new descriptor since last dequeue operation */
>> + if (cons == prod)
>
> We should set it here:
>
> *netbuf = NULL;
>
ACK.
>> + goto out;
>> +
>> + /* get response */
>> + rx_rsp = RING_GET_RESPONSE(&rxq->ring, cons);
>> + UK_ASSERT(rx_rsp->status > NETIF_RSP_NULL);
>> + id = rx_rsp->id;
>> + UK_ASSERT(id < NET_RX_RING_SIZE);
>> +
>> + /* remove grant for buffer data */
>> + gnttab_end_access(rxq->gref[id]);
>> +
>> + buf = rxq->netbuf[id];
>> + len = (uint16_t) rx_rsp->status;
>> + if (len > ETH_PKT_LEN)
>> + len = ETH_PKT_LEN;
>> + buf->len = len;
>> +
>> + *netbuf = buf;
>> +
>> + rxq->ring.rsp_cons++;
>> + count = 1;
>> +
>> +out:
>> + return count;
>> +}
>> +
>> static int netfront_rx_fillup(struct uk_netdev_rx_queue *rxq,
>> uint16_t nb_desc)
>> {
>> struct uk_netbuf *netbuf[nb_desc];
>> @@ -271,6 +314,62 @@ static int netfront_rxq_intr_enable(struct
>> uk_netdev_rx_queue *rxq)
>> return (more > 0);
>> }
>> +static int netfront_recv(struct uk_netdev *n,
>> + struct uk_netdev_rx_queue *rxq,
>> + struct uk_netbuf **pkt)
>> +{
>> + int rc, status = 0;
>> +
>> + UK_ASSERT(n != NULL);
>> + UK_ASSERT(rxq != NULL);
>> + UK_ASSERT(pkt != NULL);
>> +
>> + /* Queue interrupts have to be off when calling receive */
>> + UK_ASSERT(!(rxq->intr_enabled & NETFRONT_INTR_EN));
>> +
>> + rc = netfront_rxq_dequeue(rxq, pkt);
>> + UK_ASSERT(rc >= 0);
>> +
>> + status |= (*pkt) ? UK_NETDEV_STATUS_SUCCESS : 0x0;
>> + status |= netfront_rx_fillup(rxq, rc);
>> +
>> + /* Enable interrupt only when user had previously enabled it */
>> + if (rxq->intr_enabled & NETFRONT_INTR_USR_EN_MASK) {
>> + /* Need to enable the interrupt on the last packet */
>> + rc = netfront_rxq_intr_enable(rxq);
>> + if (rc == 1 && !(*pkt)) {
>> + /**
>> + * Packet arrive after reading the queue and before
>> + * enabling the interrupt
>> + */
>> + rc = netfront_rxq_dequeue(rxq, pkt);
>> + UK_ASSERT(rc >= 0);
>> + status |= UK_NETDEV_STATUS_SUCCESS;
>> +
>> + /*
>> + * Since we received something, we need to fillup
>> + * and notify
>> + */
>> + status |= netfront_rx_fillup(rxq, rc);
>> +
>> + /* Need to enable the interrupt on the last packet */
>> + rc = netfront_rxq_intr_enable(rxq);
>> + status |= (rc == 1) ? UK_NETDEV_STATUS_MORE : 0x0;
>> + } else if (*pkt) {
>> + /* When we originally got a packet and there is more */
>> + status |= (rc == 1) ? UK_NETDEV_STATUS_MORE : 0x0;
>> + }
>> + } else if (*pkt) {
>> + /**
>> + * For polling case, we report always there are further
>> + * packets unless the queue is empty.
>> + */
>> + status |= UK_NETDEV_STATUS_MORE;
>> + }
>> +
>> + return status;
>> +}
>> +
>> static struct uk_netdev_tx_queue *netfront_txq_setup(struct
>> uk_netdev *n,
>> uint16_t queue_id,
>> uint16_t nb_desc __unused,
>> @@ -700,6 +799,7 @@ static int netfront_add_dev(struct xenbus_device
>> *xendev)
>> /* register netdev */
>> nfdev->netdev.tx_one = netfront_xmit;
>> + nfdev->netdev.rx_one = netfront_recv;
>> nfdev->netdev.ops = &netfront_ops;
>> rc = uk_netdev_drv_register(&nfdev->netdev, drv_allocator,
>> DRIVER_NAME);
>> if (rc < 0) {
>
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |