diff mbox series

[v4,07/14] net-next/yunsilicon: Init auxiliary device

Message ID 20250213091418.2067626-8-tianx@yunsilicon.com (mailing list archive)
State Changes Requested
Delegated to: Netdev Maintainers
Headers show
Series net-next/yunsilicon: ADD Yunsilicon XSC Ethernet Driver | expand

Checks

Context Check Description
netdev/series_format success Posting correctly formatted
netdev/tree_selection success Guessed tree name to be net-next, async
netdev/ynl success Generated files up to date; no warnings/errors; no diff in generated;
netdev/fixes_present success Fixes tag not required for -next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 0 this patch: 0
netdev/build_tools success No tools touched, skip
netdev/cc_maintainers warning 1 maintainers not CCed: jacky@yunsilicon.com
netdev/build_clang fail Errors and warnings before: 56 this patch: 59
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn success Errors and warnings before: 22 this patch: 22
netdev/checkpatch warning WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
netdev/build_clang_rust success No Rust files in patch. Skipping build
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0

Commit Message

tianx Feb. 13, 2025, 9:14 a.m. UTC
Initialize eth auxiliary device when pci probing

Co-developed-by: Honggang Wei <weihg@yunsilicon.com>
Signed-off-by: Honggang Wei <weihg@yunsilicon.com>
Co-developed-by: Lei Yan <jacky@yunsilicon.com>
Signed-off-by: Lei Yan <jacky@yunsilicon.com>
Signed-off-by: Xin Tian <tianx@yunsilicon.com>
---
 .../ethernet/yunsilicon/xsc/common/xsc_core.h |  12 ++
 .../net/ethernet/yunsilicon/xsc/pci/Makefile  |   3 +-
 .../net/ethernet/yunsilicon/xsc/pci/adev.c    | 110 ++++++++++++++++++
 .../net/ethernet/yunsilicon/xsc/pci/adev.h    |  14 +++
 .../net/ethernet/yunsilicon/xsc/pci/main.c    |  10 ++
 5 files changed, 148 insertions(+), 1 deletion(-)
 create mode 100644 drivers/net/ethernet/yunsilicon/xsc/pci/adev.c
 create mode 100644 drivers/net/ethernet/yunsilicon/xsc/pci/adev.h

Comments

Leon Romanovsky Feb. 13, 2025, 2:37 p.m. UTC | #1
On Thu, Feb 13, 2025 at 05:14:19PM +0800, Xin Tian wrote:
> Initialize eth auxiliary device when pci probing
> 
> Co-developed-by: Honggang Wei <weihg@yunsilicon.com>
> Signed-off-by: Honggang Wei <weihg@yunsilicon.com>
> Co-developed-by: Lei Yan <jacky@yunsilicon.com>
> Signed-off-by: Lei Yan <jacky@yunsilicon.com>
> Signed-off-by: Xin Tian <tianx@yunsilicon.com>
> ---
>  .../ethernet/yunsilicon/xsc/common/xsc_core.h |  12 ++
>  .../net/ethernet/yunsilicon/xsc/pci/Makefile  |   3 +-
>  .../net/ethernet/yunsilicon/xsc/pci/adev.c    | 110 ++++++++++++++++++
>  .../net/ethernet/yunsilicon/xsc/pci/adev.h    |  14 +++
>  .../net/ethernet/yunsilicon/xsc/pci/main.c    |  10 ++
>  5 files changed, 148 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/net/ethernet/yunsilicon/xsc/pci/adev.c
>  create mode 100644 drivers/net/ethernet/yunsilicon/xsc/pci/adev.h

<...>

