[RFC net-next PATCH 0/2] net: Split ndo_set_rx_mode into snapshot and deferred write

I Viswanath posted 2 patches 3 months, 2 weeks ago
There is a newer version of this series
drivers/net/ethernet/realtek/8139cp.c | 67 ++++++++++++++++++---------
include/linux/netdevice.h             | 38 ++++++++++++++-
net/core/dev.c                        | 48 +++++++++++++++++--
3 files changed, 127 insertions(+), 26 deletions(-)
[RFC net-next PATCH 0/2] net: Split ndo_set_rx_mode into snapshot and deferred write
Posted by I Viswanath 3 months, 2 weeks ago
This is an implementation of the idea provided by Jakub here

https://lore.kernel.org/netdev/20250923163727.5e97abdb@kernel.org/

ndo_set_rx_mode is problematic because it cannot sleep.

To address this, this series proposes dividing existing set_rx_mode 
implementations into set_rx_mode and write_rx_config

The new set_rx_mode will be responsible for updating the rx_config
snapshot which will be used by ndo_write_rx_config to update the hardware

In brief, The callback implementations should look something like:

set_rx_mode():
    prepare_rx_config();
    update_snapshot();

write_rx_mode():
    read_snapshot();
    do_io();

write_rx_mode() is called from a work item making it sleepable 
during the do_io() section.

This model should work correctly if the following conditions hold:

1. write_rx_config should use the rx_config set by the most recent 
    call to set_rx_mode before its execution.

2. If a set_rx_mode call happens during execution of write_rx_config, 
    write_rx_config should be rescheduled.

3. All calls to modify rx_mode should pass through the set_rx_mode +
    schedule write_rx_config execution flow.

1 and 2 are guaranteed because of the properties of work queues

Drivers need to ensure 3

ndo_write_rx_config has been implemented for 8139cp driver as proof of 
concept

To use this model, a driver needs to implement the 
ndo_write_rx_config callback, have a member rx_config in 
the priv struct and replace all calls to set rx mode with 
schedule_and_set_rx_mode();

I Viswanath (2):
  net: Add ndo_write_rx_config and helper structs and functions:
  net: ethernet: Implement ndo_write_rx_config callback for the 8139cp
    driver

 drivers/net/ethernet/realtek/8139cp.c | 67 ++++++++++++++++++---------
 include/linux/netdevice.h             | 38 ++++++++++++++-
 net/core/dev.c                        | 48 +++++++++++++++++--
 3 files changed, 127 insertions(+), 26 deletions(-)
---
I tested the correctness of this by comparing rx_config request in set_rx_config and
written values in write_rx_config.

The prints I used:

After new_config is set in set_rx_mode:

printk("Requested Values: rx_config: %8x, mc_filter[0]: %8x, mc_filter[1]: %8x", new_config.rx_mode, new_config.mc_filter[0], new_config.mc_filter[1]);

After the writes in write_rx_config:

printk("RxConfig: %8x", cpr32(RxConfig));
printk("MC Filter[0]: %8x, MC Filter[1]: %8x", cpr32(MAR0 + 0), cpr32(MAR0 + 4));

Is this sufficient testing for a proof of concept?

I picked 8139cp because I could emulate it on QEMU and it was somewhat easy to refactor.

-- 
2.47.3
Re: [RFC net-next PATCH 0/2] net: Split ndo_set_rx_mode into snapshot and deferred write
Posted by Jacob Keller 3 months, 2 weeks ago

On 10/20/2025 6:48 AM, I Viswanath wrote:
> 3. All calls to modify rx_mode should pass through the set_rx_mode +
>     schedule write_rx_config execution flow.
> 
> 1 and 2 are guaranteed because of the properties of work queues
> 
> Drivers need to ensure 3
> 

Is there any mechanism to make this guarantee either implemented or at
least verified by the core? If not that, what about some sort of way to
lint driver code and make sure its correct?

In my experience, requiring drivers to do something right typically
results in a long tail of correcting drivers into the future..