0

我正在学习 linux wifi 驱动程序,并且正在探索子系统中的代码以cfg80211获取扫描请求。

我不明白为什么以下struct分配的内存比需要的多。或者,我无法理解以这种方式计算要分配的内存大小的方式。

struct定义在include/net/cfg80211.h

struct cfg80211_scan_request {
    struct cfg80211_ssid *ssids;
    int n_ssids;
    u32 n_channels;
    enum nl80211_bss_scan_width scan_width;
    const u8 *ie;
    size_t ie_len;
    u16 duration;
    bool duration_mandatory;
    u32 flags;

    u32 rates[NUM_NL80211_BANDS];

    struct wireless_dev *wdev;

    u8 mac_addr[ETH_ALEN] __aligned(2);
    u8 mac_addr_mask[ETH_ALEN] __aligned(2);
    u8 bssid[ETH_ALEN] __aligned(2);

    /* internal */
    struct wiphy *wiphy;
    unsigned long scan_start;
    struct cfg80211_scan_info info;
    bool notified;
    bool no_cck;

    /* keep last */
    struct ieee80211_channel *channels[0];
};

在 file/net/wireless/nl80211.c中,内存被分配给struct如下:

static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
{
    // ...
    struct cfg80211_scan_request *request;
    // ...
    request = kzalloc(sizeof(*request)
            + sizeof(*request->ssids) * n_ssids
            + sizeof(*request->channels) * n_channels
            + ie_len, GFP_KERNEL);
    // ...
}

我怀疑分配的内存比需要的多。或者,计算大小的方式kzalloc对我来说没有意义。

这就是我期望的代码:

static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
{
    // ...
    struct cfg80211_scan_request *request;
    // ...
    request = kzalloc(sizeof(*request)
            + sizeof(*request->channels) * n_channels, 
              GFP_KERNEL);
    // ...
}

那为什么要分配这么大的内存呢?我的理解是kzalloc(struct + flexible_array_member + extra_len_but_why)

4

1 回答 1

2

大概后面的代码kzalloc设置了指针的值,requests->ssids以便requests->ie它们指向新分配的内存,就在结构之后。

这样,三个数组只需要分配一块内存。

编辑:我找到了有问题的函数,实际上,就在 OP 中显示的 kzalloc 调用之后,我们找到了以下内容,它设置了ssidsandie指针:

if (n_ssids)
    request->ssids = (void *)&request->channels[n_channels];
request->n_ssids = n_ssids;
if (ie_len) {
    if (n_ssids)
        request->ie = (void *)(request->ssids + n_ssids);
    else
        request->ie = (void *)(request->channels + n_channels);
}
于 2020-04-05T14:06:23.973 回答