Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mei: bus: make a client pointer always available

Change life time of the client pointer, allocate it upon client device
creation and free it upon device destruction, instead of upon
connection and disconnection.
This helps to eliminate racy NULL checks in the bus code.

Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com>
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Alexander Usyskin and committed by
Greg Kroah-Hartman
c110cdb1 bd47b526

+15 -16
+15 -16
drivers/misc/mei/bus.c
··· 187 187 { 188 188 struct mei_cl *cl = cldev->cl; 189 189 190 - if (cl == NULL) 191 - return -ENODEV; 192 - 193 190 return __mei_cl_send(cl, buf, length, MEI_CL_IO_TX_BLOCKING); 194 191 } 195 192 EXPORT_SYMBOL_GPL(mei_cldev_send); ··· 203 206 ssize_t mei_cldev_recv(struct mei_cl_device *cldev, u8 *buf, size_t length) 204 207 { 205 208 struct mei_cl *cl = cldev->cl; 206 - 207 - if (cl == NULL) 208 - return -ENODEV; 209 209 210 210 return __mei_cl_recv(cl, buf, length); 211 211 } ··· 397 403 */ 398 404 bool mei_cldev_enabled(struct mei_cl_device *cldev) 399 405 { 400 - return cldev->cl && mei_cl_is_connected(cldev->cl); 406 + return mei_cl_is_connected(cldev->cl); 401 407 } 402 408 EXPORT_SYMBOL_GPL(mei_cldev_enabled); 403 409 ··· 417 423 418 424 cl = cldev->cl; 419 425 420 - if (!cl) { 426 + if (cl->state == MEI_FILE_UNINITIALIZED) { 421 427 mutex_lock(&bus->device_lock); 422 - cl = mei_cl_alloc_linked(bus); 428 + ret = mei_cl_link(cl); 423 429 mutex_unlock(&bus->device_lock); 424 - if (IS_ERR(cl)) 425 - return PTR_ERR(cl); 430 + if (ret) 431 + return ret; 426 432 /* update pointers */ 427 - cldev->cl = cl; 428 433 cl->cldev = cldev; 429 434 } 430 435 ··· 464 471 struct mei_cl *cl; 465 472 int err; 466 473 467 - if (!cldev || !cldev->cl) 474 + if (!cldev) 468 475 return -ENODEV; 469 476 470 477 cl = cldev->cl; ··· 489 496 /* Flush queues and remove any pending read */ 490 497 mei_cl_flush_queues(cl, NULL); 491 498 mei_cl_unlink(cl); 492 - 493 - kfree(cl); 494 - cldev->cl = NULL; 495 499 496 500 mutex_unlock(&bus->device_lock); 497 501 return err; ··· 744 754 745 755 mei_me_cl_put(cldev->me_cl); 746 756 mei_dev_bus_put(cldev->bus); 757 + kfree(cldev->cl); 747 758 kfree(cldev); 748 759 } 749 760 ··· 777 786 struct mei_me_client *me_cl) 778 787 { 779 788 struct mei_cl_device *cldev; 789 + struct mei_cl *cl; 780 790 781 791 cldev = kzalloc(sizeof(struct mei_cl_device), GFP_KERNEL); 782 792 if (!cldev) 783 793 return NULL; 794 + 795 + cl = mei_cl_allocate(bus); 796 + if (!cl) { 797 + kfree(cldev); 798 + return NULL; 799 + } 784 800 785 801 device_initialize(&cldev->dev); 786 802 cldev->dev.parent = bus->dev; ··· 795 797 cldev->dev.type = &mei_cl_device_type; 796 798 cldev->bus = mei_dev_bus_get(bus); 797 799 cldev->me_cl = mei_me_cl_get(me_cl); 800 + cldev->cl = cl; 798 801 mei_cl_bus_set_name(cldev); 799 802 cldev->is_added = 0; 800 803 INIT_LIST_HEAD(&cldev->bus_list);