Matias Elo(matiaselo) replied on github web page:

platform/linux-generic/odp_packet_io.c
line 5
@@ -33,9 +33,9 @@
 #include <time.h>
 
 /* Sleep this many nanoseconds between pktin receive calls */
-#define SLEEP_NSEC  1000
+#define SLEEP_USEC  1


Comment:
Comment still says nanoseconds. Should also state that the maximum value is 1 
000 000, so that timespec.tv_nsec is used correctly.


> Matias Elo(matiaselo) wrote:
> Agreed, the "divisor" can be added later if needed.


>> Juha-Matti Tilli(jmtilli) wrote:
>> Now that's a great idea! If somebody sees one microsecond as too big sleep 
>> time, it is always possible to implement a "divisor": multiply the sleep 
>> time by e.g. 4, and sleep e.g. 250 nanoseconds. No slow division operation 
>> is needed for this "divisor", only multiplication. But I won't implement 
>> this divisor now, as SLEEP_NSEC anyway always used to be 1000.


>>> Matias Elo(matiaselo) wrote:
>>> Ifdefs are not allowed.  IMO the cleanest fix would be to add a separate 
>>> commit (before this one) to this patch set, which modifies 
>>> odp_pktin_wait_time() to always return microseconds and converts SLEEP_NSEC 
>>> to SLEEP_USEC (and does necessary changes to make everything work).
>>> 
>>> Or does someone oppose having a minimum sleep time of 1us between pktin 
>>> receive calls in the old code path?


>>>> Juha-Matti Tilli(jmtilli) wrote:
>>>> I would prefer return 0; as the trial_successful already tells not to use 
>>>> this interrupt-driven way, but it probably doesn't matter much. I'll do 
>>>> this (with return 0).


>>>>> Matias Elo(matiaselo) wrote:
>>>>> By checking both ops here you can return right away and minimize overhead 
>>>>> for pktios not supporting interrupt driven mode.
>>>>> E.g.
>>>>> ```
>>>>>           if (!entry[i]->s.ops->recv_mq_tmo && !entry[i]->s.ops->fd_set) {
>>>>>                   *trial_successful = 0;
>>>>>                   return -1;
>>>>>           }
>>>>> ```


>>>>>> Juha-Matti Tilli(jmtilli) wrote:
>>>>>> I'm somewhat worried that somebody could adjust SLEEP_NSEC and then the 
>>>>>> entire thing fails. What about this:
>>>>>> 
>>>>>> <pre>
>>>>>> #if SLEEP_NSEC == 1000
>>>>>>   uint64_t usecs = wait;
>>>>>> #else
>>>>>>   uint64_t usecs = (wait * SLEEP_NSEC + 999) / 1000;
>>>>>> #endif
>>>>>> </pre>
>>>>>> 
>>>>>> For the return value, you mean <code>odp_pktin_wait_time()</code> and 
>>>>>> not <code>odp_pktin_recv_mq_tmo()</code>, right? Because I don't see how 
>>>>>> the return value of the latter could depend on <code>SLEEP_NSEC</code> 
>>>>>> definition.
>>>>>> 
>>>>>> Also, if we modify <code>odp_pktin_wait_time()</code> to always return 
>>>>>> microseconds, then <code>odp_pktin_recv_mq_tmo()</code> suddenly starts 
>>>>>> to work incorrectly with <code>SLEEP_NSEC != 1000</code> as there is a 
>>>>>> <code>wait--</code> line in there that does this just before sleeping 
>>>>>> one microsecond, exactly.


>>>>>>> Matias Elo(matiaselo) wrote:
>>>>>>> Same thing with the loop order than with netmap.


>>>>>>>> Matias Elo(matiaselo) wrote:
>>>>>>>> Couple comment lines describing the different stages of this function 
>>>>>>>> wouldn't hurt when someone is reading this code later on. 


