Skip to content

Commit 4ded3bf

Browse files
committed
wifi: mac80211: use wiphy locked debugfs for sdata/link
The debugfs files for netdevs (sdata) and links are removed with the wiphy mutex held, which may deadlock. Use the new wiphy locked debugfs to avoid that. Signed-off-by: Johannes Berg <johannes.berg@intel.com>
1 parent 3d529cd commit 4ded3bf

1 file changed

Lines changed: 105 additions & 45 deletions

File tree

net/mac80211/debugfs_netdev.c

Lines changed: 105 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -22,88 +22,148 @@
2222
#include "debugfs_netdev.h"
2323
#include "driver-ops.h"
2424

25+
struct ieee80211_if_read_sdata_data {
26+
ssize_t (*format)(const struct ieee80211_sub_if_data *, char *, int);
27+
struct ieee80211_sub_if_data *sdata;
28+
};
29+
30+
static ssize_t ieee80211_if_read_sdata_handler(struct wiphy *wiphy,
31+
struct file *file,
32+
char *buf,
33+
size_t bufsize,
34+
void *data)
35+
{
36+
struct ieee80211_if_read_sdata_data *d = data;
37+
38+
return d->format(d->sdata, buf, bufsize);
39+
}
40+
2541
static ssize_t ieee80211_if_read_sdata(
26-
struct ieee80211_sub_if_data *sdata,
42+
struct file *file,
2743
char __user *userbuf,
2844
size_t count, loff_t *ppos,
2945
ssize_t (*format)(const struct ieee80211_sub_if_data *sdata, char *, int))
3046
{
47+
struct ieee80211_sub_if_data *sdata = file->private_data;
48+
struct ieee80211_if_read_sdata_data data = {
49+
.format = format,
50+
.sdata = sdata,
51+
};
3152
char buf[200];
32-
ssize_t ret = -EINVAL;
3353

34-
wiphy_lock(sdata->local->hw.wiphy);
35-
ret = (*format)(sdata, buf, sizeof(buf));
36-
wiphy_unlock(sdata->local->hw.wiphy);
54+
return wiphy_locked_debugfs_read(sdata->local->hw.wiphy,
55+
file, buf, sizeof(buf),
56+
userbuf, count, ppos,
57+
ieee80211_if_read_sdata_handler,
58+
&data);
59+
}
3760

38-
if (ret >= 0)
39-
ret = simple_read_from_buffer(userbuf, count, ppos, buf, ret);
61+
struct ieee80211_if_write_sdata_data {
62+
ssize_t (*write)(struct ieee80211_sub_if_data *, const char *, int);
63+
struct ieee80211_sub_if_data *sdata;
64+
};
65+
66+
static ssize_t ieee80211_if_write_sdata_handler(struct wiphy *wiphy,
67+
struct file *file,
68+
char *buf,
69+
size_t count,
70+
void *data)
71+
{
72+
struct ieee80211_if_write_sdata_data *d = data;
4073

41-
return ret;
74+
return d->write(d->sdata, buf, count);
4275
}
4376

4477
static ssize_t ieee80211_if_write_sdata(
45-
struct ieee80211_sub_if_data *sdata,
78+
struct file *file,
4679
const char __user *userbuf,
4780
size_t count, loff_t *ppos,
4881
ssize_t (*write)(struct ieee80211_sub_if_data *sdata, const char *, int))
4982
{
83+
struct ieee80211_sub_if_data *sdata = file->private_data;
84+
struct ieee80211_if_write_sdata_data data = {
85+
.write = write,
86+
.sdata = sdata,
87+
};
5088
char buf[64];
51-
ssize_t ret;
5289

53-
if (count >= sizeof(buf))
54-
return -E2BIG;
90+
return wiphy_locked_debugfs_write(sdata->local->hw.wiphy,
91+
file, buf, sizeof(buf),
92+
userbuf, count,
93+
ieee80211_if_write_sdata_handler,
94+
&data);
95+
}
5596

56-
if (copy_from_user(buf, userbuf, count))
57-
return -EFAULT;
58-
buf[count] = '\0';
97+
struct ieee80211_if_read_link_data {
98+
ssize_t (*format)(const struct ieee80211_link_data *, char *, int);
99+
struct ieee80211_link_data *link;
100+
};
59101

60-
wiphy_lock(sdata->local->hw.wiphy);
61-
ret = (*write)(sdata, buf, count);
62-
wiphy_unlock(sdata->local->hw.wiphy);
102+
static ssize_t ieee80211_if_read_link_handler(struct wiphy *wiphy,
103+
struct file *file,
104+
char *buf,
105+
size_t bufsize,
106+
void *data)
107+
{
108+
struct ieee80211_if_read_link_data *d = data;
63109

64-
return ret;
110+
return d->format(d->link, buf, bufsize);
65111
}
66112

