Skip to content

Commit 55aeed0

Browse files
jgunthorpedledford
authored andcommitted
IB/core: Make ib_alloc_device init the kobject
This gets rid of the weird in-between state where struct ib_device was allocated but the kobject didn't work. Consequently ib_device_release is now guaranteed to be called in all situations and we needn't duplicate its kfrees on error paths. Signed-off-by: Jason Gunthorpe <[email protected]> Signed-off-by: Doug Ledford <[email protected]>
1 parent e999869 commit 55aeed0

File tree

4 files changed

+68
-87
lines changed

4 files changed

+68
-87
lines changed

drivers/infiniband/core/cache.c

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -351,10 +351,10 @@ static void ib_cache_setup_one(struct ib_device *device)
351351
rwlock_init(&device->cache.lock);
352352

353353
device->cache.pkey_cache =
354-
kmalloc(sizeof *device->cache.pkey_cache *
354+
kzalloc(sizeof *device->cache.pkey_cache *
355355
(rdma_end_port(device) - rdma_start_port(device) + 1), GFP_KERNEL);
356356
device->cache.gid_cache =
357-
kmalloc(sizeof *device->cache.gid_cache *
357+
kzalloc(sizeof *device->cache.gid_cache *
358358
(rdma_end_port(device) - rdma_start_port(device) + 1), GFP_KERNEL);
359359

360360
device->cache.lmc_cache = kmalloc(sizeof *device->cache.lmc_cache *
@@ -369,11 +369,8 @@ static void ib_cache_setup_one(struct ib_device *device)
369369
goto err;
370370
}
371371

372-
for (p = 0; p <= rdma_end_port(device) - rdma_start_port(device); ++p) {
373-
device->cache.pkey_cache[p] = NULL;
374-
device->cache.gid_cache [p] = NULL;
372+
for (p = 0; p <= rdma_end_port(device) - rdma_start_port(device); ++p)
375373
ib_cache_update(device, p + rdma_start_port(device));
376-
}
377374

378375
INIT_IB_EVENT_HANDLER(&device->cache.event_handler,
379376
device, ib_cache_event);

drivers/infiniband/core/core_priv.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,6 @@ int ib_device_register_sysfs(struct ib_device *device,
4343
u8, struct kobject *));
4444
void ib_device_unregister_sysfs(struct ib_device *device);
4545

46-
int ib_sysfs_setup(void);
47-
void ib_sysfs_cleanup(void);
48-
4946
int ib_cache_setup(void);
5047
void ib_cache_cleanup(void);
5148

drivers/infiniband/core/device.c

Lines changed: 60 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,35 @@ static int alloc_name(char *name)
165165
return 0;
166166
}
167167

168+
static void ib_device_release(struct device *device)
169+
{
170+
struct ib_device *dev = container_of(device, struct ib_device, dev);
171+
172+
kfree(dev->port_immutable);
173+
kfree(dev);
174+
}
175+
176+
static int ib_device_uevent(struct device *device,
177+
struct kobj_uevent_env *env)
178+
{
179+
struct ib_device *dev = container_of(device, struct ib_device, dev);
180+
181+
if (add_uevent_var(env, "NAME=%s", dev->name))
182+
return -ENOMEM;
183+
184+
/*
185+
* It would be nice to pass the node GUID with the event...
186+
*/
187+
188+
return 0;
189+
}
190+
191+
static struct class ib_class = {
192+
.name = "infiniband",
193+
.dev_release = ib_device_release,
194+
.dev_uevent = ib_device_uevent,
195+
};
196+
168197
/**
169198
* ib_alloc_device - allocate an IB device struct
170199
* @size:size of structure to allocate
@@ -177,9 +206,27 @@ static int alloc_name(char *name)
177206
*/
178207
struct ib_device *ib_alloc_device(size_t size)
179208
{
180-
BUG_ON(size < sizeof (struct ib_device));
209+
struct ib_device *device;
210+
211+
if (WARN_ON(size < sizeof(struct ib_device)))
212+
return NULL;
213+
214+
device = kzalloc(size, GFP_KERNEL);
215+
if (!device)
216+
return NULL;
217+
218+
device->dev.class = &ib_class;
219+
device_initialize(&device->dev);
220+
221+
dev_set_drvdata(&device->dev, device);
222+
223+
INIT_LIST_HEAD(&device->event_handler_list);
224+
spin_lock_init(&device->event_handler_lock);
225+
spin_lock_init(&device->client_data_lock);
226+
INIT_LIST_HEAD(&device->client_data_list);
227+
INIT_LIST_HEAD(&device->port_list);
181228

182-
return kzalloc(size, GFP_KERNEL);
229+
return device;
183230
}
184231
EXPORT_SYMBOL(ib_alloc_device);
185232

@@ -191,13 +238,8 @@ EXPORT_SYMBOL(ib_alloc_device);
191238
*/
192239
void ib_dealloc_device(struct ib_device *device)
193240
{
194-
if (device->reg_state == IB_DEV_UNINITIALIZED) {
195-
kfree(device);
196-
return;
197-
}
198-
199-
BUG_ON(device->reg_state != IB_DEV_UNREGISTERED);
200-
241+
WARN_ON(device->reg_state != IB_DEV_UNREGISTERED &&
242+
device->reg_state != IB_DEV_UNINITIALIZED);
201243
kobject_put(&device->dev.kobj);
202244
}
203245
EXPORT_SYMBOL(ib_dealloc_device);
@@ -235,7 +277,7 @@ static int verify_immutable(const struct ib_device *dev, u8 port)
235277