>>>>>>>>> Matias Elo(matiaselo) wrote:
>>>>>>>>> Same thing with the loop order than with netmap.


>>>>>>>>>> Matias Elo(matiaselo) wrote:
>>>>>>>>>> Since this loop is a performance optimization I would move it before 
>>>>>>>>>> the loop which sets the read descriptors. No use to set the 
>>>>>>>>>> descriptors if packets are already available.


>>>>>>>>>>> Matias Elo(matiaselo) wrote:
>>>>>>>>>>> The motivation for a separate `odp_pktin_wait_time()` function was 
>>>>>>>>>>> to avoid having to do time conversions in the fast path functions. 
>>>>>>>>>>> As `odp_pktin_wait_time()` already returns the time in microseconds 
>>>>>>>>>>> no additional conversions are needed here. Same thing for 
>>>>>>>>>>> `odp_pktin_recv_mq_tmo()`.
>>>>>>>>>>> 
>>>>>>>>>>> Currently, the value returned by `odp_pktin_recv_mq_tmo()` depends 
>>>>>>>>>>> on `SLEEP_NSEC` definition. This should be modified so that the 
>>>>>>>>>>> returned value is always in microseconds.


>>>>>>>>>>>> Matias Elo(matiaselo) wrote:
>>>>>>>>>>>> Every pktio type we currenly have uses microseconds for timeout, 
>>>>>>>>>>>> so you could change `recv_tmo()` and `recv_mq_tmo()` to use 
>>>>>>>>>>>> microseconds instead of nanoseconds. This removes the need for per 
>>>>>>>>>>>> operation conversions.


>>>>>>>>>>>>> Matias Elo(matiaselo) wrote:
>>>>>>>>>>>>> > Are you entirely sure about this? This is a function pointer, 
>>>>>>>>>>>>> > and if two pktio devices have the same function pointer for 
>>>>>>>>>>>>> > recv_mq_tmo(), the other function pointers including the recv() 
>>>>>>>>>>>>> > function pointer should be identical as well. We do pass the 
>>>>>>>>>>>>> > device (entry[i]) to the function pointed to by recv_mq_tmo as 
>>>>>>>>>>>>> > well, so it should be able to update the correct counters. The 
>>>>>>>>>>>>> > ops structure is const, after all...
>>>>>>>>>>>>> 
>>>>>>>>>>>>> I stand corrected, didn't notice the pktio_entry_t array 
>>>>>>>>>>>>> parameter. A bit confusing as `recv_mq_tmo()` behaves differently 
>>>>>>>>>>>>> than pretty much every other pktio op.


>>>>>>>>>>>>>> muvarov wrote
>>>>>>>>>>>>>> just pass nsec to drivers or you will have double calculation 
>>>>>>>>>>>>>> like in netmap code.


>>>>>>>>>>>>>>> Juha-Matti Tilli(jmtilli) wrote:
>>>>>>>>>>>>>>> Are you entirely sure about this? This is a function pointer, 
>>>>>>>>>>>>>>> and if two pktio devices have the same function pointer for 
>>>>>>>>>>>>>>> recv_mq_tmo(), the other function pointers including the recv() 
>>>>>>>>>>>>>>> function pointer should be identical as well. We do pass the 
>>>>>>>>>>>>>>> device (entry[i]) to the function pointed to by recv_mq_tmo as 
>>>>>>>>>>>>>>> well, so it should be able to update the correct counters. The 
>>>>>>>>>>>>>>> ops structure is const, after all...
>>>>>>>>>>>>>>> 
>>>>>>>>>>>>>>> So, when receiving packets from a particular device using 
>>>>>>>>>>>>>>> netmap, we do call netmap_recv() and pass to it the 
>>>>>>>>>>>>>>> pktio_entry[i] and also index[i] for the queue index. This is 
>>>>>>>>>>>>>>> the same that the odp_pktin_recv_mq_tmo() function already did. 
>>>>>>>>>>>>>>> It calls odp_pktin_recv() in a loop, and the latter function 
>>>>>>>>>>>>>>> calls entry->s.ops->recv(entry, queue.index, packets, num); 
>>>>>>>>>>>>>>> which to me seems to be exactly the same thing -- you pass 
>>>>>>>>>>>>>>> exactly the same entry and the same queue.index. Same function, 
>>>>>>>>>>>>>>> same arguments, I can't see how the behavior would be 
>>>>>>>>>>>>>>> different...
>>>>>>>>>>>>>>> 
>>>>>>>>>>>>>>> Now, if somebody opposes the .recv_mq_tmo function pointer due 
>>>>>>>>>>>>>>> to added code line count, I might perhaps agree. But it seems 
>>>>>>>>>>>>>>> to be the only way the DPDK support for genuine sleep could be 
>>>>>>>>>>>>>>> added, so I see some value in it.


