Skip to content

Commit 022b66f

Browse files
l1kdjbw
authored andcommitted
PCI/DOE: Allow mailbox creation without devres management
DOE mailbox creation is currently only possible through a devres-managed API. The lifetime of mailboxes thus ends with driver unbinding. An upcoming commit will create DOE mailboxes upon device enumeration by the PCI core. Their lifetime shall not be limited by a driver. Therefore rework pcim_doe_create_mb() into the non-devres-managed pci_doe_create_mb(). Add pci_doe_destroy_mb() for mailbox destruction on device removal. Provide a devres-managed wrapper under the existing pcim_doe_create_mb() name. The error path of pcim_doe_create_mb() previously called xa_destroy() if alloc_ordered_workqueue() failed. That's unnecessary because the xarray is still empty at that point. It doesn't need to be destroyed until it's been populated by pci_doe_cache_protocols(). Arrange the error path of the new pci_doe_create_mb() accordingly. pci_doe_cancel_tasks() is no longer used as callback for devm_add_action(), so refactor it to accept a struct pci_doe_mb pointer instead of a generic void pointer. Tested-by: Ira Weiny <ira.weiny@intel.com> Signed-off-by: Lukas Wunner <lukas@wunner.de> Reviewed-by: Ming Li <ming4.li@intel.com> Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> Acked-by: Bjorn Helgaas <bhelgaas@google.com> Link: https://lore.kernel.org/r/7c9a63867d70233c5e9d26cd8bf956742cd6d650.1678543498.git.lukas@wunner.de Signed-off-by: Dan Williams <dan.j.williams@intel.com>
1 parent c8fc07a commit 022b66f

1 file changed

Lines changed: 66 additions & 37 deletions

File tree

drivers/pci/doe.c

Lines changed: 66 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
*
3838
* This state is used to manage a single DOE mailbox capability. All fields
3939
* should be considered opaque to the consumers and the structure passed into
40-
* the helpers below after being created by devm_pci_doe_create()
40+
* the helpers below after being created by pci_doe_create_mb().
4141
*
4242
* @pdev: PCI device this mailbox belongs to
4343
* @cap_offset: Capability offset
@@ -415,24 +415,8 @@ static int pci_doe_cache_protocols(struct pci_doe_mb *doe_mb)
415415
return 0;
416416
}
417417

418-
static void pci_doe_xa_destroy(void *mb)
418+
static void pci_doe_cancel_tasks(struct pci_doe_mb *doe_mb)
419419
{
420-
struct pci_doe_mb *doe_mb = mb;
421-
422-
xa_destroy(&doe_mb->prots);
423-
}
424-
425-
static void pci_doe_destroy_workqueue(void *mb)
426-
{
427-
struct pci_doe_mb *doe_mb = mb;
428-
429-
destroy_workqueue(doe_mb->work_queue);
430-
}
431-
432-
static void pci_doe_cancel_tasks(void *mb)
433-
{
434-
struct pci_doe_mb *doe_mb = mb;
435-
436420
/* Stop all pending work items from starting */
437421
set_bit(PCI_DOE_FLAG_DEAD, &doe_mb->flags);
438422

@@ -442,7 +426,7 @@ static void pci_doe_cancel_tasks(void *mb)
442426
}
443427

