[RFC,v3,2/2] fpga: set owner of fpga_manager_ops for existing low-level modules

Message ID 20231218202809.84253-3-marpagan@redhat.com
State New
Headers
Series fpga: improve protection against low-level control module unloading |

Commit Message

Marco Pagani Dec. 18, 2023, 8:28 p.m. UTC
  This patch tentatively set the owner field of fpga_manager_ops to
THIS_MODULE for existing fpga manager low-level control modules.

Signed-off-by: Marco Pagani <marpagan@redhat.com>
---
 drivers/fpga/altera-cvp.c             | 1 +
 drivers/fpga/altera-pr-ip-core.c      | 1 +
 drivers/fpga/altera-ps-spi.c          | 1 +
 drivers/fpga/dfl-fme-mgr.c            | 1 +
 drivers/fpga/ice40-spi.c              | 1 +
 drivers/fpga/lattice-sysconfig.c      | 1 +
 drivers/fpga/machxo2-spi.c            | 1 +
 drivers/fpga/microchip-spi.c          | 1 +
 drivers/fpga/socfpga-a10.c            | 1 +
 drivers/fpga/socfpga.c                | 1 +
 drivers/fpga/stratix10-soc.c          | 1 +
 drivers/fpga/tests/fpga-mgr-test.c    | 1 +
 drivers/fpga/tests/fpga-region-test.c | 1 +
 drivers/fpga/ts73xx-fpga.c            | 1 +
 drivers/fpga/versal-fpga.c            | 1 +
 drivers/fpga/xilinx-spi.c             | 1 +
 drivers/fpga/zynq-fpga.c              | 1 +
 drivers/fpga/zynqmp-fpga.c            | 1 +
 18 files changed, 18 insertions(+)
  

Comments