>>>>>>>>>>>>>>>> Juha-Matti Tilli(jmtilli) wrote:
>>>>>>>>>>>>>>>> Several options: (1) I could implement a binary search 
>>>>>>>>>>>>>>>> algorithm that incrementally checks various usec values and 
>>>>>>>>>>>>>>>> uses odp_pktin_wait_time() to check which one of these trial 
>>>>>>>>>>>>>>>> attempts result in the same sleep wait value, but that would 
>>>>>>>>>>>>>>>> be slow; (2) I could implement odp_pktin_wait_time_reverse() 
>>>>>>>>>>>>>>>> that does the conversion in the other direction, but that 
>>>>>>>>>>>>>>>> would be an API change; (3) I could just do the conversion and 
>>>>>>>>>>>>>>>> pass usec values instead of sleep wait values. I carefully 
>>>>>>>>>>>>>>>> considered each and selected (3), but do you think (2) or (1) 
>>>>>>>>>>>>>>>> would be better?


>>>>>>>>>>>>>>>>> Juha-Matti Tilli(jmtilli) wrote:
>>>>>>>>>>>>>>>>> Will fix.


>>>>>>>>>>>>>>>>>> Juha-Matti Tilli(jmtilli) wrote:
>>>>>>>>>>>>>>>>>> I disagree. SLEEP_NSEC is a private #define in 
>>>>>>>>>>>>>>>>>> odp_packet_io.c so what the wait parameter actually means 
>>>>>>>>>>>>>>>>>> cannot be interpreted in the drivers. (Believe me, I tried 
>>>>>>>>>>>>>>>>>> it!) Thus, the conversion from the sleep wait parameter to 
>>>>>>>>>>>>>>>>>> microseconds is needed.


>>>>>>>>>>>>>>>>>>> Matias Elo(matiaselo) wrote:
>>>>>>>>>>>>>>>>>>> As I noted in the previous comment, I think this check 
>>>>>>>>>>>>>>>>>>> isn't enough. The input queues would have to be from the 
>>>>>>>>>>>>>>>>>>> same pktio device for this to work.


>>>>>>>>>>>>>>>>>>>> Matias Elo(matiaselo) wrote:
>>>>>>>>>>>>>>>>>>>> Internal functions should not use odp_ prefix.


>>>>>>>>>>>>>>>>>>>>> Matias Elo(matiaselo) wrote:
>>>>>>>>>>>>>>>>>>>>> You should pass the `wait` parameter to 
>>>>>>>>>>>>>>>>>>>>> `entry->s.ops->recv_tmo()` and not do any conversions 
>>>>>>>>>>>>>>>>>>>>> here.


>>>>>>>>>>>>>>>>>>>>>> Matias Elo(matiaselo) wrote:
>>>>>>>>>>>>>>>>>>>>>> ODP_TIME_SEC_IN_NS would work here.


https://github.com/Linaro/odp/pull/341#discussion_r160113095
updated_at 2018-01-08 10:42:00

Reply via email to