nl80211: increase wiphy dump size dynamically
Given a device with many channels capabilities the wiphy information can still overflow even though its size in 3.9 was reduced to 3.8 levels. For new userspace and kernel 3.10 we're going to implement a new "split dump" protocol that can use multiple messages per wiphy. For now though, add a workaround to be able to send more information to userspace. Since generic netlink doesn't have a way to set the minimum dump size globally, and we wouldn't really want to set it globally anyway, increase the size only when needed, as described in the comments. As userspace might not be prepared for large buffers, we can only use 4k. Also increase the size for the get_wiphy command. Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
Родитель
feda30271e
Коммит
645e77def9
|
@ -1307,7 +1307,7 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 portid, u32 seq, int flag
|
||||||
|
|
||||||
static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb)
|
static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb)
|
||||||
{
|
{
|
||||||
int idx = 0;
|
int idx = 0, ret;
|
||||||
int start = cb->args[0];
|
int start = cb->args[0];
|
||||||
struct cfg80211_registered_device *dev;
|
struct cfg80211_registered_device *dev;
|
||||||
|
|
||||||
|
@ -1317,9 +1317,29 @@ static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb)
|
||||||
continue;
|
continue;
|
||||||
if (++idx <= start)
|
if (++idx <= start)
|
||||||
continue;
|
continue;
|
||||||
if (nl80211_send_wiphy(skb, NETLINK_CB(cb->skb).portid,
|
ret = nl80211_send_wiphy(skb, NETLINK_CB(cb->skb).portid,
|
||||||
cb->nlh->nlmsg_seq, NLM_F_MULTI,
|
cb->nlh->nlmsg_seq, NLM_F_MULTI,
|
||||||
dev) < 0) {
|
dev);
|
||||||
|
if (ret < 0) {
|
||||||
|
/*
|
||||||
|
* If sending the wiphy data didn't fit (ENOBUFS or
|
||||||
|
* EMSGSIZE returned), this SKB is still empty (so
|
||||||
|
* it's not too big because another wiphy dataset is
|
||||||
|
* already in the skb) and we've not tried to adjust
|
||||||
|
* the dump allocation yet ... then adjust the alloc
|
||||||
|
* size to be bigger, and return 1 but with the empty
|
||||||
|
* skb. This results in an empty message being RX'ed
|
||||||
|
* in userspace, but that is ignored.
|
||||||
|
*
|
||||||
|
* We can then retry with the larger buffer.
|
||||||
|
*/
|
||||||
|
if ((ret == -ENOBUFS || ret == -EMSGSIZE) &&
|
||||||
|
!skb->len &&
|
||||||
|
cb->min_dump_alloc < 4096) {
|
||||||
|
cb->min_dump_alloc = 4096;
|
||||||
|
mutex_unlock(&cfg80211_mutex);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
idx--;
|
idx--;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1336,7 +1356,7 @@ static int nl80211_get_wiphy(struct sk_buff *skb, struct genl_info *info)
|
||||||
struct sk_buff *msg;
|
struct sk_buff *msg;
|
||||||
struct cfg80211_registered_device *dev = info->user_ptr[0];
|
struct cfg80211_registered_device *dev = info->user_ptr[0];
|
||||||
|
|
||||||
msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
|
msg = nlmsg_new(4096, GFP_KERNEL);
|
||||||
if (!msg)
|
if (!msg)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче