> -----Original Message----- > From: Verma, Shally [mailto:[email protected]] > Sent: Wednesday, March 01, 2017 11:39 AM > To: Savolainen, Petri (Nokia - FI/Espoo) <petri.savolainen@nokia-bell- > labs.com>; Francois Ozog <[email protected]> > Cc: [email protected] > Subject: RE: [lng-odp] Generic handle in ODP > > > HI Petri/Maxim > > Please see my response below. > > -----Original Message----- > From: Savolainen, Petri (Nokia - FI/Espoo) [mailto:petri.savolainen@nokia- > bell-labs.com] > Sent: 01 March 2017 14:38 > To: Verma, Shally <[email protected]>; Francois Ozog > <[email protected]> > Cc: [email protected] > Subject: RE: [lng-odp] Generic handle in ODP > > > > > -----Original Message----- > > From: lng-odp [mailto:[email protected]] On Behalf Of > > Verma, Shally > > Sent: Wednesday, March 01, 2017 10:38 AM > > To: Francois Ozog <[email protected]> > > Cc: [email protected] > > Subject: Re: [lng-odp] Generic handle in ODP > > > > HI Francois > > > > What you said is correct and in such case API should only have > > odp_packet_t as an its type signature and access memory as per > > implementation policy. > > > > I am talking about use case where an API can input data both as a > > plain buffer (which is a contiguous memory) *OR* as a packet (which is > > variable, scattered/non-scattered segmented memory). So when API sees > > that input data is from buffer pool, can simply use address > > returned by odp_buf_addr as memory pointer and do direct read/write > > (as its not segmented and contiguous memory) and when it sees chunk is > > from packet pool , then access data according to its base hw > implementation. > > > > I am taking here a simple memcpy() pseudo example to explain case . > > Say, if I want to enable memcpy from both packet and buffer memory, > > then there are 2 ways of doing it: > > > > 1. Add two separate APIs , say memcpy_from_buffer(odp_buffer_t > > buf,size_t len, void *dst) and memcpy_from_packet(odp_packet_t packet, > > size_t len, void *) OR > > > > 2. Or, make one API say memcpy(odp_handle_t handle, odp_pool_t > pool, > > size_t len, void *dst) > > > > { > > > > if (pool type== odp_buffer_t ) then > > > > addr=odp_buffer_addr((odp_buffer_t)handle); > > > > else > > > > addr=odp_packet_data((odp_packet_t)handle); > > > > > > > > memcpy(dst,addr,len); > > > > } > > > > Hope this could explain intended use case to an extent. > > > > Thanks > > Shally > > > As Maxim mentioned, odp_event_t is the single type (that is passed through > queues). An event can be buffer, packet, timeout, crypto/ipsec completion, > etc. Application needs to check event type and convert it to correct sub- > type (e.g. packet) to access the data/metadata. > > Application needs to be careful to handle buffers vs. packets correctly. > Buffers are simple, always contiguous memory blocks - whereas packets may > be fragmented. The example above would break if a packet segment boundary > is hit between addr[0]...addr[len-1]. There are a bunch of packet_copy > functions which handle segmentation correctly. > > > if (odp_event_type(ev) == ODP_EVENT_PACKET) { > pkt = odp_packet_from_event(ev); > odp_packet_copy_to_mem(pkt, 0, len, dst); } else if > (odp_event_type(ev) == ODP_EVENT_BUFFER) { > buf = odp_buffer_from_event(ev); > addr = odp_buffer_addr(buf); > memcpy(dst, addr, len); > } else { > // BAD EVENT TYPE. NO DATA TO COPY. > } > > Shally >> This is understood. However it is applicable for the Event based > action where we can do typecasting between event/packet and buffer. > I am asking for scenario which user can initiate some action on data and > that data can be either from buffer or packet pool (which may result into > some event generation). As you mentioned above - > " Application needs to be careful to handle buffers vs. packets correctly. > Buffers are simple, always contiguous memory blocks - whereas packets may > be fragmented. The example above would break if a packet segment boundary > is hit between addr[0]...addr[len-1]. There are a bunch of packet_copy > functions which handle segmentation correctly." > For the same reason, I am asking if we could add generic handle. So that > API can understand what memory type it is dealing with. > > I re-write my example here to explain bit more here.. > > if (pool type== odp_buffer_t ) then > { > addr=odp_buffer_addr((odp_buffer_t)handle); > memcpy(dst,addr,len); > } > > else > { > offset=0; > while(offset<len) > { > addr=odp_packet_offset(packet,offset,&cur_seg,&seg_len); > memcpy(dst, addr, seg_len); > offset+=seg_len; > } > } > Hope this help.
Why you would not use odp_packet_copy_to_mem() in the example above (instead of the memcpy loop)? -Petri