> diff --git a/drivers/net/ethernet/yunsilicon/xsc/pci/adev.c b/drivers/net/ethernet/yunsilicon/xsc/pci/adev.c
> new file mode 100644
> index 000000000..1f8f27d72
> --- /dev/null
> +++ b/drivers/net/ethernet/yunsilicon/xsc/pci/adev.c
> @@ -0,0 +1,110 @@
> +// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
> +/*
> + * Copyright (C) 2021-2025, Shanghai Yunsilicon Technology Co., Ltd.
> + * All rights reserved.
> + */
> +
> +#include <linux/auxiliary_bus.h>
> +#include <linux/idr.h>
> +
> +#include "adev.h"
> +
> +static DEFINE_IDA(xsc_adev_ida);
> +
> +enum xsc_adev_idx {
> +	XSC_ADEV_IDX_ETH,
> +	XSC_ADEV_IDX_MAX
> +};
> +
> +static const char * const xsc_adev_name[] = {
> +	[XSC_ADEV_IDX_ETH] = XSC_ETH_ADEV_NAME,
> +};
> +
> +static void xsc_release_adev(struct device *dev)
> +{
> +	/* Doing nothing, but auxiliary bus requires a release function */
> +}

It is unlikely to be true in driver lifetime model. At least you should
free xsc_adev here.

Thanks

> +
> +static int xsc_reg_adev(struct xsc_core_device *xdev, int idx)
> +{
> +	struct auxiliary_device	*adev;
> +	struct xsc_adev *xsc_adev;
> +	int ret;
> +
> +	xsc_adev = kzalloc(sizeof(*xsc_adev), GFP_KERNEL);
> +	if (!xsc_adev)
> +		return -ENOMEM;
> +
> +	adev = &xsc_adev->adev;
> +	adev->name = xsc_adev_name[idx];
> +	adev->id = xdev->adev_id;
> +	adev->dev.parent = &xdev->pdev->dev;
> +	adev->dev.release = xsc_release_adev;
> +	xsc_adev->xdev = xdev;
> +
> +	ret = auxiliary_device_init(adev);
> +	if (ret)
> +		goto err_free_adev;
> +
> +	ret = auxiliary_device_add(adev);
> +	if (ret)
> +		goto err_uninit_adev;
> +
> +	xdev->xsc_adev_list[idx] = xsc_adev;
> +
> +	return 0;
> +err_uninit_adev:
> +	auxiliary_device_uninit(adev);
> +err_free_adev:
> +	kfree(xsc_adev);
> +
> +	return ret;
> +}
tianx Feb. 14, 2025, 3:14 a.m. UTC | #2
On 2025/2/13 22:37, Leon Romanovsky wrote:
> On Thu, Feb 13, 2025 at 05:14:19PM +0800, Xin Tian wrote:
>> Initialize eth auxiliary device when pci probing
>>
>> Co-developed-by: Honggang Wei <weihg@yunsilicon.com>
>> Signed-off-by: Honggang Wei <weihg@yunsilicon.com>
>> Co-developed-by: Lei Yan <jacky@yunsilicon.com>
>> Signed-off-by: Lei Yan <jacky@yunsilicon.com>
>> Signed-off-by: Xin Tian <tianx@yunsilicon.com>
>> ---
>>   .../ethernet/yunsilicon/xsc/common/xsc_core.h |  12 ++
>>   .../net/ethernet/yunsilicon/xsc/pci/Makefile  |   3 +-
>>   .../net/ethernet/yunsilicon/xsc/pci/adev.c    | 110 ++++++++++++++++++
>>   .../net/ethernet/yunsilicon/xsc/pci/adev.h    |  14 +++
>>   .../net/ethernet/yunsilicon/xsc/pci/main.c    |  10 ++
>>   5 files changed, 148 insertions(+), 1 deletion(-)
>>   create mode 100644 drivers/net/ethernet/yunsilicon/xsc/pci/adev.c
>>   create mode 100644 drivers/net/ethernet/yunsilicon/xsc/pci/adev.h
> <...>
>
>> diff --git a/drivers/net/ethernet/yunsilicon/xsc/pci/adev.c b/drivers/net/ethernet/yunsilicon/xsc/pci/adev.c
>> new file mode 100644
>> index 000000000..1f8f27d72
>> --- /dev/null
>> +++ b/drivers/net/ethernet/yunsilicon/xsc/pci/adev.c
>> @@ -0,0 +1,110 @@
>> +// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
>> +/*
>> + * Copyright (C) 2021-2025, Shanghai Yunsilicon Technology Co., Ltd.
>> + * All rights reserved.
>> + */
>> +
>> +#include <linux/auxiliary_bus.h>
>> +#include <linux/idr.h>
>> +
>> +#include "adev.h"
>> +
>> +static DEFINE_IDA(xsc_adev_ida);
>> +
>> +enum xsc_adev_idx {
>> +	XSC_ADEV_IDX_ETH,
>> +	XSC_ADEV_IDX_MAX
>> +};
>> +
>> +static const char * const xsc_adev_name[] = {
>> +	[XSC_ADEV_IDX_ETH] = XSC_ETH_ADEV_NAME,
>> +};
>> +
>> +static void xsc_release_adev(struct device *dev)
>> +{
>> +	/* Doing nothing, but auxiliary bus requires a release function */
>> +}
> It is unlikely to be true in driver lifetime model. At least you should
> free xsc_adev here.
>
> Thanks