67113
static ssize_t ieee80211_if_read_link(
68-
struct ieee80211_link_data *link,
114+
struct file *file,
69115
char __user *userbuf,
70116
size_t count, loff_t *ppos,
71117
ssize_t (*format)(const struct ieee80211_link_data *link, char *, int))
72118
{
119+
struct ieee80211_link_data *link = file->private_data;
120+
struct ieee80211_if_read_link_data data = {
121+
.format = format,
122+
.link = link,
123+
};
73124
char buf[200];
74-
ssize_t ret = -EINVAL;
75125

76-
wiphy_lock(link->sdata->local->hw.wiphy);
77-
ret = (*format)(link, buf, sizeof(buf));
78-
wiphy_unlock(link->sdata->local->hw.wiphy);
126+
return wiphy_locked_debugfs_read(link->sdata->local->hw.wiphy,
127+
file, buf, sizeof(buf),
128+
userbuf, count, ppos,
129+
ieee80211_if_read_link_handler,
130+
&data);
131+
}
132+
133+
struct ieee80211_if_write_link_data {
134+
ssize_t (*write)(struct ieee80211_link_data *, const char *, int);
135+
struct ieee80211_link_data *link;
136+
};
79137

80-
if (ret >= 0)
81-
ret = simple_read_from_buffer(userbuf, count, ppos, buf, ret);
138+
static ssize_t ieee80211_if_write_link_handler(struct wiphy *wiphy,
139+
struct file *file,
140+
char *buf,
141+
size_t count,
142+
void *data)
143+
{
144+
struct ieee80211_if_write_sdata_data *d = data;
82145

83-
return ret;
146+
return d->write(d->sdata, buf, count);
84147
}
85148

86149
static ssize_t ieee80211_if_write_link(
87-
struct ieee80211_link_data *link,
150+
struct file *file,
88151
const char __user *userbuf,
89152
size_t count, loff_t *ppos,
90153
ssize_t (*write)(struct ieee80211_link_data *link, const char *, int))
91154
{
155+
struct ieee80211_link_data *link = file->private_data;
156+
struct ieee80211_if_write_link_data data = {
157+
.write = write,
158+
.link = link,
159+
};
92160
char buf[64];
93-
ssize_t ret;
94-
95-
if (count >= sizeof(buf))
96-
return -E2BIG;
97-
98-
if (copy_from_user(buf, userbuf, count))
99-
return -EFAULT;
100-
buf[count] = '\0';
101-
102-
wiphy_lock(link->sdata->local->hw.wiphy);
103-
ret = (*write)(link, buf, count);
104-
wiphy_unlock(link->sdata->local->hw.wiphy);
105161

106-
return ret;
162+
return wiphy_locked_debugfs_write(link->sdata->local->hw.wiphy,
163+
file, buf, sizeof(buf),
164+
userbuf, count,
165+
ieee80211_if_write_link_handler,
166+
&data);
107167
}
108168

109169
#define IEEE80211_IF_FMT(name, type, field, format_string) \
@@ -173,7 +233,7 @@ static ssize_t ieee80211_if_read_##name(struct file *file, \
173233
char __user *userbuf, \
174234
size_t count, loff_t *ppos) \
175235
{ \
176-
return ieee80211_if_read_sdata(file->private_data, \
236+
return ieee80211_if_read_sdata(file, \
177237
userbuf, count, ppos, \
178238
ieee80211_if_fmt_##name); \
179239
}
@@ -183,7 +243,7 @@ static ssize_t ieee80211_if_write_##name(struct file *file, \
183243
const char __user *userbuf, \
184244
size_t count, loff_t *ppos) \
185245
{ \
186-
return ieee80211_if_write_sdata(file->private_data, userbuf, \
246+
return ieee80211_if_write_sdata(file, userbuf, \
187247
count, ppos, \
188248
ieee80211_if_parse_##name); \
189249
}
@@ -211,7 +271,7 @@ static ssize_t ieee80211_if_read_##name(struct file *file, \
211271
char __user *userbuf, \
212272
size_t count, loff_t *ppos) \
213273
{ \
214-
return ieee80211_if_read_link(file->private_data, \
274+
return ieee80211_if_read_link(file, \
215275
userbuf, count, ppos, \
216276
ieee80211_if_fmt_##name); \
217277
}
@@ -221,7 +281,7 @@ static ssize_t ieee80211_if_write_##name(struct file *file, \
221281
const char __user *userbuf, \
222282
size_t count, loff_t *ppos) \
223283
{ \
224-
return ieee80211_if_write_link(file->private_data, userbuf, \
284+
return ieee80211_if_write_link(file, userbuf, \
225285
count, ppos, \
226286
ieee80211_if_parse_##name); \
227287
}

0 commit comments

Comments
 (0)