444428
/**
445-
* pcim_doe_create_mb() - Create a DOE mailbox object
429+
* pci_doe_create_mb() - Create a DOE mailbox object
446430
*
447431
* @pdev: PCI device to create the DOE mailbox for
448432
* @cap_offset: Offset of the DOE mailbox
@@ -453,24 +437,20 @@ static void pci_doe_cancel_tasks(void *mb)
453437
* RETURNS: created mailbox object on success
454438
* ERR_PTR(-errno) on failure
455439
*/
456-
struct pci_doe_mb *pcim_doe_create_mb(struct pci_dev *pdev, u16 cap_offset)
440+
static struct pci_doe_mb *pci_doe_create_mb(struct pci_dev *pdev,
441+
u16 cap_offset)
457442
{
458443
struct pci_doe_mb *doe_mb;
459-
struct device *dev = &pdev->dev;
460444
int rc;
461445

462-
doe_mb = devm_kzalloc(dev, sizeof(*doe_mb), GFP_KERNEL);
446+
doe_mb = kzalloc(sizeof(*doe_mb), GFP_KERNEL);
463447
if (!doe_mb)
464448
return ERR_PTR(-ENOMEM);
465449

466450
doe_mb->pdev = pdev;
467451
doe_mb->cap_offset = cap_offset;
468452
init_waitqueue_head(&doe_mb->wq);
469-
470453
xa_init(&doe_mb->prots);
471-
rc = devm_add_action(dev, pci_doe_xa_destroy, doe_mb);
472-
if (rc)
473-
return ERR_PTR(rc);
474454

475455
doe_mb->work_queue = alloc_ordered_workqueue("%s %s DOE [%x]", 0,
476456
dev_driver_string(&pdev->dev),
@@ -479,36 +459,85 @@ struct pci_doe_mb *pcim_doe_create_mb(struct pci_dev *pdev, u16 cap_offset)
479459
if (!doe_mb->work_queue) {
480460
pci_err(pdev, "[%x] failed to allocate work queue\n",
481461
doe_mb->cap_offset);
482-
return ERR_PTR(-ENOMEM);
462+
rc = -ENOMEM;
463+
goto err_free;
483464
}
484-
rc = devm_add_action_or_reset(dev, pci_doe_destroy_workqueue, doe_mb);
485-
if (rc)
486-
return ERR_PTR(rc);
487465

488466
/* Reset the mailbox by issuing an abort */
489467
rc = pci_doe_abort(doe_mb);
490468
if (rc) {
491469
pci_err(pdev, "[%x] failed to reset mailbox with abort command : %d\n",
492470
doe_mb->cap_offset, rc);
493-
return ERR_PTR(rc);
471+
goto err_destroy_wq;
494472
}
495473

496474
/*
497475
* The state machine and the mailbox should be in sync now;
498-
* Set up cancel tasks prior to using the mailbox to query protocols.
476+
* Use the mailbox to query protocols.
499477
*/
500-
rc = devm_add_action_or_reset(dev, pci_doe_cancel_tasks, doe_mb);
501-
if (rc)
502-
return ERR_PTR(rc);
503-
504478
rc = pci_doe_cache_protocols(doe_mb);
505479
if (rc) {
506480
pci_err(pdev, "[%x] failed to cache protocols : %d\n",
507481
doe_mb->cap_offset, rc);
508-
return ERR_PTR(rc);
482+
goto err_cancel;
509483
}
510484

511485
return doe_mb;
486+
487+
err_cancel:
488+
pci_doe_cancel_tasks(doe_mb);
489+
xa_destroy(&doe_mb->prots);
490+
err_destroy_wq:
491+
destroy_workqueue(doe_mb->work_queue);
492+
err_free:
493+
kfree(doe_mb);
494+
return ERR_PTR(rc);
495+
}
496+
497+
/**
498+
* pci_doe_destroy_mb() - Destroy a DOE mailbox object
499+
*
500+
* @ptr: Pointer to DOE mailbox
501+
*
502+
* Destroy all internal data structures created for the DOE mailbox.
503+
*/
504+
static void pci_doe_destroy_mb(void *ptr)
505+
{
506+
struct pci_doe_mb *doe_mb = ptr;
507+
508+
pci_doe_cancel_tasks(doe_mb);
509+
xa_destroy(&doe_mb->prots);
510+
destroy_workqueue(doe_mb->work_queue);
511+
kfree(doe_mb);
512+
}
513+
514+
/**
515+
* pcim_doe_create_mb() - Create a DOE mailbox object
516+
*
517+
* @pdev: PCI device to create the DOE mailbox for
518+
* @cap_offset: Offset of the DOE mailbox
519+
*
520+
* Create a single mailbox object to manage the mailbox protocol at the
521+
* cap_offset specified. The mailbox will automatically be destroyed on
522+
* driver unbinding from @pdev.
523+
*
524+
* RETURNS: created mailbox object on success
525+
* ERR_PTR(-errno) on failure
526+
*/
527+
struct pci_doe_mb *pcim_doe_create_mb(struct pci_dev *pdev, u16 cap_offset)
528+
{
529+
struct pci_doe_mb *doe_mb;
530+
int rc;
531+
532+
doe_mb = pci_doe_create_mb(pdev, cap_offset);
533+
if (IS_ERR(doe_mb))
534+
return doe_mb;
535+
536+
rc = devm_add_action_or_reset(&pdev->dev, pci_doe_destroy_mb, doe_mb);
537+
if (rc)
538+
return ERR_PTR(rc);
539+
540+
return doe_mb;
512541
}
513542
EXPORT_SYMBOL_GPL(pcim_doe_create_mb);
514543

0 commit comments

Comments
 (0)