Hi Leon, xsc_adev has already been freed after calling 
auxiliary_device_uninit. If I free it again in the release callback, it 
will cause a double free.

>> +
>> +static int xsc_reg_adev(struct xsc_core_device *xdev, int idx)
>> +{
>> +	struct auxiliary_device	*adev;
>> +	struct xsc_adev *xsc_adev;
>> +	int ret;
>> +
>> +	xsc_adev = kzalloc(sizeof(*xsc_adev), GFP_KERNEL);
>> +	if (!xsc_adev)
>> +		return -ENOMEM;
>> +
>> +	adev = &xsc_adev->adev;
>> +	adev->name = xsc_adev_name[idx];
>> +	adev->id = xdev->adev_id;
>> +	adev->dev.parent = &xdev->pdev->dev;
>> +	adev->dev.release = xsc_release_adev;
>> +	xsc_adev->xdev = xdev;
>> +
>> +	ret = auxiliary_device_init(adev);
>> +	if (ret)
>> +		goto err_free_adev;
>> +
>> +	ret = auxiliary_device_add(adev);
>> +	if (ret)
>> +		goto err_uninit_adev;
>> +
>> +	xdev->xsc_adev_list[idx] = xsc_adev;
>> +
>> +	return 0;
>> +err_uninit_adev:
>> +	auxiliary_device_uninit(adev);
>> +err_free_adev:
>> +	kfree(xsc_adev);
>> +

>> +	return ret;
>> +}
Leon Romanovsky Feb. 16, 2025, 9:59 a.m. UTC | #3
On Fri, Feb 14, 2025 at 11:14:45AM +0800, tianx wrote:
> On 2025/2/13 22:37, Leon Romanovsky wrote:
> > On Thu, Feb 13, 2025 at 05:14:19PM +0800, Xin Tian wrote:
> >> Initialize eth auxiliary device when pci probing
> >>
> >> Co-developed-by: Honggang Wei <weihg@yunsilicon.com>
> >> Signed-off-by: Honggang Wei <weihg@yunsilicon.com>
> >> Co-developed-by: Lei Yan <jacky@yunsilicon.com>
> >> Signed-off-by: Lei Yan <jacky@yunsilicon.com>
> >> Signed-off-by: Xin Tian <tianx@yunsilicon.com>
> >> ---
> >>   .../ethernet/yunsilicon/xsc/common/xsc_core.h |  12 ++
> >>   .../net/ethernet/yunsilicon/xsc/pci/Makefile  |   3 +-
> >>   .../net/ethernet/yunsilicon/xsc/pci/adev.c    | 110 ++++++++++++++++++
> >>   .../net/ethernet/yunsilicon/xsc/pci/adev.h    |  14 +++
> >>   .../net/ethernet/yunsilicon/xsc/pci/main.c    |  10 ++
> >>   5 files changed, 148 insertions(+), 1 deletion(-)
> >>   create mode 100644 drivers/net/ethernet/yunsilicon/xsc/pci/adev.c
> >>   create mode 100644 drivers/net/ethernet/yunsilicon/xsc/pci/adev.h
> > <...>

<...>

