Signed-off-by: Denis Kenzior <denk...@gmail.com>
---
 net/wireless/nl80211.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 682a095415eb..24b67de99f3a 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -2498,6 +2498,22 @@ static int nl80211_dump_wiphy(struct sk_buff *skb, 
struct netlink_callback *cb)
                        rtnl_unlock();
                        return ret;
                }
+
+               /*
+                * auto-detect support for large buffer sizes: af_netlink
+                * will allocate skbufs larger than 4096 in cases where
+                * it detects that the client receive buffer (given to
+                * recvmsg) is bigger.  In such cases we can assume that
+                * performing split dumps is wasteful since the client
+                * can likely safely consume the entire un-split wiphy
+                * message in one go without the extra message header
+                * overhead.
+                */
+               if (skb_tailroom(skb) > 4096) {
+                       state->large_message = true;
+                       state->split = false;
+               }
+
                cb->args[0] = (long)state;
        }
 
@@ -2531,6 +2547,7 @@ static int nl80211_dump_wiphy(struct sk_buff *skb, struct 
netlink_callback *cb)
                                 * We can then retry with the larger buffer.
                                 */
                                if ((ret == -ENOBUFS || ret == -EMSGSIZE) &&
+                                   !state->large_message &&
                                    !skb->len && !state->split &&
                                    cb->min_dump_alloc < 4096) {
                                        cb->min_dump_alloc = 4096;
-- 
2.21.0

Reply via email to