17
17
static DEFINE_IDA (nsim_bus_dev_ids );
18
18
static LIST_HEAD (nsim_bus_dev_list );
19
19
static DEFINE_MUTEX (nsim_bus_dev_list_lock );
20
+ static bool nsim_bus_enable ;
20
21
21
22
static struct nsim_bus_dev * to_nsim_bus_dev (struct device * dev )
22
23
{
@@ -99,6 +100,9 @@ new_port_store(struct device *dev, struct device_attribute *attr,
99
100
unsigned int port_index ;
100
101
int ret ;
101
102
103
+ /* Prevent to use nsim_bus_dev before initialization. */
104
+ if (!smp_load_acquire (& nsim_bus_dev -> init ))
105
+ return - EBUSY ;
102
106
ret = kstrtouint (buf , 0 , & port_index );
103
107
if (ret )
104
108
return ret ;
@@ -116,6 +120,9 @@ del_port_store(struct device *dev, struct device_attribute *attr,
116
120
unsigned int port_index ;
117
121
int ret ;
118
122
123
+ /* Prevent to use nsim_bus_dev before initialization. */
124
+ if (!smp_load_acquire (& nsim_bus_dev -> init ))
125
+ return - EBUSY ;
119
126
ret = kstrtouint (buf , 0 , & port_index );
120
127
if (ret )
121
128
return ret ;
@@ -179,15 +186,30 @@ new_device_store(struct bus_type *bus, const char *buf, size_t count)
179
186
pr_err ("Format for adding new device is \"id port_count\" (uint uint).\n" );
180
187
return - EINVAL ;
181
188
}
182
- nsim_bus_dev = nsim_bus_dev_new (id , port_count );
183
- if (IS_ERR (nsim_bus_dev ))
184
- return PTR_ERR (nsim_bus_dev );
185
189
186
190
mutex_lock (& nsim_bus_dev_list_lock );
191
+ /* Prevent to use resource before initialization. */
192
+ if (!smp_load_acquire (& nsim_bus_enable )) {
193
+ err = - EBUSY ;
194
+ goto err ;
195
+ }
196
+
197
+ nsim_bus_dev = nsim_bus_dev_new (id , port_count );
198
+ if (IS_ERR (nsim_bus_dev )) {
199
+ err = PTR_ERR (nsim_bus_dev );
200
+ goto err ;
201
+ }
202
+
203
+ /* Allow using nsim_bus_dev */
204
+ smp_store_release (& nsim_bus_dev -> init , true);
205
+
187
206
list_add_tail (& nsim_bus_dev -> list , & nsim_bus_dev_list );
188
207
mutex_unlock (& nsim_bus_dev_list_lock );
189
208
190
209
return count ;
210
+ err :
211
+ mutex_unlock (& nsim_bus_dev_list_lock );
212
+ return err ;
191
213
}
192
214
static BUS_ATTR_WO (new_device );
193
215
@@ -215,6 +237,11 @@ del_device_store(struct bus_type *bus, const char *buf, size_t count)
215
237
216
238
err = - ENOENT ;
217
239
mutex_lock (& nsim_bus_dev_list_lock );
240
+ /* Prevent to use resource before initialization. */
241
+ if (!smp_load_acquire (& nsim_bus_enable )) {
242
+ mutex_unlock (& nsim_bus_dev_list_lock );
243
+ return - EBUSY ;
244
+ }
218
245
list_for_each_entry_safe (nsim_bus_dev , tmp , & nsim_bus_dev_list , list ) {
219
246
if (nsim_bus_dev -> dev .id != id )
220
247
continue ;
@@ -284,6 +311,8 @@ nsim_bus_dev_new(unsigned int id, unsigned int port_count)
284
311
nsim_bus_dev -> dev .type = & nsim_bus_dev_type ;
285
312
nsim_bus_dev -> port_count = port_count ;
286
313
nsim_bus_dev -> initial_net = current -> nsproxy -> net_ns ;
314
+ /* Disallow using nsim_bus_dev */
315
+ smp_store_release (& nsim_bus_dev -> init , false);
287
316
288
317
err = device_register (& nsim_bus_dev -> dev );
289
318
if (err )
@@ -299,6 +328,8 @@ nsim_bus_dev_new(unsigned int id, unsigned int port_count)
299
328
300
329
static void nsim_bus_dev_del (struct nsim_bus_dev * nsim_bus_dev )
301
330
{
331
+ /* Disallow using nsim_bus_dev */
332
+ smp_store_release (& nsim_bus_dev -> init , false);
302
333
device_unregister (& nsim_bus_dev -> dev );
303
334
ida_free (& nsim_bus_dev_ids , nsim_bus_dev -> dev .id );
304
335
kfree (nsim_bus_dev );
@@ -320,6 +351,8 @@ int nsim_bus_init(void)
320
351
err = driver_register (& nsim_driver );
321
352
if (err )
322
353
goto err_bus_unregister ;
354
+ /* Allow using resources */
355
+ smp_store_release (& nsim_bus_enable , true);
323
356
return 0 ;
324
357
325
358
err_bus_unregister :
@@ -331,12 +364,16 @@ void nsim_bus_exit(void)
331
364
{
332
365
struct nsim_bus_dev * nsim_bus_dev , * tmp ;
333
366
367
+ /* Disallow using resources */
368
+ smp_store_release (& nsim_bus_enable , false);
369
+
334
370
mutex_lock (& nsim_bus_dev_list_lock );
335
371
list_for_each_entry_safe (nsim_bus_dev , tmp , & nsim_bus_dev_list , list ) {
336
372
list_del (& nsim_bus_dev -> list );
337
373
nsim_bus_dev_del (nsim_bus_dev );
338
374
}
339
375
mutex_unlock (& nsim_bus_dev_list_lock );
376
+
340
377
driver_unregister (& nsim_driver );
341
378
bus_unregister (& nsim_bus );
342
379
}
0 commit comments