> >> +	[XSC_ADEV_IDX_ETH] = XSC_ETH_ADEV_NAME,
> >> +};
> >> +
> >> +static void xsc_release_adev(struct device *dev)
> >> +{
> >> +	/* Doing nothing, but auxiliary bus requires a release function */
> >> +}
> > It is unlikely to be true in driver lifetime model. At least you should
> > free xsc_adev here.
> >
> > Thanks
> 
> Hi Leon, xsc_adev has already been freed after calling 
> auxiliary_device_uninit. If I free it again in the release callback, it 
> will cause a double free.

You should follow standard driver lifetime model. Your
auxiliary_device_uninit() is wrong and shouldn't exist from the
beginning.

Thanks
tianx Feb. 17, 2025, 2:16 a.m. UTC | #4
On 2025/2/16 17:59, Leon Romanovsky wrote:
> On Fri, Feb 14, 2025 at 11:14:45AM +0800, tianx wrote:
>> On 2025/2/13 22:37, Leon Romanovsky wrote:
>>> On Thu, Feb 13, 2025 at 05:14:19PM +0800, Xin Tian wrote:
>>>> Initialize eth auxiliary device when pci probing
>>>>
>>>> Co-developed-by: Honggang Wei <weihg@yunsilicon.com>
>>>> Signed-off-by: Honggang Wei <weihg@yunsilicon.com>
>>>> Co-developed-by: Lei Yan <jacky@yunsilicon.com>
>>>> Signed-off-by: Lei Yan <jacky@yunsilicon.com>
>>>> Signed-off-by: Xin Tian <tianx@yunsilicon.com>
>>>> ---
>>>>    .../ethernet/yunsilicon/xsc/common/xsc_core.h |  12 ++
>>>>    .../net/ethernet/yunsilicon/xsc/pci/Makefile  |   3 +-
>>>>    .../net/ethernet/yunsilicon/xsc/pci/adev.c    | 110 ++++++++++++++++++
>>>>    .../net/ethernet/yunsilicon/xsc/pci/adev.h    |  14 +++
>>>>    .../net/ethernet/yunsilicon/xsc/pci/main.c    |  10 ++
>>>>    5 files changed, 148 insertions(+), 1 deletion(-)
>>>>    create mode 100644 drivers/net/ethernet/yunsilicon/xsc/pci/adev.c
>>>>    create mode 100644 drivers/net/ethernet/yunsilicon/xsc/pci/adev.h
>>> <...>
> <...>
>
>>>> +	[XSC_ADEV_IDX_ETH] = XSC_ETH_ADEV_NAME,
>>>> +};
>>>> +
>>>> +static void xsc_release_adev(struct device *dev)
>>>> +{
>>>> +	/* Doing nothing, but auxiliary bus requires a release function */
>>>> +}
>>> It is unlikely to be true in driver lifetime model. At least you should
>>> free xsc_adev here.
>>>
>>> Thanks
>> Hi Leon, xsc_adev has already been freed after calling
>> auxiliary_device_uninit. If I free it again in the release callback, it
>> will cause a double free.
> You should follow standard driver lifetime model. Your
> auxiliary_device_uninit() is wrong and shouldn't exist from the
> beginning.
>
> Thanks

OK, I'll change it.

Thanks for reviewing.
diff mbox series

Patch

diff --git a/drivers/net/ethernet/yunsilicon/xsc/common/xsc_core.h b/drivers/net/ethernet/yunsilicon/xsc/common/xsc_core.h
index 738823474..c417a2867 100644
--- a/drivers/net/ethernet/yunsilicon/xsc/common/xsc_core.h
+++ b/drivers/net/ethernet/yunsilicon/xsc/common/xsc_core.h
@@ -7,6 +7,7 @@ 
 #define __XSC_CORE_H
 
 #include <linux/pci.h>
+#include <linux/auxiliary_bus.h>
 
 #include "common/xsc_cmdq.h"
 
@@ -222,6 +223,15 @@  struct xsc_irq_info {
 	char name[XSC_MAX_IRQ_NAME];
 };
 