236278
static int read_port_immutable(struct ib_device *device)
237279
{
238-
int ret = -ENOMEM;
280+
int ret;
239281
u8 start_port = rdma_start_port(device);
240282
u8 end_port = rdma_end_port(device);
241283
u8 port;
@@ -251,26 +293,18 @@ static int read_port_immutable(struct ib_device *device)
251293
* (end_port + 1),
252294
GFP_KERNEL);
253295
if (!device->port_immutable)
254-
goto err;
296+
return -ENOMEM;
255297

256298
for (port = start_port; port <= end_port; ++port) {
257299
ret = device->get_port_immutable(device, port,
258300
&device->port_immutable[port]);
259301
if (ret)
260-
goto err;
302+
return ret;
261303

262-
if (verify_immutable(device, port)) {
263-
ret = -EINVAL;
264-
goto err;
265-
}
304+
if (verify_immutable(device, port))
305+
return -EINVAL;
266306
}
267-
268-
ret = 0;
269-
goto out;
270-
err:
271-
kfree(device->port_immutable);
272-
out:
273-
return ret;
307+
return 0;
274308
}
275309

276310
/**
@@ -301,11 +335,6 @@ int ib_register_device(struct ib_device *device,
301335
goto out;
302336
}
303337

304-
INIT_LIST_HEAD(&device->event_handler_list);
305-
INIT_LIST_HEAD(&device->client_data_list);
306-
spin_lock_init(&device->event_handler_lock);
307-
spin_lock_init(&device->client_data_lock);
308-
309338
ret = read_port_immutable(device);
310339
if (ret) {
311340
printk(KERN_WARNING "Couldn't create per port immutable data %s\n",
@@ -317,7 +346,6 @@ int ib_register_device(struct ib_device *device,
317346
if (ret) {
318347
printk(KERN_WARNING "Couldn't register device %s with driver model\n",
319348
device->name);
320-
kfree(device->port_immutable);
321349
goto out;
322350
}
323351

@@ -834,7 +862,7 @@ static int __init ib_core_init(void)
834862
if (!ib_wq)
835863
return -ENOMEM;
836864

837-
ret = ib_sysfs_setup();
865+
ret = class_register(&ib_class);
838866
if (ret) {
839867
printk(KERN_WARNING "Couldn't create InfiniBand device class\n");
840868
goto err;
@@ -858,7 +886,7 @@ static int __init ib_core_init(void)
858886
ibnl_cleanup();
859887

860888
err_sysfs:
861-
ib_sysfs_cleanup();
889+
class_unregister(&ib_class);
862890

863891
err:
864892
destroy_workqueue(ib_wq);
@@ -869,7 +897,7 @@ static void __exit ib_core_cleanup(void)
869897
{
870898
ib_cache_cleanup();
871899
ibnl_cleanup();
872-
ib_sysfs_cleanup();
900+
class_unregister(&ib_class);
873901
/* Make sure that any pending umem accounting work is done. */
874902
destroy_workqueue(ib_wq);
875903
}

drivers/infiniband/core/sysfs.c

Lines changed: 5 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -457,29 +457,6 @@ static struct kobj_type port_type = {
457457
.default_attrs = port_default_attrs
458458
};
459459

460-
static void ib_device_release(struct device *device)
461-
{
462-
struct ib_device *dev = container_of(device, struct ib_device, dev);
463-
464-
kfree(dev->port_immutable);
465-
kfree(dev);
466-
}
467-
468-
static int ib_device_uevent(struct device *device,
469-
struct kobj_uevent_env *env)
470-
{
471-
struct ib_device *dev = container_of(device, struct ib_device, dev);
472-
473-
if (add_uevent_var(env, "NAME=%s", dev->name))
474-
return -ENOMEM;
475-
476-
/*
477-
* It would be nice to pass the node GUID with the event...
478-
*/
479-
480-
return 0;
481-
}
482-
483460
static struct attribute **
484461
alloc_group_attrs(ssize_t (*show)(struct ib_port *,
485462
struct port_attribute *, char *buf),
@@ -702,12 +679,6 @@ static struct device_attribute *ib_class_attributes[] = {
702679
&dev_attr_node_desc
703680
};
704681

705-
static struct class ib_class = {
706-
.name = "infiniband",
707-
.dev_release = ib_device_release,
708-
.dev_uevent = ib_device_uevent,
709-
};
710-
711682
/* Show a given an attribute in the statistics group */
712683
static ssize_t show_protocol_stat(const struct device *device,
713684
struct device_attribute *attr, char *buf,
@@ -846,14 +817,12 @@ int ib_device_register_sysfs(struct ib_device *device,
846817
int ret;
847818
int i;
848819

849-
class_dev->class = &ib_class;
850-
class_dev->parent = device->dma_device;
851-
dev_set_name(class_dev, "%s", device->name);
852-
dev_set_drvdata(class_dev, device);
853-
854-
INIT_LIST_HEAD(&device->port_list);
820+
device->dev.parent = device->dma_device;
821+
ret = dev_set_name(class_dev, "%s", device->name);
822+
if (ret)
823+
return ret;
855824

856-
ret = device_register(class_dev);
825+
ret = device_add(class_dev);
857826
if (ret)
858827
goto err;
859828

@@ -916,13 +885,3 @@ void ib_device_unregister_sysfs(struct ib_device *device)
916885

917886
device_unregister(&device->dev);
918887
}
919-
920-
int ib_sysfs_setup(void)
921-
{
922-
return class_register(&ib_class);
923-
}
924-
925-
void ib_sysfs_cleanup(void)
926-
{
927-
class_unregister(&ib_class);
928-
}

0 commit comments

Comments
 (0)