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:
Johan Hedberg 2016-06-05 19:17:03 +03:00
commit d10d1b21f5

View file

@ -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_ASSERT(buf->ref > 0);
if (--buf->ref) {
return;
}
while (buf && --buf->ref == 0) {
struct net_buf *frags = buf->frags;
if (buf->frags) {
net_buf_unref(buf->frags);
buf->frags = NULL;
}
if (buf->destroy) {
buf->destroy(buf);
} else {
nano_fifo_put(buf->free, buf);
if (buf->destroy) {
buf->destroy(buf);
} else {
nano_fifo_put(buf->free, buf);
}
buf = frags;
}
}