+// adev
+#define XSC_PCI_DRV_NAME "xsc_pci"
+#define XSC_ETH_ADEV_NAME "eth"
+
+struct xsc_adev {
+	struct auxiliary_device	adev;
+	struct xsc_core_device	*xdev;
+};
+
 // hw
 struct xsc_reg_addr {
 	u64	tx_db;
@@ -368,6 +378,8 @@  enum xsc_interface_state {
 struct xsc_core_device {
 	struct pci_dev		*pdev;
 	struct device		*device;
+	int			adev_id;
+	struct xsc_adev		**xsc_adev_list;
 	void			*eth_priv;
 	struct xsc_dev_resource	*dev_res;
 	int			numa_node;
diff --git a/drivers/net/ethernet/yunsilicon/xsc/pci/Makefile b/drivers/net/ethernet/yunsilicon/xsc/pci/Makefile
index 3525d1c74..ad0ecc122 100644
--- a/drivers/net/ethernet/yunsilicon/xsc/pci/Makefile
+++ b/drivers/net/ethernet/yunsilicon/xsc/pci/Makefile
@@ -6,4 +6,5 @@  ccflags-y += -I$(srctree)/drivers/net/ethernet/yunsilicon/xsc
 
 obj-$(CONFIG_YUNSILICON_XSC_PCI) += xsc_pci.o
 
-xsc_pci-y := main.o cmdq.o hw.o qp.o cq.o alloc.o eq.o pci_irq.o
+xsc_pci-y := main.o cmdq.o hw.o qp.o cq.o alloc.o eq.o pci_irq.o adev.o
+
diff --git a/drivers/net/ethernet/yunsilicon/xsc/pci/adev.c b/drivers/net/ethernet/yunsilicon/xsc/pci/adev.c
new file mode 100644
index 000000000..1f8f27d72
--- /dev/null
+++ b/drivers/net/ethernet/yunsilicon/xsc/pci/adev.c
@@ -0,0 +1,110 @@ 
+// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
+/*
+ * Copyright (C) 2021-2025, Shanghai Yunsilicon Technology Co., Ltd.
+ * All rights reserved.
+ */
+
+#include <linux/auxiliary_bus.h>
+#include <linux/idr.h>
+
+#include "adev.h"
+
+static DEFINE_IDA(xsc_adev_ida);
+
+enum xsc_adev_idx {
+	XSC_ADEV_IDX_ETH,
+	XSC_ADEV_IDX_MAX
+};
+
+static const char * const xsc_adev_name[] = {
+	[XSC_ADEV_IDX_ETH] = XSC_ETH_ADEV_NAME,
+};
+
+static void xsc_release_adev(struct device *dev)
+{
+	/* Doing nothing, but auxiliary bus requires a release function */
+}
+
+static int xsc_reg_adev(struct xsc_core_device *xdev, int idx)
+{
+	struct auxiliary_device	*adev;
+	struct xsc_adev *xsc_adev;
+	int ret;
+
+	xsc_adev = kzalloc(sizeof(*xsc_adev), GFP_KERNEL);
+	if (!xsc_adev)
+		return -ENOMEM;
+
+	adev = &xsc_adev->adev;
+	adev->name = xsc_adev_name[idx];
+	adev->id = xdev->adev_id;
+	adev->dev.parent = &xdev->pdev->dev;
+	adev->dev.release = xsc_release_adev;
+	xsc_adev->xdev = xdev;
+
+	ret = auxiliary_device_init(adev);
+	if (ret)
+		goto err_free_adev;
+
+	ret = auxiliary_device_add(adev);
+	if (ret)
+		goto err_uninit_adev;
+
+	xdev->xsc_adev_list[idx] = xsc_adev;
+
+	return 0;
+err_uninit_adev:
+	auxiliary_device_uninit(adev);
+err_free_adev:
+	kfree(xsc_adev);
+
+	return ret;
+}
+
+static void xsc_unreg_adev(struct xsc_core_device *xdev, int idx)
+{
+	struct xsc_adev *xsc_adev = xdev->xsc_adev_list[idx];
+	struct auxiliary_device *adev = &xsc_adev->adev;
+
+	auxiliary_device_delete(adev);
+	auxiliary_device_uninit(adev);
+
+	kfree(xsc_adev);
+	xdev->xsc_adev_list[idx] = NULL;
+}
+
+int xsc_adev_init(struct xsc_core_device *xdev)
+{
+	struct xsc_adev **xsc_adev_list;
+	int adev_id;
+	int ret;
+
+	xsc_adev_list = kzalloc(sizeof(void *) * XSC_ADEV_IDX_MAX, GFP_KERNEL);
+	if (!xsc_adev_list)
+		return -ENOMEM;
+	xdev->xsc_adev_list = xsc_adev_list;
+
+	adev_id = ida_alloc(&xsc_adev_ida, GFP_KERNEL);
+	if (adev_id < 0)
+		goto err_free_adev_list;
+	xdev->adev_id = adev_id;
+
+	ret = xsc_reg_adev(xdev, XSC_ADEV_IDX_ETH);
+	if (ret)
+		goto err_dalloc_adev_id;
+
+	return 0;
+err_dalloc_adev_id:
+	ida_free(&xsc_adev_ida, xdev->adev_id);
+err_free_adev_list:
+	kfree(xsc_adev_list);
+
+	return ret;
+}
+
+void xsc_adev_uninit(struct xsc_core_device *xdev)
+{
+	xsc_unreg_adev(xdev, XSC_ADEV_IDX_ETH);
+	ida_free(&xsc_adev_ida, xdev->adev_id);
+	kfree(xdev->xsc_adev_list);
+}
diff --git a/drivers/net/ethernet/yunsilicon/xsc/pci/adev.h b/drivers/net/ethernet/yunsilicon/xsc/pci/adev.h
new file mode 100644
index 000000000..3de4dd26f
--- /dev/null
+++ b/drivers/net/ethernet/yunsilicon/xsc/pci/adev.h
@@ -0,0 +1,14 @@ 
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright (C) 2021-2025, Shanghai Yunsilicon Technology Co., Ltd.
+ * All rights reserved.
+ */
+
+#ifndef __ADEV_H
+#define __ADEV_H
+
+#include "common/xsc_core.h"
+
+int xsc_adev_init(struct xsc_core_device *xdev);
+void xsc_adev_uninit(struct xsc_core_device *xdev);
+
+#endif
diff --git a/drivers/net/ethernet/yunsilicon/xsc/pci/main.c b/drivers/net/ethernet/yunsilicon/xsc/pci/main.c
index 72eb2a37d..48c4a2a7f 100644
--- a/drivers/net/ethernet/yunsilicon/xsc/pci/main.c
+++ b/drivers/net/ethernet/yunsilicon/xsc/pci/main.c
@@ -10,6 +10,7 @@ 
 #include "cq.h"
 #include "eq.h"
 #include "pci_irq.h"
+#include "adev.h"
 
 static const struct pci_device_id xsc_pci_id_table[] = {
 	{ PCI_DEVICE(XSC_PCI_VENDOR_ID, XSC_MC_PF_DEV_ID) },
@@ -260,10 +261,18 @@  static int xsc_load(struct xsc_core_device *xdev)
 		goto err_hw_cleanup;
 	}
 
+	err = xsc_adev_init(xdev);
+	if (err) {
+		pci_err(xdev->pdev, "xsc_adev_init failed %d\n", err);
+		goto err_irq_eq_destroy;
+	}
+
 	set_bit(XSC_INTERFACE_STATE_UP, &xdev->intf_state);
 	mutex_unlock(&xdev->intf_state_mutex);
 
 	return 0;
+err_irq_eq_destroy:
+	xsc_irq_eq_destroy(xdev);
 err_hw_cleanup:
 	xsc_hw_cleanup(xdev);
 out:
@@ -273,6 +282,7 @@  static int xsc_load(struct xsc_core_device *xdev)
 
 static int xsc_unload(struct xsc_core_device *xdev)
 {
+	xsc_adev_uninit(xdev);
 	mutex_lock(&xdev->intf_state_mutex);
 	if (!test_bit(XSC_INTERFACE_STATE_UP, &xdev->intf_state)) {
 		xsc_hw_cleanup(xdev);