-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
gnrc_netif: add packet to queue when device is busy #11263
Conversation
Initial gut feeling for this API change is positive. I think it simplifies a few device drivers as those don't have to block anymore until the radio is done transmitting the previous frame. I know that at least the mrf24j40 has a clunky
Maybe this should be called a Device Access Control Scheme? 😄 |
See #11264 for my |
My feelings exactly. Now we can finally make the drivers just return "-EBUSY" when it currently cannot send. Conceptionally this is a rather large change, so I suggest we don't rush it into the release. |
Also I just noticed that it is not that easy |
00ad20c
to
3d01075
Compare
Rebased to current master to resolve conflict. |
And set to WIP due to #11263 (comment) |
Made queue larger, since it was way to small for larger fragmented packets. |
Reworked a little bit, so a rewrite of all the |
7467741
to
a11bd99
Compare
Rebased to current master to resolve a conflict caused by the merging of #11837. |
a11bd99
to
e29f3d5
Compare
Squashed to simplify some integration into a separate branch. |
(cherry picked from commit 5cc265f, see RIOT-OS#11263)
... and also send on send error (i.e. when *medium* was busy) (cherry picked from commit 825b0f5, see RIOT-OS#11263)
(cherry picked from commit e29f3d5, see RIOT-OS#11263)
(cherry picked from commit 609add0, see RIOT-OS#11263)
Should I squash then or are you still going through the changes? |
Sure, please squash |
I just saw: also need to rebase ... again -.- |
19fe623
to
bb2f1c2
Compare
Squashed |
... and also send on send error (i.e. when *medium* was busy)
bb2f1c2
to
818097f
Compare
And rebased and adapted to current master. |
I tested this one carefully using #14787 and notice something strange: if a radio returns For instance, using this feature with
If I modify the driver to return diff --git a/drivers/at86rf2xx/at86rf2xx_netdev.c b/drivers/at86rf2xx/at86rf2xx_netdev.c
index 3c83a43947..f8ff12d0da 100644
--- a/drivers/at86rf2xx/at86rf2xx_netdev.c
+++ b/drivers/at86rf2xx/at86rf2xx_netdev.c
@@ -114,6 +114,10 @@ static int _send(netdev_t *netdev, const iolist_t *iolist)
at86rf2xx_t *dev = (at86rf2xx_t *)netdev;
size_t len = 0;
+ if (at86rf2xx_get_status(dev) == AT86RF2XX_STATE_BUSY_TX_ARET) {
+ return -EBUSY;
+ }
+ I get
I consistently get extra ~8-10 ms if Any idea on why this could happen? |
With this patch--- a/drivers/at86rf215/at86rf215.c
+++ b/drivers/at86rf215/at86rf215.c
@@ -250,6 +250,10 @@ static void _block_while_busy(at86rf215_t *dev)
static void at86rf215_block_while_busy(at86rf215_t *dev)
{
+ if (IS_ACTIVE(GNRC_NETIF_PKTQ)) {
+ return;
+ }
+
if (_tx_ongoing(dev)) {
DEBUG("[at86rf215] Block while TXing\n");
_block_while_busy(dev);
@@ -262,7 +266,12 @@ int at86rf215_tx_prepare(at86rf215_t *dev)
return -EAGAIN;
}
- at86rf215_block_while_busy(dev);
+ if (IS_ACTIVE(GNRC_NETIF_PKTQ) && _tx_ongoing(dev)) {
+ return -EBUSY;
+ } else {
+ at86rf215_block_while_busy(dev);
+ }
+
dev->tx_frame_len = IEEE802154_FCS_LEN;
return 0;
I get better results: master
gnrc_netif_pktq
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code looks good and is working fine.
Let's finally get this in!
@kaspar030 your concerns seem to be addressed. Can we dismiss your stale review ? (or you can just ACK :) ) |
Is it strange that when there is queuing involved that there might be an overhead? |
If you are worried that it is such a high overhead, you have to remember to divide your round-trip time by 22 (11 fragments send to and from) and you get a more accurate picture. |
I think so. I would expect an overhead of memory usage, but not such an RTT overhead. Considering that the queue is there because network stack is much faster than the network device (including queue operations), I wouldn't expect such a time difference.
I'm not worried about the higher RTT considering that this fixes several problems, but I'm just wondering why there's such a difference. |
(I'm not blocking this PR, I'm just trying to figure out where does this time difference come from) |
Comments have been addressed over a year ago
} | ||
/* hold in case device was busy to not having to rewrite *all* the link | ||
* layer implementations in case `gnrc_netif_pktq` is included */ | ||
gnrc_pktbuf_hold(pkt, 1); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What was meant by this comment? 😨
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When this was written, the netif implementations just threw away the packet when they were unable to send (might not be the case with netdev_new
, I don't know).
So, to prevent it not to be lost in that case, we hold
the packet (i.e. the next release
does not remove it from the packet buffer), to put it into the queue later in ll1431-1437. If the device was not busy, we just remove it in l1447.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
netdev_new
does indeed not release on send
Contribution description
This fixes the issue showcased in #11256 (assuming the
gnrc_netif_pktq
module is compiled in and the network device supports to return-EBUSY
) by providing a very simple MAC scheme: If the device is busy on send, queue the packet and don't send. When RX_COMPLETE or TX_COMPLETE is issued, try to send the first packet in the queue.Testing procedure
Run
make tests-gnrc_netif_pktq test
fortests/unittests
. For testing the actual integration a device adaptation is needed, which I will provide forat86rf2xx
.Since I edited the
gnrc_netif.c
: pinging withgnrc_networking
should still work.Issues/PRs references
Provides a fix for the race condition show-cased in #11256.
Basis for #11068
SY`) by providing a very simple MAC scheme: If the device is busy on send, queue the packet and don't send. When RX_COMPLETE or TX_COMPLETE is issued, try to send the first packet in the queue.
Testing procedure
Run
make tests-gnrc_netif_pktq test
fortests/unittests
. For testing the actual integration a device adaptation is needed, which I will provide forat86rf2xx
.Since I edited the
gnrc_netif.c
: pinging withgnrc_networking
should still work.Issues/PRs references
Provides a fix for the race condition show-cased in #11256.