Hugh Brown
|
Re: Porting NetBSD Network Driver
|
Hugh Brown
02/07/2018 2:00 PM
post118522
|
Re: Porting NetBSD Network Driver
The definition for DELAY() can be found in usr/include/io-pkt/machine/param.h and it cannot be used in an interrupt
service routine.
nanospin_ns() can be used in an interrupt service routine, but it isn't recommended. See the docs.
On 2018-02-07, 12:49 PM, "Danny Yen(deleted)" <community-noreply@qnx.com> wrote:
In the documentation, under "Differences between ported NetBSD drivers and native drivers", it says that there are
two different "delay" functions: delay() and DELAY(), where DELAY() is reentrant. However, Neutrino's version of delay()
is very different (millisecond instead of microsecond). That's why QNX had defined a DELAY() to support microsecond.
Furthermore, ported drivers should define delay() to DELAY().
My question is two folds:
1. Where can I actually find DELAY()? I see delay() in unistd.h but I can't seem to find DELAY() anywhere. Momentics
does not seem to recognize it.
2. Is Neutrino's implementation of DELAY() or delay() reentrant, i.e. safe to be used in an interrupt or process
context?
_______________________________________________
Networking Drivers
http://community.qnx.com/sf/go/post118521
To cancel your subscription to this discussion, please e-mail drivers-networking-unsubscribe@community.qnx.com
|
|
|
Nick Reilly
|
Re: Porting NetBSD Network Driver
|
Nick Reilly
02/07/2018 2:05 PM
post118523
|
Re: Porting NetBSD Network Driver
DELAY is defined in usr/include/io-pkt/machine/param.h
#define DELAY(_x) (((_x) >= 1000) ? (delay)(((_x) / 1000) + 1) : nanospin_ns((_x) * 1000L))
There are several things to consider with delays of any sort in a driver:
1) QNX kernel timer tick resolution. By default the timer tick is 1ms so any form of delay/sleep call will have that
resolution. nanospin_ns() can be used for shorter delays but suffers from calibration issues.
2) io-pkt is in general behaviour single threaded - there is a single "network stack context" that performs most
operations. Performing a delay in one driver in the stack context will usually block traffic on other interfaces.
3) To overcome point 2 we have introduced nic_delay() in usr/include/netdrvr/nicsupport.h However note that in yielding
stack context to permit traffic to flow on other interfaces, it also permits other operations to happen on your driver -
including such things as removal e.g. on a USB interface. Care needs to be taken with locking.
4) Adding to the complexity, the stack context can migrate between posix threads so the locks need to be nic_mutex and
not pthread_mutex - see usr/include/netdrvr/nic_mutex.h
5) io-pkt internal timers as used by nic_delay() tick at between 8ms and 50ms depending on traffic. If you have many
calls to nic_delay() for a short delays then you can find this taking significant clock time. Moving the entire block of
code across to a blockop solves this issue and makes the nic_delay() behave like a normal delay.
Think very carefully about delays in drivers, they have historically been the cause of many issues!
|
|
|