Greg KH Dec. 18, 2023, 8:33 p.m. UTC | #1
On Mon, Dec 18, 2023 at 09:28:09PM +0100, Marco Pagani wrote:
> This patch tentatively set the owner field of fpga_manager_ops to
> THIS_MODULE for existing fpga manager low-level control modules.
> 
> Signed-off-by: Marco Pagani <marpagan@redhat.com>
> ---
>  drivers/fpga/altera-cvp.c             | 1 +
>  drivers/fpga/altera-pr-ip-core.c      | 1 +
>  drivers/fpga/altera-ps-spi.c          | 1 +
>  drivers/fpga/dfl-fme-mgr.c            | 1 +
>  drivers/fpga/ice40-spi.c              | 1 +
>  drivers/fpga/lattice-sysconfig.c      | 1 +
>  drivers/fpga/machxo2-spi.c            | 1 +
>  drivers/fpga/microchip-spi.c          | 1 +
>  drivers/fpga/socfpga-a10.c            | 1 +
>  drivers/fpga/socfpga.c                | 1 +
>  drivers/fpga/stratix10-soc.c          | 1 +
>  drivers/fpga/tests/fpga-mgr-test.c    | 1 +
>  drivers/fpga/tests/fpga-region-test.c | 1 +
>  drivers/fpga/ts73xx-fpga.c            | 1 +
>  drivers/fpga/versal-fpga.c            | 1 +
>  drivers/fpga/xilinx-spi.c             | 1 +
>  drivers/fpga/zynq-fpga.c              | 1 +
>  drivers/fpga/zynqmp-fpga.c            | 1 +
>  18 files changed, 18 insertions(+)
> 
> diff --git a/drivers/fpga/altera-cvp.c b/drivers/fpga/altera-cvp.c
> index 4ffb9da537d8..aeb913547dd8 100644
> --- a/drivers/fpga/altera-cvp.c
> +++ b/drivers/fpga/altera-cvp.c
> @@ -520,6 +520,7 @@ static const struct fpga_manager_ops altera_cvp_ops = {
>  	.write_init	= altera_cvp_write_init,
>  	.write		= altera_cvp_write,
>  	.write_complete	= altera_cvp_write_complete,
> +	.owner		= THIS_MODULE,

Note, this is not how to do this, force the compiler to set this for you
automatically, otherwise everyone will always forget to do it.  Look at
how functions like usb_register_driver() works.

Also, are you _sure_ that you need a module owner in this structure?  I
still don't know why...

thanks,

greg k-h
  
Marco Pagani Dec. 19, 2023, 2:54 p.m. UTC | #2
On 2023-12-18 21:33, Greg Kroah-Hartman wrote:
> On Mon, Dec 18, 2023 at 09:28:09PM +0100, Marco Pagani wrote:
>> This patch tentatively set the owner field of fpga_manager_ops to
>> THIS_MODULE for existing fpga manager low-level control modules.
>>
>> Signed-off-by: Marco Pagani <marpagan@redhat.com>
>> ---
>>  drivers/fpga/altera-cvp.c             | 1 +
>>  drivers/fpga/altera-pr-ip-core.c      | 1 +
>>  drivers/fpga/altera-ps-spi.c          | 1 +
>>  drivers/fpga/dfl-fme-mgr.c            | 1 +
>>  drivers/fpga/ice40-spi.c              | 1 +
>>  drivers/fpga/lattice-sysconfig.c      | 1 +
>>  drivers/fpga/machxo2-spi.c            | 1 +
>>  drivers/fpga/microchip-spi.c          | 1 +
>>  drivers/fpga/socfpga-a10.c            | 1 +
>>  drivers/fpga/socfpga.c                | 1 +
>>  drivers/fpga/stratix10-soc.c          | 1 +
>>  drivers/fpga/tests/fpga-mgr-test.c    | 1 +
>>  drivers/fpga/tests/fpga-region-test.c | 1 +
>>  drivers/fpga/ts73xx-fpga.c            | 1 +
>>  drivers/fpga/versal-fpga.c            | 1 +
>>  drivers/fpga/xilinx-spi.c             | 1 +
>>  drivers/fpga/zynq-fpga.c              | 1 +
>>  drivers/fpga/zynqmp-fpga.c            | 1 +
>>  18 files changed, 18 insertions(+)
>>
>> diff --git a/drivers/fpga/altera-cvp.c b/drivers/fpga/altera-cvp.c
>> index 4ffb9da537d8..aeb913547dd8 100644
>> --- a/drivers/fpga/altera-cvp.c
>> +++ b/drivers/fpga/altera-cvp.c
>> @@ -520,6 +520,7 @@ static const struct fpga_manager_ops altera_cvp_ops = {
>>  	.write_init	= altera_cvp_write_init,
>>  	.write		= altera_cvp_write,
>>  	.write_complete	= altera_cvp_write_complete,
>> +	.owner		= THIS_MODULE,
> 
> Note, this is not how to do this, force the compiler to set this for you
> automatically, otherwise everyone will always forget to do it.  Look at
> how functions like usb_register_driver() works.
> 
> Also, are you _sure_ that you need a module owner in this structure?  I
> still don't know why...
>

Do you mean moving the module owner field to the manager context and setting
it during registration with a helper macro?

Something like:

struct fpga_manager {
	...
	struct module *owner;
};

#define fpga_mgr_register(parent, ...) \
	__fpga_mgr_register(parent,..., THIS_MODULE)

struct fpga_manager *
__fpga_mgr_register(struct device *parent, ..., struct module *owner)
{
	...
	mgr->owner = owner;
}

Thanks,
Marco
  
Greg KH Dec. 19, 2023, 3:10 p.m. UTC | #3
On Tue, Dec 19, 2023 at 03:54:25PM +0100, Marco Pagani wrote:
> 
> 
> On 2023-12-18 21:33, Greg Kroah-Hartman wrote:
> > On Mon, Dec 18, 2023 at 09:28:09PM +0100, Marco Pagani wrote:
> >> This patch tentatively set the owner field of fpga_manager_ops to
> >> THIS_MODULE for existing fpga manager low-level control modules.
> >>
> >> Signed-off-by: Marco Pagani <marpagan@redhat.com>
> >> ---
> >>  drivers/fpga/altera-cvp.c             | 1 +
> >>  drivers/fpga/altera-pr-ip-core.c      | 1 +
> >>  drivers/fpga/altera-ps-spi.c          | 1 +
> >>  drivers/fpga/dfl-fme-mgr.c            | 1 +
> >>  drivers/fpga/ice40-spi.c              | 1 +
> >>  drivers/fpga/lattice-sysconfig.c      | 1 +
> >>  drivers/fpga/machxo2-spi.c            | 1 +
> >>  drivers/fpga/microchip-spi.c          | 1 +
> >>  drivers/fpga/socfpga-a10.c            | 1 +
> >>  drivers/fpga/socfpga.c                | 1 +
> >>  drivers/fpga/stratix10-soc.c          | 1 +
> >>  drivers/fpga/tests/fpga-mgr-test.c    | 1 +
> >>  drivers/fpga/tests/fpga-region-test.c | 1 +
> >>  drivers/fpga/ts73xx-fpga.c            | 1 +
> >>  drivers/fpga/versal-fpga.c            | 1 +
> >>  drivers/fpga/xilinx-spi.c             | 1 +
> >>  drivers/fpga/zynq-fpga.c              | 1 +
> >>  drivers/fpga/zynqmp-fpga.c            | 1 +
> >>  18 files changed, 18 insertions(+)
> >>
> >> diff --git a/drivers/fpga/altera-cvp.c b/drivers/fpga/altera-cvp.c
> >> index 4ffb9da537d8..aeb913547dd8 100644
> >> --- a/drivers/fpga/altera-cvp.c
> >> +++ b/drivers/fpga/altera-cvp.c
> >> @@ -520,6 +520,7 @@ static const struct fpga_manager_ops altera_cvp_ops = {
> >>  	.write_init	= altera_cvp_write_init,
> >>  	.write		= altera_cvp_write,
> >>  	.write_complete	= altera_cvp_write_complete,
> >> +	.owner		= THIS_MODULE,
> > 
> > Note, this is not how to do this, force the compiler to set this for you
> > automatically, otherwise everyone will always forget to do it.  Look at
> > how functions like usb_register_driver() works.
> > 
> > Also, are you _sure_ that you need a module owner in this structure?  I
> > still don't know why...
> >
> 
> Do you mean moving the module owner field to the manager context and setting
> it during registration with a helper macro?

I mean set it during registration with a helper macro.

> Something like:
> 
> struct fpga_manager {
> 	...
> 	struct module *owner;
> };
> 
> #define fpga_mgr_register(parent, ...) \
> 	__fpga_mgr_register(parent,..., THIS_MODULE)
> 
> struct fpga_manager *
> __fpga_mgr_register(struct device *parent, ..., struct module *owner)
> {
> 	...
> 	mgr->owner = owner;
> }

Yes.

But again, is a module owner even needed?  I don't think you all have
proven that yet...

thanks,

greg k-h
  
Marco Pagani Dec. 19, 2023, 5:17 p.m. UTC | #4
On 2023-12-19 16:10, Greg Kroah-Hartman wrote:
> On Tue, Dec 19, 2023 at 03:54:25PM +0100, Marco Pagani wrote:
>>
>>
>> On 2023-12-18 21:33, Greg Kroah-Hartman wrote:
>>> On Mon, Dec 18, 2023 at 09:28:09PM +0100, Marco Pagani wrote:
>>>> This patch tentatively set the owner field of fpga_manager_ops to
>>>> THIS_MODULE for existing fpga manager low-level control modules.
>>>>
>>>> Signed-off-by: Marco Pagani <marpagan@redhat.com>
>>>> ---
>>>>  drivers/fpga/altera-cvp.c             | 1 +
>>>>  drivers/fpga/altera-pr-ip-core.c      | 1 +
>>>>  drivers/fpga/altera-ps-spi.c          | 1 +
>>>>  drivers/fpga/dfl-fme-mgr.c            | 1 +
>>>>  drivers/fpga/ice40-spi.c              | 1 +
>>>>  drivers/fpga/lattice-sysconfig.c      | 1 +
>>>>  drivers/fpga/machxo2-spi.c            | 1 +
>>>>  drivers/fpga/microchip-spi.c          | 1 +
>>>>  drivers/fpga/socfpga-a10.c            | 1 +
>>>>  drivers/fpga/socfpga.c                | 1 +
>>>>  drivers/fpga/stratix10-soc.c          | 1 +
>>>>  drivers/fpga/tests/fpga-mgr-test.c    | 1 +
>>>>  drivers/fpga/tests/fpga-region-test.c | 1 +
>>>>  drivers/fpga/ts73xx-fpga.c            | 1 +
>>>>  drivers/fpga/versal-fpga.c            | 1 +
>>>>  drivers/fpga/xilinx-spi.c             | 1 +
>>>>  drivers/fpga/zynq-fpga.c              | 1 +
>>>>  drivers/fpga/zynqmp-fpga.c            | 1 +
>>>>  18 files changed, 18 insertions(+)
>>>>
>>>> diff --git a/drivers/fpga/altera-cvp.c b/drivers/fpga/altera-cvp.c
>>>> index 4ffb9da537d8..aeb913547dd8 100644
>>>> --- a/drivers/fpga/altera-cvp.c
>>>> +++ b/drivers/fpga/altera-cvp.c
>>>> @@ -520,6 +520,7 @@ static const struct fpga_manager_ops altera_cvp_ops = {
>>>>  	.write_init	= altera_cvp_write_init,
>>>>  	.write		= altera_cvp_write,
>>>>  	.write_complete	= altera_cvp_write_complete,
>>>> +	.owner		= THIS_MODULE,
>>>
>>> Note, this is not how to do this, force the compiler to set this for you
>>> automatically, otherwise everyone will always forget to do it.  Look at
>>> how functions like usb_register_driver() works.
>>>
>>> Also, are you _sure_ that you need a module owner in this structure?  I
>>> still don't know why...
>>>
>>
>> Do you mean moving the module owner field to the manager context and setting
>> it during registration with a helper macro?
> 
> I mean set it during registration with a helper macro.
> 
>> Something like:
>>
>> struct fpga_manager {
>> 	...
>> 	struct module *owner;
>> };
>>
>> #define fpga_mgr_register(parent, ...) \
>> 	__fpga_mgr_register(parent,..., THIS_MODULE)
>>
>> struct fpga_manager *
>> __fpga_mgr_register(struct device *parent, ..., struct module *owner)
>> {
>> 	...
>> 	mgr->owner = owner;
>> }
> 
> Yes.
> 
> But again, is a module owner even needed?  I don't think you all have
> proven that yet...

Programming an FPGA involves a potentially lengthy sequence of interactions
with the reconfiguration engine. The manager conceptually organizes these
interactions as a sequence of ops. Low-level modules implement these ops/steps
for a specific device. If we don't protect the low-level module, someone might
unload it right when we are in the middle of a low-level op programming the
FPGA. As far as I know, the kernel would crash in that case.

Thanks,
Marco
  
Greg KH Dec. 19, 2023, 6:11 p.m. UTC | #5
On Tue, Dec 19, 2023 at 06:17:20PM +0100, Marco Pagani wrote:
> 
> On 2023-12-19 16:10, Greg Kroah-Hartman wrote:
> > On Tue, Dec 19, 2023 at 03:54:25PM +0100, Marco Pagani wrote:
> >>
> >>
> >> On 2023-12-18 21:33, Greg Kroah-Hartman wrote:
> >>> On Mon, Dec 18, 2023 at 09:28:09PM +0100, Marco Pagani wrote:
> >>>> This patch tentatively set the owner field of fpga_manager_ops to
> >>>> THIS_MODULE for existing fpga manager low-level control modules.
> >>>>
> >>>> Signed-off-by: Marco Pagani <marpagan@redhat.com>
> >>>> ---
> >>>>  drivers/fpga/altera-cvp.c             | 1 +
> >>>>  drivers/fpga/altera-pr-ip-core.c      | 1 +
> >>>>  drivers/fpga/altera-ps-spi.c          | 1 +
> >>>>  drivers/fpga/dfl-fme-mgr.c            | 1 +
> >>>>  drivers/fpga/ice40-spi.c              | 1 +
> >>>>  drivers/fpga/lattice-sysconfig.c      | 1 +
> >>>>  drivers/fpga/machxo2-spi.c            | 1 +
> >>>>  drivers/fpga/microchip-spi.c          | 1 +
> >>>>  drivers/fpga/socfpga-a10.c            | 1 +
> >>>>  drivers/fpga/socfpga.c                | 1 +
> >>>>  drivers/fpga/stratix10-soc.c          | 1 +
> >>>>  drivers/fpga/tests/fpga-mgr-test.c    | 1 +
> >>>>  drivers/fpga/tests/fpga-region-test.c | 1 +
> >>>>  drivers/fpga/ts73xx-fpga.c            | 1 +
> >>>>  drivers/fpga/versal-fpga.c            | 1 +
> >>>>  drivers/fpga/xilinx-spi.c             | 1 +
> >>>>  drivers/fpga/zynq-fpga.c              | 1 +
> >>>>  drivers/fpga/zynqmp-fpga.c            | 1 +
> >>>>  18 files changed, 18 insertions(+)
> >>>>
> >>>> diff --git a/drivers/fpga/altera-cvp.c b/drivers/fpga/altera-cvp.c
> >>>> index 4ffb9da537d8..aeb913547dd8 100644
> >>>> --- a/drivers/fpga/altera-cvp.c
> >>>> +++ b/drivers/fpga/altera-cvp.c
> >>>> @@ -520,6 +520,7 @@ static const struct fpga_manager_ops altera_cvp_ops = {
> >>>>  	.write_init	= altera_cvp_write_init,
> >>>>  	.write		= altera_cvp_write,
> >>>>  	.write_complete	= altera_cvp_write_complete,
> >>>> +	.owner		= THIS_MODULE,
> >>>
> >>> Note, this is not how to do this, force the compiler to set this for you
> >>> automatically, otherwise everyone will always forget to do it.  Look at
> >>> how functions like usb_register_driver() works.
> >>>
> >>> Also, are you _sure_ that you need a module owner in this structure?  I
> >>> still don't know why...
> >>>
> >>
> >> Do you mean moving the module owner field to the manager context and setting
> >> it during registration with a helper macro?
> > 
> > I mean set it during registration with a helper macro.
> > 
> >> Something like:
> >>
> >> struct fpga_manager {
> >> 	...
> >> 	struct module *owner;
> >> };
> >>
> >> #define fpga_mgr_register(parent, ...) \
> >> 	__fpga_mgr_register(parent,..., THIS_MODULE)
> >>
> >> struct fpga_manager *
> >> __fpga_mgr_register(struct device *parent, ..., struct module *owner)
> >> {
> >> 	...
> >> 	mgr->owner = owner;
> >> }
> > 
> > Yes.
> > 
> > But again, is a module owner even needed?  I don't think you all have
> > proven that yet...
> 
> Programming an FPGA involves a potentially lengthy sequence of interactions
> with the reconfiguration engine. The manager conceptually organizes these
> interactions as a sequence of ops. Low-level modules implement these ops/steps
> for a specific device. If we don't protect the low-level module, someone might
> unload it right when we are in the middle of a low-level op programming the
> FPGA. As far as I know, the kernel would crash in that case.

The only way an unload of a module can happen is if a user explicitly
asks for it to be unloaded.  So they get what they ask for, right?

How do you "know" it is active?  And why doesn't the normal
"driver/device" bindings prevent unloading from being a problem?  When
you unload a module, you stop all ops on the driver, and then unregister
it, which causes any future ones to fail.

Or am I missing something here?

thanks,

greg k-h
  
Marco Pagani Dec. 20, 2023, 10:24 p.m. UTC | #6
On 19/12/23 19:11, Greg Kroah-Hartman wrote:
> On Tue, Dec 19, 2023 at 06:17:20PM +0100, Marco Pagani wrote:
>>
>> On 2023-12-19 16:10, Greg Kroah-Hartman wrote:
>>> On Tue, Dec 19, 2023 at 03:54:25PM +0100, Marco Pagani wrote:
>>>>
>>>>
>>>> On 2023-12-18 21:33, Greg Kroah-Hartman wrote:
>>>>> On Mon, Dec 18, 2023 at 09:28:09PM +0100, Marco Pagani wrote:
>>>>>> This patch tentatively set the owner field of fpga_manager_ops to
>>>>>> THIS_MODULE for existing fpga manager low-level control modules.
>>>>>>
>>>>>> Signed-off-by: Marco Pagani <marpagan@redhat.com>
>>>>>> ---
>>>>>>  drivers/fpga/altera-cvp.c             | 1 +
>>>>>>  drivers/fpga/altera-pr-ip-core.c      | 1 +
>>>>>>  drivers/fpga/altera-ps-spi.c          | 1 +
>>>>>>  drivers/fpga/dfl-fme-mgr.c            | 1 +
>>>>>>  drivers/fpga/ice40-spi.c              | 1 +
>>>>>>  drivers/fpga/lattice-sysconfig.c      | 1 +
>>>>>>  drivers/fpga/machxo2-spi.c            | 1 +
>>>>>>  drivers/fpga/microchip-spi.c          | 1 +
>>>>>>  drivers/fpga/socfpga-a10.c            | 1 +
>>>>>>  drivers/fpga/socfpga.c                | 1 +
>>>>>>  drivers/fpga/stratix10-soc.c          | 1 +
>>>>>>  drivers/fpga/tests/fpga-mgr-test.c    | 1 +
>>>>>>  drivers/fpga/tests/fpga-region-test.c | 1 +
>>>>>>  drivers/fpga/ts73xx-fpga.c            | 1 +
>>>>>>  drivers/fpga/versal-fpga.c            | 1 +
>>>>>>  drivers/fpga/xilinx-spi.c             | 1 +
>>>>>>  drivers/fpga/zynq-fpga.c              | 1 +
>>>>>>  drivers/fpga/zynqmp-fpga.c            | 1 +
>>>>>>  18 files changed, 18 insertions(+)
>>>>>>
>>>>>> diff --git a/drivers/fpga/altera-cvp.c b/drivers/fpga/altera-cvp.c
>>>>>> index 4ffb9da537d8..aeb913547dd8 100644
>>>>>> --- a/drivers/fpga/altera-cvp.c
>>>>>> +++ b/drivers/fpga/altera-cvp.c
>>>>>> @@ -520,6 +520,7 @@ static const struct fpga_manager_ops altera_cvp_ops = {
>>>>>>  	.write_init	= altera_cvp_write_init,
>>>>>>  	.write		= altera_cvp_write,
>>>>>>  	.write_complete	= altera_cvp_write_complete,
>>>>>> +	.owner		= THIS_MODULE,
>>>>>
>>>>> Note, this is not how to do this, force the compiler to set this for you
>>>>> automatically, otherwise everyone will always forget to do it.  Look at
>>>>> how functions like usb_register_driver() works.
>>>>>
>>>>> Also, are you _sure_ that you need a module owner in this structure?  I
>>>>> still don't know why...
>>>>>
>>>>
>>>> Do you mean moving the module owner field to the manager context and setting
>>>> it during registration with a helper macro?
>>>
>>> I mean set it during registration with a helper macro.
>>>
>>>> Something like:
>>>>
>>>> struct fpga_manager {
>>>> 	...
>>>> 	struct module *owner;
>>>> };
>>>>
>>>> #define fpga_mgr_register(parent, ...) \
>>>> 	__fpga_mgr_register(parent,..., THIS_MODULE)
>>>>
>>>> struct fpga_manager *
>>>> __fpga_mgr_register(struct device *parent, ..., struct module *owner)
>>>> {
>>>> 	...
>>>> 	mgr->owner = owner;
>>>> }
>>>
>>> Yes.
>>>
>>> But again, is a module owner even needed?  I don't think you all have
>>> proven that yet...
>>
>> Programming an FPGA involves a potentially lengthy sequence of interactions
>> with the reconfiguration engine. The manager conceptually organizes these
>> interactions as a sequence of ops. Low-level modules implement these ops/steps
>> for a specific device. If we don't protect the low-level module, someone might
>> unload it right when we are in the middle of a low-level op programming the
>> FPGA. As far as I know, the kernel would crash in that case.
> 
> The only way an unload of a module can happen is if a user explicitly
> asks for it to be unloaded.  So they get what they ask for, right?
>

Right, the user should get what he asked for, including hanging the
hardware. My only concern is that the kernel should not crash.

> How do you "know" it is active?  And why doesn't the normal
> "driver/device" bindings prevent unloading from being a problem?  When
> you unload a module, you stop all ops on the driver, and then unregister
> it, which causes any future ones to fail.
> 
> Or am I missing something here?
>
 
I think the problem is that the ops are not directly tied to the driver
of the manager's parent device. It is not even required to have a driver
to register a manager. The only way to know if the fpga manager is
active (i.e., someone is running one op) is by poking manager->state.

One possibility that comes into my mind, excluding a major reworking,
is waiting in fpga_mgr_unregister() until the manager reaches a steady
state (no ops are running) before unregistering the device. However, it
feels questionable because if one of the ops hangs, the module removal
will also hang.

Thanks,
Marco
  
Greg KH Dec. 21, 2023, 8:22 a.m. UTC | #7
On Wed, Dec 20, 2023 at 11:24:20PM +0100, Marco Pagani wrote:
> 
> 
> On 19/12/23 19:11, Greg Kroah-Hartman wrote:
> > On Tue, Dec 19, 2023 at 06:17:20PM +0100, Marco Pagani wrote:
> >>
> >> On 2023-12-19 16:10, Greg Kroah-Hartman wrote:
> >>> On Tue, Dec 19, 2023 at 03:54:25PM +0100, Marco Pagani wrote:
> >>>>
> >>>>
> >>>> On 2023-12-18 21:33, Greg Kroah-Hartman wrote:
> >>>>> On Mon, Dec 18, 2023 at 09:28:09PM +0100, Marco Pagani wrote:
> >>>>>> This patch tentatively set the owner field of fpga_manager_ops to
> >>>>>> THIS_MODULE for existing fpga manager low-level control modules.
> >>>>>>
> >>>>>> Signed-off-by: Marco Pagani <marpagan@redhat.com>
> >>>>>> ---
> >>>>>>  drivers/fpga/altera-cvp.c             | 1 +
> >>>>>>  drivers/fpga/altera-pr-ip-core.c      | 1 +
> >>>>>>  drivers/fpga/altera-ps-spi.c          | 1 +
> >>>>>>  drivers/fpga/dfl-fme-mgr.c            | 1 +
> >>>>>>  drivers/fpga/ice40-spi.c              | 1 +
> >>>>>>  drivers/fpga/lattice-sysconfig.c      | 1 +
> >>>>>>  drivers/fpga/machxo2-spi.c            | 1 +
> >>>>>>  drivers/fpga/microchip-spi.c          | 1 +
> >>>>>>  drivers/fpga/socfpga-a10.c            | 1 +
> >>>>>>  drivers/fpga/socfpga.c                | 1 +
> >>>>>>  drivers/fpga/stratix10-soc.c          | 1 +
> >>>>>>  drivers/fpga/tests/fpga-mgr-test.c    | 1 +
> >>>>>>  drivers/fpga/tests/fpga-region-test.c | 1 +
> >>>>>>  drivers/fpga/ts73xx-fpga.c            | 1 +
> >>>>>>  drivers/fpga/versal-fpga.c            | 1 +
> >>>>>>  drivers/fpga/xilinx-spi.c             | 1 +
> >>>>>>  drivers/fpga/zynq-fpga.c              | 1 +
> >>>>>>  drivers/fpga/zynqmp-fpga.c            | 1 +
> >>>>>>  18 files changed, 18 insertions(+)
> >>>>>>
> >>>>>> diff --git a/drivers/fpga/altera-cvp.c b/drivers/fpga/altera-cvp.c
> >>>>>> index 4ffb9da537d8..aeb913547dd8 100644
> >>>>>> --- a/drivers/fpga/altera-cvp.c
> >>>>>> +++ b/drivers/fpga/altera-cvp.c
> >>>>>> @@ -520,6 +520,7 @@ static const struct fpga_manager_ops altera_cvp_ops = {
> >>>>>>  	.write_init	= altera_cvp_write_init,
> >>>>>>  	.write		= altera_cvp_write,
> >>>>>>  	.write_complete	= altera_cvp_write_complete,
> >>>>>> +	.owner		= THIS_MODULE,
> >>>>>
> >>>>> Note, this is not how to do this, force the compiler to set this for you
> >>>>> automatically, otherwise everyone will always forget to do it.  Look at
> >>>>> how functions like usb_register_driver() works.
> >>>>>
> >>>>> Also, are you _sure_ that you need a module owner in this structure?  I
> >>>>> still don't know why...
> >>>>>
> >>>>
> >>>> Do you mean moving the module owner field to the manager context and setting
> >>>> it during registration with a helper macro?
> >>>
> >>> I mean set it during registration with a helper macro.
> >>>
> >>>> Something like:
> >>>>
> >>>> struct fpga_manager {
> >>>> 	...
> >>>> 	struct module *owner;
> >>>> };
> >>>>
> >>>> #define fpga_mgr_register(parent, ...) \
> >>>> 	__fpga_mgr_register(parent,..., THIS_MODULE)
> >>>>
> >>>> struct fpga_manager *
> >>>> __fpga_mgr_register(struct device *parent, ..., struct module *owner)
> >>>> {
> >>>> 	...
> >>>> 	mgr->owner = owner;
> >>>> }
> >>>
> >>> Yes.
> >>>
> >>> But again, is a module owner even needed?  I don't think you all have
> >>> proven that yet...
> >>
> >> Programming an FPGA involves a potentially lengthy sequence of interactions
> >> with the reconfiguration engine. The manager conceptually organizes these
> >> interactions as a sequence of ops. Low-level modules implement these ops/steps
> >> for a specific device. If we don't protect the low-level module, someone might
> >> unload it right when we are in the middle of a low-level op programming the
> >> FPGA. As far as I know, the kernel would crash in that case.
> > 
> > The only way an unload of a module can happen is if a user explicitly
> > asks for it to be unloaded.  So they get what they ask for, right?
> >
> 
> Right, the user should get what he asked for, including hanging the
> hardware. My only concern is that the kernel should not crash.
> 
> > How do you "know" it is active?  And why doesn't the normal
> > "driver/device" bindings prevent unloading from being a problem?  When
> > you unload a module, you stop all ops on the driver, and then unregister
> > it, which causes any future ones to fail.
> > 
> > Or am I missing something here?
> >
>  
> I think the problem is that the ops are not directly tied to the driver
> of the manager's parent device.

Then that needs to be fixed right there, as that is obviously not using
the driver model properly.

Why aren't the "ops" a driver that is bound to this device?  If it is
the one responsible for controlling it, then it should be a driver and
as such, the driver model logic will handle things if/when a module is
unloaded to tear things down better.

> It is not even required to have a driver
> to register a manager. The only way to know if the fpga manager is
> active (i.e., someone is running one op) is by poking manager->state.

That too seems wrong, why is this?

> One possibility that comes into my mind, excluding a major reworking,
> is waiting in fpga_mgr_unregister() until the manager reaches a steady
> state (no ops are running) before unregistering the device. However, it
> feels questionable because if one of the ops hangs, the module removal
> will also hang.

You never know when a new operand will come in, so there's no way to
know "all is quiet", sorry.

Try fixing this properly, buy using the driver model correctly, that
should help resolve these issues automatically instead of hacked up
module reference count attempts.

Remember, this is the whole reason why the driver model was created all
those 20+ years ago, to move away from these module reference count
issues, let's not forget history please.

thanks,

greg k-h
  
Xu Yilun Dec. 21, 2023, 9:26 a.m. UTC | #8
On Tue, Dec 19, 2023 at 07:11:09PM +0100, Greg Kroah-Hartman wrote:
> On Tue, Dec 19, 2023 at 06:17:20PM +0100, Marco Pagani wrote:
> > 
> > On 2023-12-19 16:10, Greg Kroah-Hartman wrote:
> > > On Tue, Dec 19, 2023 at 03:54:25PM +0100, Marco Pagani wrote:
> > >>
> > >>
> > >> On 2023-12-18 21:33, Greg Kroah-Hartman wrote:
> > >>> On Mon, Dec 18, 2023 at 09:28:09PM +0100, Marco Pagani wrote:
> > >>>> This patch tentatively set the owner field of fpga_manager_ops to
> > >>>> THIS_MODULE for existing fpga manager low-level control modules.
> > >>>>
> > >>>> Signed-off-by: Marco Pagani <marpagan@redhat.com>
> > >>>> ---
> > >>>>  drivers/fpga/altera-cvp.c             | 1 +
> > >>>>  drivers/fpga/altera-pr-ip-core.c      | 1 +
> > >>>>  drivers/fpga/altera-ps-spi.c          | 1 +
> > >>>>  drivers/fpga/dfl-fme-mgr.c            | 1 +
> > >>>>  drivers/fpga/ice40-spi.c              | 1 +
> > >>>>  drivers/fpga/lattice-sysconfig.c      | 1 +
> > >>>>  drivers/fpga/machxo2-spi.c            | 1 +
> > >>>>  drivers/fpga/microchip-spi.c          | 1 +
> > >>>>  drivers/fpga/socfpga-a10.c            | 1 +
> > >>>>  drivers/fpga/socfpga.c                | 1 +
> > >>>>  drivers/fpga/stratix10-soc.c          | 1 +
> > >>>>  drivers/fpga/tests/fpga-mgr-test.c    | 1 +
> > >>>>  drivers/fpga/tests/fpga-region-test.c | 1 +
> > >>>>  drivers/fpga/ts73xx-fpga.c            | 1 +
> > >>>>  drivers/fpga/versal-fpga.c            | 1 +
> > >>>>  drivers/fpga/xilinx-spi.c             | 1 +
> > >>>>  drivers/fpga/zynq-fpga.c              | 1 +
> > >>>>  drivers/fpga/zynqmp-fpga.c            | 1 +
> > >>>>  18 files changed, 18 insertions(+)
> > >>>>
> > >>>> diff --git a/drivers/fpga/altera-cvp.c b/drivers/fpga/altera-cvp.c
> > >>>> index 4ffb9da537d8..aeb913547dd8 100644
> > >>>> --- a/drivers/fpga/altera-cvp.c
> > >>>> +++ b/drivers/fpga/altera-cvp.c
> > >>>> @@ -520,6 +520,7 @@ static const struct fpga_manager_ops altera_cvp_ops = {
> > >>>>  	.write_init	= altera_cvp_write_init,
> > >>>>  	.write		= altera_cvp_write,
> > >>>>  	.write_complete	= altera_cvp_write_complete,
> > >>>> +	.owner		= THIS_MODULE,
> > >>>
> > >>> Note, this is not how to do this, force the compiler to set this for you
> > >>> automatically, otherwise everyone will always forget to do it.  Look at
> > >>> how functions like usb_register_driver() works.
> > >>>
> > >>> Also, are you _sure_ that you need a module owner in this structure?  I
> > >>> still don't know why...
> > >>>
> > >>
> > >> Do you mean moving the module owner field to the manager context and setting
> > >> it during registration with a helper macro?
> > > 
> > > I mean set it during registration with a helper macro.
> > > 
> > >> Something like:
> > >>
> > >> struct fpga_manager {
> > >> 	...
> > >> 	struct module *owner;
> > >> };
> > >>
> > >> #define fpga_mgr_register(parent, ...) \
> > >> 	__fpga_mgr_register(parent,..., THIS_MODULE)
> > >>
> > >> struct fpga_manager *
> > >> __fpga_mgr_register(struct device *parent, ..., struct module *owner)
> > >> {
> > >> 	...
> > >> 	mgr->owner = owner;
> > >> }
> > > 
> > > Yes.
> > > 
> > > But again, is a module owner even needed?  I don't think you all have
> > > proven that yet...
> > 
> > Programming an FPGA involves a potentially lengthy sequence of interactions
> > with the reconfiguration engine. The manager conceptually organizes these
> > interactions as a sequence of ops. Low-level modules implement these ops/steps
> > for a specific device. If we don't protect the low-level module, someone might
> > unload it right when we are in the middle of a low-level op programming the
> > FPGA. As far as I know, the kernel would crash in that case.
> 
> The only way an unload of a module can happen is if a user explicitly
> asks for it to be unloaded.  So they get what they ask for, right?

We have discussed this before [1]. The conclusion is kernel developers can
prevent user module unloading, as long as it doesn't make things
complex. Actually some fundamental subsystems do care about module
unloading. And I assume this patch doesn't make a complex fix.

[1] https://lore.kernel.org/linux-fpga/2023110922-lurk-subdivide-4962@gregkh/
> 
> How do you "know" it is active?  And why doesn't the normal

The FPGA core manages the reprogramming flow and knows if device is
active. FPGA core will grab the low-level driver module until
reprograming is finished. 

> "driver/device" bindings prevent unloading from being a problem?  When
> you unload a module, you stop all ops on the driver, and then unregister
> it, which causes any future ones to fail.

This is also discussed [2]. It is still about user explicit module
unloading. The low-level driver module on its own has no way to
garantee its own code page of callbacks not accessed. It *is*
accessing its code page when it tries (to release) any protection. [3]

Core code which calls into it must help, and something like
file_operations.owner is an effective way. This is why a struct
module *owner is introduced for core code to provide help.

[2] https://lore.kernel.org/linux-fpga/2023110918-showroom-choosy-ad14@gregkh/
[3] https://lore.kernel.org/all/20231010003746.GN800259@ZenIV/

Thanks,
Yilun

> 
> Or am I missing something here?
> 
> thanks,
> 
> greg k-h
>
  
Marco Pagani Dec. 22, 2023, 8:52 p.m. UTC | #9
On 2023-12-21 09:22, Greg Kroah-Hartman wrote:
> On Wed, Dec 20, 2023 at 11:24:20PM +0100, Marco Pagani wrote:
>>
>>
>> On 19/12/23 19:11, Greg Kroah-Hartman wrote:
>>> On Tue, Dec 19, 2023 at 06:17:20PM +0100, Marco Pagani wrote:
>>>>
>>>> On 2023-12-19 16:10, Greg Kroah-Hartman wrote:
>>>>> On Tue, Dec 19, 2023 at 03:54:25PM +0100, Marco Pagani wrote:
>>>>>>
>>>>>>
>>>>>> On 2023-12-18 21:33, Greg Kroah-Hartman wrote:
>>>>>>> On Mon, Dec 18, 2023 at 09:28:09PM +0100, Marco Pagani wrote:
>>>>>>>> This patch tentatively set the owner field of fpga_manager_ops to
>>>>>>>> THIS_MODULE for existing fpga manager low-level control modules.
>>>>>>>>
>>>>>>>> Signed-off-by: Marco Pagani <marpagan@redhat.com>
>>>>>>>> ---
>>>>>>>>  drivers/fpga/altera-cvp.c             | 1 +
>>>>>>>>  drivers/fpga/altera-pr-ip-core.c      | 1 +
>>>>>>>>  drivers/fpga/altera-ps-spi.c          | 1 +
>>>>>>>>  drivers/fpga/dfl-fme-mgr.c            | 1 +
>>>>>>>>  drivers/fpga/ice40-spi.c              | 1 +
>>>>>>>>  drivers/fpga/lattice-sysconfig.c      | 1 +
>>>>>>>>  drivers/fpga/machxo2-spi.c            | 1 +
>>>>>>>>  drivers/fpga/microchip-spi.c          | 1 +
>>>>>>>>  drivers/fpga/socfpga-a10.c            | 1 +
>>>>>>>>  drivers/fpga/socfpga.c                | 1 +
>>>>>>>>  drivers/fpga/stratix10-soc.c          | 1 +
>>>>>>>>  drivers/fpga/tests/fpga-mgr-test.c    | 1 +
>>>>>>>>  drivers/fpga/tests/fpga-region-test.c | 1 +
>>>>>>>>  drivers/fpga/ts73xx-fpga.c            | 1 +
>>>>>>>>  drivers/fpga/versal-fpga.c            | 1 +
>>>>>>>>  drivers/fpga/xilinx-spi.c             | 1 +
>>>>>>>>  drivers/fpga/zynq-fpga.c              | 1 +
>>>>>>>>  drivers/fpga/zynqmp-fpga.c            | 1 +
>>>>>>>>  18 files changed, 18 insertions(+)
>>>>>>>>
>>>>>>>> diff --git a/drivers/fpga/altera-cvp.c b/drivers/fpga/altera-cvp.c
>>>>>>>> index 4ffb9da537d8..aeb913547dd8 100644
>>>>>>>> --- a/drivers/fpga/altera-cvp.c
>>>>>>>> +++ b/drivers/fpga/altera-cvp.c
>>>>>>>> @@ -520,6 +520,7 @@ static const struct fpga_manager_ops altera_cvp_ops = {
>>>>>>>>  	.write_init	= altera_cvp_write_init,
>>>>>>>>  	.write		= altera_cvp_write,
>>>>>>>>  	.write_complete	= altera_cvp_write_complete,
>>>>>>>> +	.owner		= THIS_MODULE,
>>>>>>>
>>>>>>> Note, this is not how to do this, force the compiler to set this for you
>>>>>>> automatically, otherwise everyone will always forget to do it.  Look at
>>>>>>> how functions like usb_register_driver() works.
>>>>>>>
>>>>>>> Also, are you _sure_ that you need a module owner in this structure?  I
>>>>>>> still don't know why...
>>>>>>>
>>>>>>
>>>>>> Do you mean moving the module owner field to the manager context and setting
>>>>>> it during registration with a helper macro?
>>>>>
>>>>> I mean set it during registration with a helper macro.
>>>>>
>>>>>> Something like:
>>>>>>
>>>>>> struct fpga_manager {
>>>>>> 	...
>>>>>> 	struct module *owner;
>>>>>> };
>>>>>>
>>>>>> #define fpga_mgr_register(parent, ...) \
>>>>>> 	__fpga_mgr_register(parent,..., THIS_MODULE)
>>>>>>
>>>>>> struct fpga_manager *
>>>>>> __fpga_mgr_register(struct device *parent, ..., struct module *owner)
>>>>>> {
>>>>>> 	...
>>>>>> 	mgr->owner = owner;
>>>>>> }
>>>>>
>>>>> Yes.
>>>>>
>>>>> But again, is a module owner even needed?  I don't think you all have
>>>>> proven that yet...
>>>>
>>>> Programming an FPGA involves a potentially lengthy sequence of interactions
>>>> with the reconfiguration engine. The manager conceptually organizes these
>>>> interactions as a sequence of ops. Low-level modules implement these ops/steps
>>>> for a specific device. If we don't protect the low-level module, someone might
>>>> unload it right when we are in the middle of a low-level op programming the
>>>> FPGA. As far as I know, the kernel would crash in that case.
>>>
>>> The only way an unload of a module can happen is if a user explicitly
>>> asks for it to be unloaded.  So they get what they ask for, right?
>>>
>>
>> Right, the user should get what he asked for, including hanging the
>> hardware. My only concern is that the kernel should not crash.
>>
>>> How do you "know" it is active?  And why doesn't the normal
>>> "driver/device" bindings prevent unloading from being a problem?  When
>>> you unload a module, you stop all ops on the driver, and then unregister
>>> it, which causes any future ones to fail.
>>>
>>> Or am I missing something here?
>>>
>>  
>> I think the problem is that the ops are not directly tied to the driver
>> of the manager's parent device.
> 
> Then that needs to be fixed right there, as that is obviously not using
> the driver model properly.
> 
> Why aren't the "ops" a driver that is bound to this device?  If it is
> the one responsible for controlling it, then it should be a driver and
> as such, the driver model logic will handle things if/when a module is
> unloaded to tear things down better.
> 
>> It is not even required to have a driver
>> to register a manager. The only way to know if the fpga manager is
>> active (i.e., someone is running one op) is by poking manager->state.
> 
> That too seems wrong, why is this?

I don't know. I was not around when the fpga subsystem was laid down.

> 
>> One possibility that comes into my mind, excluding a major reworking,
>> is waiting in fpga_mgr_unregister() until the manager reaches a steady
>> state (no ops are running) before unregistering the device. However, it
>> feels questionable because if one of the ops hangs, the module removal
>> will also hang.
> 
> You never know when a new operand will come in, so there's no way to
> know "all is quiet", sorry.
> 
> Try fixing this properly, buy using the driver model correctly, that
> should help resolve these issues automatically instead of hacked up
> module reference count attempts.
> 
> Remember, this is the whole reason why the driver model was created all
> those 20+ years ago, to move away from these module reference count
> issues, let's not forget history please.
> 

I do not entirely understand this part. The subsystem only provides an
in-kernel API for programming the fpga that in-kernel consumers can use.
The ops that the low-level module implements are used only internally by
the manager in a predefined order.

There is no standard interface for programming the fpga exposed to
userspace using file_operations or attributes exported via sysfs.
The manager only exports read-only attributes for status. On top
of that, there is only the support for device tree overlays.

Would it be correct to assume that the responsibility of keeping
the low-level module in while programming the fpga is on the kernel
component that consumes the subsystem's in-kernel API and (eventually)
exports a programming interface to userspace?

If we consider the case where the programming is done through a
userspace interface exported by the same module that implements the ops,
then we should be good even without taking the low-level module in the
manager.

However, I guess the decision to take the low-level module in the
manager was meant to address the case where the module implementing the
ops and the consumer of the in-kernel API (that may optionally export a
userspace interface for programming) are two separate entities.

Thanks,
Marco
  

Patch

diff --git a/drivers/fpga/altera-cvp.c b/drivers/fpga/altera-cvp.c
index 4ffb9da537d8..aeb913547dd8 100644
--- a/drivers/fpga/altera-cvp.c
+++ b/drivers/fpga/altera-cvp.c
@@ -520,6 +520,7 @@  static const struct fpga_manager_ops altera_cvp_ops = {
 	.write_init	= altera_cvp_write_init,
 	.write		= altera_cvp_write,
 	.write_complete	= altera_cvp_write_complete,
+	.owner		= THIS_MODULE,
 };
 
 static const struct cvp_priv cvp_priv_v1 = {
diff --git a/drivers/fpga/altera-pr-ip-core.c b/drivers/fpga/altera-pr-ip-core.c
index df8671af4a92..354221c609e6 100644
--- a/drivers/fpga/altera-pr-ip-core.c
+++ b/drivers/fpga/altera-pr-ip-core.c
@@ -171,6 +171,7 @@  static const struct fpga_manager_ops alt_pr_ops = {
 	.write_init = alt_pr_fpga_write_init,
 	.write = alt_pr_fpga_write,
 	.write_complete = alt_pr_fpga_write_complete,
+	.owner = THIS_MODULE,
 };
 
 int alt_pr_register(struct device *dev, void __iomem *reg_base)
diff --git a/drivers/fpga/altera-ps-spi.c b/drivers/fpga/altera-ps-spi.c
index 740980e7cef8..3be05796a6fc 100644
--- a/drivers/fpga/altera-ps-spi.c
+++ b/drivers/fpga/altera-ps-spi.c
@@ -228,6 +228,7 @@  static const struct fpga_manager_ops altera_ps_ops = {
 	.write_init = altera_ps_write_init,
 	.write = altera_ps_write,
 	.write_complete = altera_ps_write_complete,
+	.owner = THIS_MODULE,
 };
 
 static int altera_ps_probe(struct spi_device *spi)
diff --git a/drivers/fpga/dfl-fme-mgr.c b/drivers/fpga/dfl-fme-mgr.c
index ab228d8837a0..740ce82e3ac9 100644
--- a/drivers/fpga/dfl-fme-mgr.c
+++ b/drivers/fpga/dfl-fme-mgr.c
@@ -264,6 +264,7 @@  static const struct fpga_manager_ops fme_mgr_ops = {
 	.write = fme_mgr_write,
 	.write_complete = fme_mgr_write_complete,
 	.status = fme_mgr_status,
+	.owner = THIS_MODULE,
 };
 
 static void fme_mgr_get_compat_id(void __iomem *fme_pr,
diff --git a/drivers/fpga/ice40-spi.c b/drivers/fpga/ice40-spi.c
index 7cbb3558b844..97afa6dc5d76 100644
--- a/drivers/fpga/ice40-spi.c
+++ b/drivers/fpga/ice40-spi.c
@@ -130,6 +130,7 @@  static const struct fpga_manager_ops ice40_fpga_ops = {
 	.write_init = ice40_fpga_ops_write_init,
 	.write = ice40_fpga_ops_write,
 	.write_complete = ice40_fpga_ops_write_complete,
+	.owner = THIS_MODULE,
 };
 
 static int ice40_fpga_probe(struct spi_device *spi)
diff --git a/drivers/fpga/lattice-sysconfig.c b/drivers/fpga/lattice-sysconfig.c
index ba51a60f672f..1393cdd11e49 100644
--- a/drivers/fpga/lattice-sysconfig.c
+++ b/drivers/fpga/lattice-sysconfig.c
@@ -348,6 +348,7 @@  static const struct fpga_manager_ops sysconfig_fpga_mgr_ops = {
 	.write_init = sysconfig_ops_write_init,
 	.write = sysconfig_ops_write,
 	.write_complete = sysconfig_ops_write_complete,
+	.owner = THIS_MODULE,
 };
 
 int sysconfig_probe(struct sysconfig_priv *priv)
diff --git a/drivers/fpga/machxo2-spi.c b/drivers/fpga/machxo2-spi.c
index 905607992a12..46193a47f863 100644
--- a/drivers/fpga/machxo2-spi.c
+++ b/drivers/fpga/machxo2-spi.c
@@ -358,6 +358,7 @@  static const struct fpga_manager_ops machxo2_ops = {
 	.write_init = machxo2_write_init,
 	.write = machxo2_write,
 	.write_complete = machxo2_write_complete,
+	.owner = THIS_MODULE,
 };
 
 static int machxo2_spi_probe(struct spi_device *spi)
diff --git a/drivers/fpga/microchip-spi.c b/drivers/fpga/microchip-spi.c
index 2a82c726d6e5..023ccdf2d5da 100644
--- a/drivers/fpga/microchip-spi.c
+++ b/drivers/fpga/microchip-spi.c
@@ -362,6 +362,7 @@  static const struct fpga_manager_ops mpf_ops = {
 	.write_init = mpf_ops_write_init,
 	.write = mpf_ops_write,
 	.write_complete = mpf_ops_write_complete,
+	.owner = THIS_MODULE,
 };
 
 static int mpf_probe(struct spi_device *spi)
diff --git a/drivers/fpga/socfpga-a10.c b/drivers/fpga/socfpga-a10.c
index cc4861e345c9..a8ab74b30006 100644
--- a/drivers/fpga/socfpga-a10.c
+++ b/drivers/fpga/socfpga-a10.c
@@ -463,6 +463,7 @@  static const struct fpga_manager_ops socfpga_a10_fpga_mgr_ops = {
 	.write_init = socfpga_a10_fpga_write_init,
 	.write = socfpga_a10_fpga_write,
 	.write_complete = socfpga_a10_fpga_write_complete,
+	.owner = THIS_MODULE,
 };
 
 static int socfpga_a10_fpga_probe(struct platform_device *pdev)
diff --git a/drivers/fpga/socfpga.c b/drivers/fpga/socfpga.c
index 723ea0ad3f09..87f3f4a367d0 100644
--- a/drivers/fpga/socfpga.c
+++ b/drivers/fpga/socfpga.c
@@ -538,6 +538,7 @@  static const struct fpga_manager_ops socfpga_fpga_ops = {
 	.write_init = socfpga_fpga_ops_configure_init,
 	.write = socfpga_fpga_ops_configure_write,
 	.write_complete = socfpga_fpga_ops_configure_complete,
+	.owner = THIS_MODULE,
 };
 
 static int socfpga_fpga_probe(struct platform_device *pdev)
diff --git a/drivers/fpga/stratix10-soc.c b/drivers/fpga/stratix10-soc.c
index cacb9cc5757e..63a5a2fe4911 100644
--- a/drivers/fpga/stratix10-soc.c
+++ b/drivers/fpga/stratix10-soc.c
@@ -393,6 +393,7 @@  static const struct fpga_manager_ops s10_ops = {
 	.write_init = s10_ops_write_init,
 	.write = s10_ops_write,
 	.write_complete = s10_ops_write_complete,
+	.owner = THIS_MODULE,
 };
 
 static int s10_probe(struct platform_device *pdev)
diff --git a/drivers/fpga/tests/fpga-mgr-test.c b/drivers/fpga/tests/fpga-mgr-test.c
index 6acec55b60ce..4c2a3e98f8ad 100644
--- a/drivers/fpga/tests/fpga-mgr-test.c
+++ b/drivers/fpga/tests/fpga-mgr-test.c
@@ -187,6 +187,7 @@  static const struct fpga_manager_ops fake_mgr_ops = {
 	.write = op_write,
 	.write_sg = op_write_sg,
 	.write_complete = op_write_complete,
+	.owner = THIS_MODULE,
 };
 
 static void fpga_mgr_test_get(struct kunit *test)
diff --git a/drivers/fpga/tests/fpga-region-test.c b/drivers/fpga/tests/fpga-region-test.c
index baab07e3fc59..2705c1b33d09 100644
--- a/drivers/fpga/tests/fpga-region-test.c
+++ b/drivers/fpga/tests/fpga-region-test.c
@@ -52,6 +52,7 @@  static int op_write(struct fpga_manager *mgr, const char *buf, size_t count)
  */
 static const struct fpga_manager_ops fake_mgr_ops = {
 	.write = op_write,
+	.owner = THIS_MODULE,
 };
 
 static int op_enable_set(struct fpga_bridge *bridge, bool enable)
diff --git a/drivers/fpga/ts73xx-fpga.c b/drivers/fpga/ts73xx-fpga.c
index 4e1d2a4d3df4..20b8db0d150a 100644
--- a/drivers/fpga/ts73xx-fpga.c
+++ b/drivers/fpga/ts73xx-fpga.c
@@ -96,6 +96,7 @@  static const struct fpga_manager_ops ts73xx_fpga_ops = {
 	.write_init	= ts73xx_fpga_write_init,
 	.write		= ts73xx_fpga_write,
 	.write_complete	= ts73xx_fpga_write_complete,
+	.owner		= THIS_MODULE,
 };
 
 static int ts73xx_fpga_probe(struct platform_device *pdev)
diff --git a/drivers/fpga/versal-fpga.c b/drivers/fpga/versal-fpga.c
index 3710e8f01be2..02fd8ed36ff0 100644
--- a/drivers/fpga/versal-fpga.c
+++ b/drivers/fpga/versal-fpga.c
@@ -40,6 +40,7 @@  static int versal_fpga_ops_write(struct fpga_manager *mgr,
 static const struct fpga_manager_ops versal_fpga_ops = {
 	.write_init = versal_fpga_ops_write_init,
 	.write = versal_fpga_ops_write,
+	.owner = THIS_MODULE,
 };
 
 static int versal_fpga_probe(struct platform_device *pdev)
diff --git a/drivers/fpga/xilinx-spi.c b/drivers/fpga/xilinx-spi.c
index e1a227e7ff2a..d58cf0ccbd41 100644
--- a/drivers/fpga/xilinx-spi.c
+++ b/drivers/fpga/xilinx-spi.c
@@ -218,6 +218,7 @@  static const struct fpga_manager_ops xilinx_spi_ops = {
 	.write_init = xilinx_spi_write_init,
 	.write = xilinx_spi_write,
 	.write_complete = xilinx_spi_write_complete,
+	.owner = THIS_MODULE,
 };
 
 static int xilinx_spi_probe(struct spi_device *spi)
diff --git a/drivers/fpga/zynq-fpga.c b/drivers/fpga/zynq-fpga.c
index 96611d424a10..241e1fe48a13 100644
--- a/drivers/fpga/zynq-fpga.c
+++ b/drivers/fpga/zynq-fpga.c
@@ -548,6 +548,7 @@  static const struct fpga_manager_ops zynq_fpga_ops = {
 	.write_init = zynq_fpga_ops_write_init,
 	.write_sg = zynq_fpga_ops_write,
 	.write_complete = zynq_fpga_ops_write_complete,
+	.owner = THIS_MODULE,
 };
 
 static int zynq_fpga_probe(struct platform_device *pdev)
diff --git a/drivers/fpga/zynqmp-fpga.c b/drivers/fpga/zynqmp-fpga.c
index f3434e2c487b..2f66400d2330 100644
--- a/drivers/fpga/zynqmp-fpga.c
+++ b/drivers/fpga/zynqmp-fpga.c
@@ -101,6 +101,7 @@  static const struct fpga_manager_ops zynqmp_fpga_ops = {
 	.state = zynqmp_fpga_ops_state,
 	.write_init = zynqmp_fpga_ops_write_init,
 	.write = zynqmp_fpga_ops_write,
+	.owner = THIS_MODULE,
 };
 
 static int zynqmp_fpga_probe(struct platform_device *pdev)