Isn't a pktio instance (pure HW or SW like in this case) allowed to
put requirements on what kind of buffers (e.g. number and sizes of
segments) that are required for reception?

On transmission, the pktio instance ought to handle segmented buffers.
Possibly linux-generic could use writev() to write a vector of buffer
segments as one packet?

On 6 November 2014 15:24, Maxim Uvarov <[email protected]> wrote:
> On 11/06/2014 03:56 PM, Bill Fischofer wrote:
>>
>> In reworking the packet code, one point I'm not clear on is how the
>> linux-generic raw socket I/O model is supposed to deal with segmented
>> packets on both receive and transmit paths.
>>
>> Transmit is presumably more straightforward.  Here's a snippet from
>> odp_packet_socket.c (routine
>>
>> while (i < len) { pkt = pkt_table[i]; frame = odp_packet_l2(pkt);
>> frame_len = odp_packet_get_len(pkt); ret = send(sockfd, frame, frame_len,
>> flags); if (odp_unlikely(ret == -1)) { if (odp_likely(errno == EAGAIN)) {
>> flags = 0; /* blocking for next rounds */ continue; /* resend buffer */ }
>> else { break; } } i++; } /* end while */
>>
>> The current code assumes that it has contiguous addressability to the
>> entire packet.  Is that a requirement of the raw socket interface?  If not
>> then it would seem this could be replaced by the following more general
>> code:
>>
>> while (i < len) {
>> pkt = pkt_table[i];
>>
>> frame_len = odp_packet_len(pkt);
>> frame_offset = 0;
>>
>> while (frame_len > 0) {
>> frame = odp_packet_offset_map(pkt,frame_offset,&seglen);
>> if (frame == NULL)
>> break;
>> ret = send(sockfd, frame, seg_len, flags);
>
>
> I think raw sockets expect that packet is in continuous memory. You can
> relay on that on receive but on send you never know how that packet was
> created.
> For example app can create segmented packets, segments are in different
> address. In that case you need to copy that data to temporary buffer before
> sending.
>
>  ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags);
> Works with vectors:
>
>            struct msghdr {
>                void         *msg_name;       /* optional address */
>                socklen_t     msg_namelen;    /* size of address */
>                struct iovec *msg_iov;        /* scatter/gather array */
>                size_t        msg_iovlen;     /* # elements in msg_iov */
>                void         *msg_control;    /* ancillary data, see below */
>                size_t        msg_controllen; /* ancillary data buffer len */
>                int           msg_flags;      /* flags on received message */
>            };
>
> But for raw sockets more likely that each entry in vector will be separate
> packet. But it's needed to check if it's so or not.
>
> Maxim.
>
>> if (odp_unlikely(ret == -1)) {
>> if (odp_likely(errno == EAGAIN)) {
>> flags = 0;/* blocking for next rounds */
>> continue;/* resend buffer */
>> } else {
>> frame_offset += seg_len;
>> frame_len  -= seg_len;
>> }
>> }
>> }
>> i++;
>> }/* end while */
>>
>> Would this code be functionally correct from a raw socket perspective?
>>
>> Receive processing has similar issues.  I've not been able to find any raw
>> socket examples (via googling) that don't assume they can receive an entire
>> packet into a single contiguous buffer. Is that a requirement of the
>> interface?
>>
>> Is there support for scatter/gather lists in these APIs?  If so then we
>> may need some additional ODP APIs (possibly internal) to allow the segment
>> lists to be manipulated as a whole rather than one-by-one.
>>
>> Thanks.
>>
>> Bill
>>
>>
>> _______________________________________________
>> lng-odp mailing list
>> [email protected]
>> http://lists.linaro.org/mailman/listinfo/lng-odp
>
>
>
> _______________________________________________
> lng-odp mailing list
> [email protected]
> http://lists.linaro.org/mailman/listinfo/lng-odp

_______________________________________________
lng-odp mailing list
[email protected]
http://lists.linaro.org/mailman/listinfo/lng-odp

Reply via email to