net: buf: Don't use recursion for freeing fragment list
Freeing the fragment list by recursively calling net_buf_unref() is elegant but dangerous. Since we have fairly small stack sizes it'd be possible to overflow the stack if the user creates a very long list of fragments (empirical tests showed that some 21 fragments is enough to kill a 2k stack). Instead, use a while-loop for freeing up the fragments, thereby guaranteeing a fixed upper bound for net_buf_unref() stack usage. Change-Id: Ibfe794fa717d1cddc84365c7b7b9cff4024edbf6 Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
This commit is contained in:
parent
7720f6ed1c
commit
d10d1b21f5
1 changed files with 9 additions and 10 deletions
19
net/buf.c
19
net/buf.c
|
@ -129,19 +129,18 @@ void net_buf_unref(struct net_buf *buf)
|
||||||
NET_BUF_DBG("buf %p ref %u fifo %p\n", buf, buf->ref, buf->free);
|
NET_BUF_DBG("buf %p ref %u fifo %p\n", buf, buf->ref, buf->free);
|
||||||
NET_BUF_ASSERT(buf->ref > 0);
|
NET_BUF_ASSERT(buf->ref > 0);
|
||||||
|
|
||||||
if (--buf->ref) {
|
while (buf && --buf->ref == 0) {
|
||||||
return;
|
struct net_buf *frags = buf->frags;
|
||||||
}
|
|
||||||
|
|
||||||
if (buf->frags) {
|
|
||||||
net_buf_unref(buf->frags);
|
|
||||||
buf->frags = NULL;
|
buf->frags = NULL;
|
||||||
}
|
|
||||||
|
|
||||||
if (buf->destroy) {
|
if (buf->destroy) {
|
||||||
buf->destroy(buf);
|
buf->destroy(buf);
|
||||||
} else {
|
} else {
|
||||||
nano_fifo_put(buf->free, buf);
|
nano_fifo_put(buf->free, buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
buf = frags;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue