Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH net 2/2] net: pse-pd: guard against freed PI data on regulator disable
From: Carlo Szelinsky @ 2026-06-15 18:00 UTC (permalink / raw)
  To: Simon Horman
  Cc: Oleksij Rempel, Kory Maincent, Andrew Lunn, David S . Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, netdev, linux-kernel,
	Carlo Szelinsky
In-Reply-To: <20260527122418.2410341-2-horms@kernel.org>

Hi Simon,

Thanks for forwarding this... I'd missed it the first time round.
Both points are valid; answering inline.

> [High]
> Is the pcdev->pi = NULL store correctly synchronized with the readers?
> ...
> Would taking pcdev->lock around the kfree()+NULL store in
> pse_release_pis() (so the NULL observation under pcdev->lock is
> authoritative) close that window? Alternatively, can the regulator
> unregister be ordered to run before pse_release_pis() so no consumer
> can invoke a regulator op while the PI array is being torn down?

Agreed, the guard is not authoritative as it stands. For v2 I'd take
pcdev->lock around the kfree() + pcdev->pi = NULL in pse_release_pis(),
so the NULL observed under the lock is authoritative.

I leaned away from reordering the regulator unregister, because both
the PI regulators and their consumer are devm-bound to pcdev->dev
(devm_regulator_register() and devm_regulator_get_exclusive()), so
reordering means tearing the regulators down by hand in
pse_controller_unregister() instead of letting devres do it, heavier
than a net fix wants. Does the contained fix (lock around the free)
work for you, or would you rather see the reorder?

One thing I'd like your read on for the commit message: the consumer
get is exclusive on pcdev->dev, so I couldn't pin down a concrete
external consumer that calls a regulator op on another CPU during
unbind. Do you have a specific path in mind, or should I describe the
lock as closing a narrow theoretical window rather than a proven race?
I'll add it either way.. I just want to make sure we are aligned :-)

> [High]
> Should the same NULL guard be applied to pse_pi_is_enabled() and
> pse_pi_enable()?
> ...
> Should these two callbacks receive the same guard, or alternatively
> should the unwind order be changed so that no callback can fire after
> the PI array is freed?

Yes. Both follow the same rdev_get_drvdata() -> mutex_lock() ->
unconditional pcdev->pi[id] pattern as the disable path, so for v2 I'll
add the same !pcdev->pi guard to pse_pi_is_enabled() and
pse_pi_enable().

Thanks,
Carlo

^ permalink raw reply

* Re: [PATCH net 1/2] net: pse-pd: disable IRQ before freeing PI data in unregister
From: Carlo Szelinsky @ 2026-06-15 17:59 UTC (permalink / raw)
  To: Simon Horman
  Cc: Oleksij Rempel, Kory Maincent, Andrew Lunn, David S . Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, netdev, linux-kernel,
	Carlo Szelinsky
In-Reply-To: <20260601162506.GY2256768@horms.kernel.org>

Hi Simon,

Thanks, this all makes sense.

> > Did I miss a path where the worker reaches pcdev->pi?
>
> I am concerned that this can occur if pse_send_ntf_worker()
> calls pse_control_put(). In which case __pse_control_release()
> may run, which accesses psec->pcdev->pi[psec->id].admin_state_enabled.

You're right, I was wrong. The worker does reach pcdev->pi through
pse_control_put() -> __pse_control_release(). For v2 I'll move
cancel_work_sync(&pcdev->ntf_work) before pse_release_pis() and fix
the patch 1 commit message, which wrongly claims the worker never
touches pcdev->pi.

> I wonder if you may have missed the AI-generated review of it that I
> forwarded.

I did, thanks for the hint. I went over it again more carefully
now. :-) Both [High] points seem to be valid, I'll reply to them inline 
on the 2/2 review thread so the discussion stays where it was raised.

> For these last three pre-existing items I think it's best to handle
> them separately.

Agreed, I'll send those on their own later.

Thanks,
Carlo

^ permalink raw reply

* Re: [PATCH RFC net-next 0/4] net: pse-pd: decouple controller lookup from MDIO probe
From: Carlo Szelinsky @ 2026-06-15 18:08 UTC (permalink / raw)
  To: Corey Leavitt, Kory Maincent, Jakub Kicinski, Russell King
  Cc: Oleksij Rempel, Andrew Lunn, Heiner Kallweit, David S . Miller,
	Eric Dumazet, Paolo Abeni, Simon Horman, netdev, linux-kernel
In-Reply-To: <177795581584.12433.14568712745388778289@leavitt.info>

Hi Corey,

just checking in on this one. Did you get a chance to continue with the
series, or is there anything I can help with to move it forward? I'm
happy to test a v2, and I can still run the SFP path on the
S600WP-5GT-2SX-SE once it's back on my desk.

Kory, Jakub, Russell :-) it would be great to hear your view on the
approach so Corey can plan the next version. The series fixed the probe
loop in my testing and I'd really like to see it land.

Thanks,
Carlo

^ permalink raw reply

* RE: [Intel-wired-lan] [PATCH iwl-next v12] ice: add support for unmanaged DPLL on E830 NIC
From: Mekala, SunithaX D @ 2026-06-15 18:14 UTC (permalink / raw)
  To: Kubalewski, Arkadiusz, intel-wired-lan@lists.osuosl.org
  Cc: pmenzel@molgen.mpg.de, linux-doc@vger.kernel.org,
	netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
	Kubalewski, Arkadiusz, Loktionov, Aleksandr, Nguyen, Anthony L,
	Fodor, Zoltan, horms@kernel.org, Kitszel, Przemyslaw,
	Grinberg, Vitaly
In-Reply-To: <20260508110856.550999-1-arkadiusz.kubalewski@intel.com>

> -----Original Message-----
> From: Intel-wired-lan <intel-wired-lan-bounces@osuosl.org> On Behalf Of Arkadiusz Kubalewski
> Sent: Friday, May 8, 2026 4:09 AM
> To: intel-wired-lan@lists.osuosl.org
> Cc: pmenzel@molgen.mpg.de; linux-doc@vger.kernel.org; netdev@vger.kernel.org; linux-kernel@vger.kernel.org; Kubalewski, Arkadiusz <arkadiusz.kubalewski@intel.com>; Loktionov, Aleksandr <aleksandr.loktionov@intel.com>; Nguyen, Anthony L <anthony.l.nguyen@intel.com>; Fodor, Zoltan <zoltan.fodor@intel.com>; horms@kernel.org; Kitszel, Przemyslaw <przemyslaw.kitszel@intel.com>; Grinberg, Vitaly <vgrinber@redhat.com>
> Subject: [Intel-wired-lan] [PATCH iwl-next v12] ice: add support for unmanaged DPLL on E830 NIC
>
> Hardware variants of E830 may support an unmanaged DPLL where the
> configuration is hardcoded within the hardware and firmware, meaning
> users cannot modify settings. However, users are able to check the DPLL
> lock status and obtain configuration information through the Linux DPLL
> and devlink health subsystem.
>
> Availability of 'loss of lock' health status code determines if such
> support is available, if true, register single DPLL device with 1 input
> and 1 output and provide hardcoded/read only properties of a pin and
> DPLL device. User is only allowed to check DPLL device status and receive
> notifications on DPLL lock status change.
>
> When present, the DPLL device locks to an external signal provided
> through the PCIe/OCP pin. The expected input signal is 1PPS
> (1 Pulse Per Second) embedded on a 10MHz reference clock.
> The DPLL produces output:
> - for MAC (Media Access Control) & PHY (Physical Layer) clocks,
> - 1PPS for synchronization of onboard PHC (Precision Hardware Clock) timer.
>
> Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
> Reviewed-by: Paul Menzel <pmenzel@molgen.mpg.de>
> Signed-off-by: Grzegorz Nitka <grzegorz.nitka@intel.com>
> Signed-off-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
> ---
> v12:
> - remove HAVE_DPLL_ESYNC ifdef
> - guard ice_dpll_lock_state_set_unmanaged() call in health event handler
>   with test_bit(ICE_FLAG_DPLL, pf->flags) and pf->dplls.unmanaged
> - add NULL guards for first/second dpll in ice_dpll_deinit_direct_pins()
> - add comments explaining intentional continue in
>   ice_dpll_init_info_direct_pins() for unmanaged pins
> v11:
> - rebase and fix conflicts
> ---
>  .../device_drivers/ethernet/intel/ice.rst     |  83 +++++
>  .../net/ethernet/intel/ice/devlink/health.c   |   6 +
>  .../net/ethernet/intel/ice/ice_adminq_cmd.h   |  12 +
>  drivers/net/ethernet/intel/ice/ice_common.c   | 136 ++++++++
>  drivers/net/ethernet/intel/ice/ice_common.h   |   8 +
>  drivers/net/ethernet/intel/ice/ice_dpll.c     | 314 ++++++++++++++++--
>  drivers/net/ethernet/intel/ice/ice_dpll.h     |  10 +
>  drivers/net/ethernet/intel/ice/ice_main.c     |  11 +-
>  drivers/net/ethernet/intel/ice/ice_ptp_hw.c   |  46 +++
>  drivers/net/ethernet/intel/ice/ice_ptp_hw.h   |   1 +
>  10 files changed, 604 insertions(+), 23 deletions(-)

Tested-by: Sunitha Mekala <sunithax.d.mekala@intel.com> (A Contingent worker at Intel)

^ permalink raw reply

* Re: [PATCH net-next 1/5] tls: reject the combination of TLS and sockmap
From: Jakub Kicinski @ 2026-06-15 18:20 UTC (permalink / raw)
  To: Jakub Sitnicki
  Cc: Paolo Abeni, davem, netdev, edumazet, andrew+netdev, horms, bpf,
	john.fastabend, sd
In-Reply-To: <87bjddc4xm.fsf@cloudflare.com>

On Sun, 14 Jun 2026 21:12:05 +0200 Jakub Sitnicki wrote:
> On Sun, Jun 14, 2026 at 10:09 AM +02, Paolo Abeni wrote:
> > On 6/14/26 3:40 AM, Jakub Kicinski wrote:  
> >> TLS and sockmap (BPF psock) integration hides a lot of latent bugs.
> >> Bugs which may be more or less relevant for real users but they
> >> are definitely exploitable.
> >> 
> >> We could not find anyone actively using this integration so let's
> >> reject this config. Adding a TLS socket to a sockmap was already
> >> rejected by sk_psock_init() through the inet_csk_has_ulp() check.
> >> We need to reject the attempts to configure the TLS keys (rather
> >> than adding the ULP itself) because checking prior to the ULP
> >> installation is tricky without risking a race with sockmap getting
> >> added in parallel (sockmap does not hold the socket lock).  
> >
> > Aren't both tls_ctx_create() and sk_psock_init() under (write) the
> > callback lock? Isn't that enough to avoid races?  
> 
> +1, but we would have to tweak inet_csk_has_ulp() to check for
> icsk_ulp_data in addition to icsk_ulp_ops. Only icsk_ulp_data is set
> under sk_callback_lock.
> 
> espintcp faces the same race...

Right, some deeper restructuring is needed for that. Also - I'm aware
of the race that Sashiko points out but we need to draw the line
somewhere if we want to hit the current merge window.

IOW I decided to keep it simple and focus on removing TLS+sockmap
integration, races in ULP vs sockmap init is a separate can of warms.

^ permalink raw reply

* Re: [PATCH net-next 0/9] atm: remove more dead code
From: Jakub Kicinski @ 2026-06-15 18:24 UTC (permalink / raw)
  To: Simon Horman
  Cc: davem, netdev, edumazet, pabeni, andrew+netdev, 3chas3, mitch,
	linux-atm-general, dwmw2
In-Reply-To: <20260615163319.GO712698@horms.kernel.org>

On Mon, 15 Jun 2026 17:33:19 +0100 Simon Horman wrote:
> On Sat, Jun 13, 2026 at 01:10:23PM -0700, Jakub Kicinski wrote:
> > Commit 6deb53595092 ("net: remove unused ATM protocols and legacy
> > ATM device drivers") removed a good chunk of old ATM drivers.
> > Our goal going forward is to limit the ATM support to PPPoATM
> > used in ADSL deployments.
> > 
> > A recent burst of AI generated fixes for net/atm/signaling.c and
> > net/atm/svc.c made me look closer at the remaining code. PPPoATM runs
> > over permanent virtual circuits (PF_ATMPVC) with a statically
> > configured VPI/VCI. We can drop switched virtual circuits (SVCs)
> > and user-space signaling (atmsigd) support. While digging around
> > I noticed a few more obviously dead pieces of code.
> > 
> > Annoyingly, I have applied one "fix" to QoS config which will
> > now make net conflict with this series :/
> > 
> > Jakub Kicinski (9):
> >   atm: remove AAL3/4 transport support
> >   atm: remove the unused send_oam / push_oam callbacks
> >   atm: remove dead SONET PHY ioctls
> >   atm: remove the local ATM (NSAP) address registry
> >   atm: remove SVC socket support and the signaling daemon interface
> >   atm: remove the unused change_qos device operation
> >   atm: remove the unused pre_send and send_bh device operations
> >   atm: remove unused ATM PHY operations
> >   atm: remove orphaned uAPI for deleted drivers, protocols and SVCs  
> 
> There is a compile time nit on patch 4/9.
> 
>   ../net/atm/resources.c: In function ‘atm_dev_ioctl’:
>   ../net/atm/resources.c:227:20: warning: variable ‘len’ set but not used [-Wunused-but-set-variable=]
>     227 |         int error, len, size = 0;
>         |                    ^~~
> 
> It might be nice to clear that one.
> But overall this looks good to me.
> 
> Reviewed-by: Simon Horman <horms@kernel.org>

Ugh, I thought clang is strictly better at finding these and
build-tested only with clang. Posting v2 shortly...

^ permalink raw reply

* Re: [PATCH net] sctp: hold socket lock when dumping endpoints in sctp_diag
From: Xin Long @ 2026-06-15 18:24 UTC (permalink / raw)
  To: Simon Horman
  Cc: netdev, linux-sctp, davem, kuba, edumazet, pabeni,
	marcelo.leitner, w, zdi-disclosures
In-Reply-To: <20260615110402.753443-2-horms@kernel.org>

On Mon, Jun 15, 2026 at 7:04 AM Simon Horman <horms@kernel.org> wrote:
>
> This is an AI-generated review of your patch. The human sending this
> email has considered the AI review valid, or at least plausible.
> Full review at: https://netdev-ai.bots.linux.dev/sashiko/
> ---
> sctp: hold socket lock when dumping endpoints in sctp_diag
>
> This change reworks SCTP_DIAG endpoint dumping so the socket lock is held
> across inet_sctp_diag_fill() to keep the bind address list stable, and
> moves position tracking into sctp_for_each_endpoint() which now drops the
> bucket read_lock_bh() before invoking the callback.
>
> A few questions on the new iterator and dump callback below.
>
> > diff --git a/net/sctp/diag.c b/net/sctp/diag.c
> > index d758f5c3e06e..9108272ca527 100644
> > --- a/net/sctp/diag.c
> > +++ b/net/sctp/diag.c
> > @@ -373,42 +374,36 @@ static int sctp_ep_dump(struct sctp_endpoint *ep, void *p)
> >       struct sk_buff *skb = commp->skb;
> >       struct netlink_callback *cb = commp->cb;
> >       const struct inet_diag_req_v2 *r = commp->r;
> > -     struct net *net = sock_net(skb->sk);
> >       struct inet_sock *inet = inet_sk(sk);
> >       int err = 0;
> >
> > -     if (!net_eq(sock_net(sk), net))
> > +     lock_sock(sk);
> > +     if (sctp_sstate(sk, CLOSED))
> >               goto out;
>
> [Low]
> The new unconditional skip on sctp_sstate(sk, CLOSED) does not appear to
> be described in the changelog.
>
> SCTP_SS_CLOSED maps to TCP_CLOSE, so a userspace caller that asks for
> TCPF_CLOSE in idiag_states will silently receive nothing from the
> endpoint hash for entries in that state.
>
> Most hashed endpoints are LISTENING (sctp_hash_endpoint() is called from
> sctp_listen_start() right after inet_sk_set_state(sk, SCTP_SS_LISTENING))
> so the practical effect is small, but is the intent to filter teardown
> windows (in which case ep->base.dead might be a more direct check) or to
> honour the user-requested idiag_states bitmask?  Either way, would it be
> worth calling this behaviour change out in the commit message?
>
> >
> > -     if (cb->args[4] < cb->args[1])
> > -             goto next;
> > -
> > -     if (!(r->idiag_states & TCPF_LISTEN) && !list_empty(&ep->asocs))
> > -             goto next;
> > +     if ((r->idiag_states & ~(TCPF_LISTEN | TCPF_CLOSE)) &&
> > +         !list_empty(&ep->asocs))
> > +             goto out;
>
> [ ... ]
>
> > @@ -479,41 +474,40 @@ static void sctp_diag_dump(struct sk_buff *skb, struct netlink_callback *cb,
> >               .r = r,
> >               .net_admin = netlink_net_capable(cb->skb, CAP_NET_ADMIN),
> >       };
> > -     int pos = cb->args[2];
> > +     int pos;
> >
> >       /* eps hashtable dumps
> >        * args:
> >        * 0 : if it will traversal listen sock
> >        * 1 : to record the sock pos of this time's traversal
> > -      * 4 : to work as a temporary variable to traversal list
> >        */
> >       if (cb->args[0] == 0) {
> > -             if (!(idiag_states & TCPF_LISTEN))
> > -                     goto skip;
> > -             if (sctp_for_each_endpoint(sctp_ep_dump, &commp))
> > -                     goto done;
> > -skip:
> > +             if (idiag_states & TCPF_LISTEN) {
> > +                     pos = cb->args[1];
> > +                     if (sctp_for_each_endpoint(sctp_ep_dump, net, &pos,
> > +                                                &commp)) {
> > +                             cb->args[1] = pos;
> > +                             return;
> > +                     }
> > +             }
> >               cb->args[0] = 1;
> >               cb->args[1] = 0;
> > -             cb->args[4] = 0;
> >       }
> >
> > +     if (!(idiag_states & ~(TCPF_LISTEN | TCPF_CLOSE)))
> > +             return;
> > +
> >       /* asocs by transport hashtable dump
> >        * args:
> >        * 1 : to record the assoc pos of this time's traversal
> >        * 2 : to record the transport pos of this time's traversal
> >        * 3 : to mark if we have dumped the ep info of the current asoc
> >        * 4 : to work as a temporary variable to traversal list
> > -      * 5 : to save the sk we get from travelsing the tsp list.
> >        */
> > -     if (!(idiag_states & ~(TCPF_LISTEN | TCPF_CLOSE)))
> > -             goto done;
> > -
> > +     pos = cb->args[2];
> >       sctp_transport_traverse_process(sctp_sock_filter, sctp_sock_dump,
> >                                       net, &pos, &commp);
> >       cb->args[2] = pos;
> > -
> > -done:
> >       cb->args[1] = cb->args[4];
> >       cb->args[4] = 0;
> >  }
>
> [Low]
> The commit message states that args[4] tracking is removed, but the
> asocs-phase comment block still lists:
>
>          * 4 : to work as a temporary variable to traversal list
>
> and the trailing epilogue still does:
>
>         cb->args[1] = cb->args[4];
>         cb->args[4] = 0;
>
> Are those leftovers from the eps-phase rewrite, or are they still needed
> by the asocs phase?  If args[4] is genuinely gone, should the comment
> and the epilogue be cleaned up too?
>
> The previous comment also listed:
>
>          * 5 : to save the sk we get from travelsing the tsp list.
>
> which is dropped here without further mention.  Is args[5] confirmed
> unused on the asocs path?
>
> > diff --git a/net/sctp/socket.c b/net/sctp/socket.c
> > index 66e12fb0c646..1ed405dedc01 100644
> > --- a/net/sctp/socket.c
> > +++ b/net/sctp/socket.c
> > @@ -5369,24 +5369,44 @@ struct sctp_transport *sctp_transport_get_idx(struct net *net,
> >  }
> >
> >  int sctp_for_each_endpoint(int (*cb)(struct sctp_endpoint *, void *),
> > -                        void *p) {
> > -     int err = 0;
> > -     int hash = 0;
> > -     struct sctp_endpoint *ep;
> > +                        struct net *net, int *pos, void *p) {
> > +     int err, hash = 0, idx = 0, start;
> >       struct sctp_hashbucket *head;
> > +     struct sctp_endpoint *ep;
> > +     struct sock *sk;
> >
> >       for (head = sctp_ep_hashtable; hash < sctp_ep_hashsize;
> >            hash++, head++) {
> > +             start = idx;
> > +again:
> > +             sk = NULL;
> >               read_lock_bh(&head->lock);
> >               sctp_for_each_hentry(ep, &head->chain) {
> > -                     err = cb(ep, p);
> > -                     if (err)
> > +                     if (sock_net(ep->base.sk) != net)
> > +                             continue;
> > +                     if (idx++ >= *pos) {
> > +                             sk = ep->base.sk;
> > +                             sock_hold(sk);
> >                               break;
> > +                     }
> >               }
> >               read_unlock_bh(&head->lock);
> > +
> > +             if (sk) {
> > +                     err = cb(ep, p);
>
> [Critical]
> Can ep be freed before this cb(ep, p) call?
>
> The bucket read_lock_bh() is dropped above, and only sock_hold(sk) is
> taken.  In sctp_endpoint_init() the reference direction is
> ep -> sk:
>
>         refcount_set(&ep->base.refcnt, 1);
>         ...
>         sock_hold(sk);
>
> so taking sock_hold(sk) does not pin ep.
>
> A concurrent close(2) on the same socket runs:
>
>   sctp_close()
>     -> release_sock()                  /* lock_sock dropped here */
>     -> sk_common_release()
>        -> sctp_destroy_sock()
>           -> sctp_endpoint_free()
>              -> sctp_unhash_endpoint()
>              -> sctp_endpoint_put()    /* refcount may reach 0 */
>                 -> call_rcu(&ep->rcu, sctp_endpoint_destroy_rcu)
>
> The destroy callback then does sctp_sk(sk)->ep = NULL; sock_put(sk);
> kfree(ep).
>
> Between read_unlock_bh() and cb(ep, p), this iterator is no longer in
> any RCU read-side section, and sctp_ep_dump() then calls lock_sock(sk)
> which may sleep.  That allows an RCU grace period to elapse before the
> callback dereferences ep at:
>
>         struct sock *sk = ep->base.sk;
>         ...
>         if ((r->idiag_states & ~(TCPF_LISTEN | TCPF_CLOSE)) &&
>             !list_empty(&ep->asocs))
>
> The sibling helpers in the same file pin the endpoint explicitly to
> avoid this:
>
>   sctp_transport_traverse_process()
>         if (sctp_endpoint_hold(ep)) { /* asoc can be peeled off */
>                 ret = cb(ep, tsp, p);
>                 ...
>                 sctp_endpoint_put(ep);
>         }
>
> Should sctp_for_each_endpoint() take sctp_endpoint_hold(ep) inside the
> bucket read_lock_bh() (while ep is still hashed and live) and a matching
> sctp_endpoint_put(ep) after cb returns?
>
> [Medium]
> Can this restart pattern miss or duplicate endpoints when the bucket is
> modified concurrently?
>
> After processing one ep the loop does:
>
>                         idx = start;
>                         goto again;
>
> which re-walks the bucket from the head and uses the running counter
> idx compared against *pos to skip already-emitted entries.
>
> __sctp_hash_endpoint() inserts at the hlist head and
> __sctp_unhash_endpoint() can delete arbitrary nodes, both under the
> bucket write_lock that this iterator releases between walks.  A
> concurrent listen() on a sibling endpoint shifts every existing entry's
> index by +1, and a concurrent close() before the cursor shifts indices
> by -1.
>
> Under that pattern, can SCTP_DIAG consumers observe duplicated
> endpoints (the previously-emitted entry now sits at the new *pos) or
> miss live endpoints (the next un-emitted entry is shifted past the
> cursor)?  The pre-patch sweep walked each bucket once with read_lock_bh
> held throughout, so this consistency window did not exist.
>
> [Low]
> For a bucket that contains N matching endpoints, does this restart
> pattern walk the bucket O(N^2) times?
>
> For a bucket {A,B,C} starting from *pos=0 the goto-again loop performs
> 1+2+3 traversals to dump three entries plus a final 3-entry walk that
> finds nothing and terminates with sk == NULL, which is nine list
> iterations to dump three endpoints.  The pre-patch code walked each
> bucket exactly once because the callback ran while still holding
> read_lock_bh().
>
> The commit message describes the change as simplifying endpoint
> traversal; could the description also note the new per-bucket scan
> cost, or could a cursor that survives unlock/relock be used instead?
>
> > +                     if (err) {
> > +                             sock_put(sk);
> > +                             return err;
> > +                     }
> > +                     sock_put(sk);
> > +                     (*pos)++;
> > +
> > +                     idx = start;
> > +                     goto again;
> > +             }
> >       }
> >
> > -     return err;
> > +     return 0;
> >  }
> >  EXPORT_SYMBOL_GPL(sctp_for_each_endpoint);

Low: #1, #2, #5, not really issues,
but worth mentioning about it in changelog.

Critical: #3, not valid.
socket refcnt can't be 0 when traversing the chain under read_lock_bh().

But it seems better to hold ep instead sk, and also to check
ep->base.dead instead of sk_state CLOSED.

Medium: #4, not valid.
it's completely okay to dump duplicate or skip socks because of
concurrent close() and listen() in diag.

will post v2 with some improvements mentioned above.

Thanks.

^ permalink raw reply

* Re: [PATCH net-next 1/3] net: bcmgenet: collapse TX priority queues to a single queue
From: Justin Chen @ 2026-06-15 18:40 UTC (permalink / raw)
  To: Nicolai Buchwitz, Doug Berger, Florian Fainelli,
	bcm-kernel-feedback-list, Andrew Lunn, David S . Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni
  Cc: Ovidiu Panait, netdev, linux-kernel
In-Reply-To: <20260612205915.3156127-2-nb@tipi-net.de>



On 6/12/26 1:59 PM, Nicolai Buchwitz wrote:
> The strict-priority TX queues can starve under multi-queue load and
> trip NETDEV_WATCHDOG. Justin's earlier series [1] worked around the
> symptom but kept the design.
> 
> The multi-queue design was originally used for STB use cases that are
> no longer needed, as confirmed by Justin. v1 hw_params already
> exercises a single-queue path. Point v2-v4 at the same configuration:
> ring 0 takes the full BD pool, every per-ring loop collapses to one
> iteration, and netif_set_real_num_tx_queues drops to 1 via the
> existing tx_queues + 1 arithmetic.
> 
> Tested on Raspberry Pi CM4 (BCM2711). The baseline kernel trips
> NETDEV_WATCHDOG within seconds under iperf3 UDP saturation
> (-u -b0 -P16 -t60). After the change the same test completes
> without a watchdog, and a single-stream 60 s UDP run sustains
> 956 Mbit/s with 0/4952890 datagrams lost. Single-stream TCP
> throughput is unchanged at 943 Mbit/s.
> 
> [1] https://lore.kernel.org/netdev/20260406175756.134567-1-justin.chen@broadcom.com/
> 
> Signed-off-by: Nicolai Buchwitz <nb@tipi-net.de>

Reviewed-by: Justin Chen <justin.chen@broadcom.com>
Tested-by: Justin Chen <justin.chen@broadcom.com>


^ permalink raw reply

* Re: [PATCH net-next 2/3] net: bcmgenet: remove dead priority queue plumbing
From: Justin Chen @ 2026-06-15 18:40 UTC (permalink / raw)
  To: Nicolai Buchwitz, Doug Berger, Florian Fainelli,
	bcm-kernel-feedback-list, Andrew Lunn, David S . Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni
  Cc: Ovidiu Panait, netdev, linux-kernel
In-Reply-To: <20260612205915.3156127-3-nb@tipi-net.de>



On 6/12/26 1:59 PM, Nicolai Buchwitz wrote:
> With a single TX ring there is nothing left to prioritize. Drop the
> unused register writes, enum entries, helper macros, and the dead
> "flow period for ring != 0" branch in bcmgenet_init_tx_ring().
> 
> The DMA_ARBITER_{RR,WRR,SP} and DMA_RING_BUF_PRIORITY_* HW defines
> are kept as register documentation.
> 
> No functional change.
> 
> Signed-off-by: Nicolai Buchwitz <nb@tipi-net.de>

Reviewed-by: Justin Chen <justin.chen@broadcom.com>
Tested-by: Justin Chen <justin.chen@broadcom.com>

^ permalink raw reply

* Re: [PATCH net-next 3/3] net: bcmgenet: allocate a single-queue netdev
From: Justin Chen @ 2026-06-15 18:40 UTC (permalink / raw)
  To: Nicolai Buchwitz, Doug Berger, Florian Fainelli,
	bcm-kernel-feedback-list, Andrew Lunn, David S . Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni
  Cc: Ovidiu Panait, netdev, linux-kernel
In-Reply-To: <20260612205915.3156127-4-nb@tipi-net.de>



On 6/12/26 1:59 PM, Nicolai Buchwitz wrote:
> The driver only uses TX ring 0 and RX ring 0, so allocating a netdev
> with GENET_MAX_MQ_CNT + 1 = 5 TX and 5 RX slots leaves four of each
> unused. Switch to alloc_etherdev() which allocates exactly one queue
> of each kind.
> 
> No functional change: netif_set_real_num_{tx,rx}_queues() already
> clamps the visible queue count to 1.
> 
> Signed-off-by: Nicolai Buchwitz <nb@tipi-net.de>

Reviewed-by: Justin Chen <justin.chen@broadcom.com>
Tested-by: Justin Chen <justin.chen@broadcom.com>

^ permalink raw reply

* Re: [PATCH net-next 1/5] tls: reject the combination of TLS and sockmap
From: Jakub Sitnicki @ 2026-06-15 18:45 UTC (permalink / raw)
  To: Jakub Kicinski
  Cc: davem, netdev, edumazet, pabeni, andrew+netdev, horms, bpf,
	john.fastabend, sd
In-Reply-To: <20260614014102.461064-2-kuba@kernel.org>

On Sat, Jun 13, 2026 at 06:40 PM -07, Jakub Kicinski wrote:
> TLS and sockmap (BPF psock) integration hides a lot of latent bugs.
> Bugs which may be more or less relevant for real users but they
> are definitely exploitable.
>
> We could not find anyone actively using this integration so let's
> reject this config. Adding a TLS socket to a sockmap was already
> rejected by sk_psock_init() through the inet_csk_has_ulp() check.
> We need to reject the attempts to configure the TLS keys (rather
> than adding the ULP itself) because checking prior to the ULP
> installation is tricky without risking a race with sockmap getting
> added in parallel (sockmap does not hold the socket lock).
>
> This patch is a minimal rejection of the feature. Subsequent patch
> in the series will do a light dead code removal. Full cleanup would
> require a major rewrite of the Tx path, we don't need skmsg any more.
>
> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
> ---

SGTM until we can come up with a generic way to exclude sockmapped
sockets from ktls and espintcp.

Reviewed-by: Jakub Sitnicki <jakub@cloudflare.com>

^ permalink raw reply

* Re: [PATCH net-next V3 00/15] net/mlx5: Add switchdev mode support for Socket Direct single netdev, part 2/2
From: patchwork-bot+netdevbpf @ 2026-06-15 18:50 UTC (permalink / raw)
  To: Tariq Toukan
  Cc: edumazet, kuba, pabeni, andrew+netdev, davem, saeedm, leon,
	mbloch, shayd, ohartoov, edwards, msanalla, horms, gbayer, kees,
	moshe, parav, phaddad, netdev, linux-rdma, linux-kernel, gal
In-Reply-To: <20260612113904.537595-1-tariqt@nvidia.com>

Hello:

This series was applied to netdev/net-next.git (main)
by Jakub Kicinski <kuba@kernel.org>:

On Fri, 12 Jun 2026 14:38:49 +0300 you wrote:
> Hi,
> 
> This is part 2. Find part 1 here:
> https://lore.kernel.org/all/20260531113954.395443-1-tariqt@nvidia.com/
> 
> This series enables Socket Direct single netdev to operate in switchdev
> mode with shared FDB. SD single netdev combines multiple PCI functions
> behind a single netdev interface. To support switchdev offloads, these
> functions must participate in virtual LAG (shared FDB).
> 
> [...]

Here is the summary with links:
  - [net-next,V3,01/15] net/mlx5: E-Switch, skip uplink IB rep load for SD secondary devices
    https://git.kernel.org/netdev/net-next/c/597baeb467d8
  - [net-next,V3,02/15] net/mlx5: devcom, expose locked variant of send_event
    https://git.kernel.org/netdev/net-next/c/95e26588c84b
  - [net-next,V3,03/15] net/mlx5: devcom, add DEVCOM_CANT_FAIL for non-rollback events
    https://git.kernel.org/netdev/net-next/c/d5e77e4d3023
  - [net-next,V3,04/15] net/mlx5: SD, make primary/secondary role determination more robust
    https://git.kernel.org/netdev/net-next/c/4b918a198389
  - [net-next,V3,05/15] net/mlx5: SD, add L2 table silent mode query support
    https://git.kernel.org/netdev/net-next/c/13158554a302
  - [net-next,V3,06/15] net/mlx5: SD, expend vport metadata for SD secondary devices
    https://git.kernel.org/netdev/net-next/c/a1bfe9f1da83
  - [net-next,V3,07/15] net/mlx5: SD, support switchdev mode transition with shared FDB
    https://git.kernel.org/netdev/net-next/c/2a3fb8b2f450
  - [net-next,V3,08/15] net/mlx5: E-Switch, notify SD on eswitch disable
    https://git.kernel.org/netdev/net-next/c/232de72bdea2
  - [net-next,V3,09/15] net/mlx5: LAG, store demux resources per master lag_func
    https://git.kernel.org/netdev/net-next/c/eaaf1ff178a0
  - [net-next,V3,10/15] net/mlx5: LAG, disable both regular and SD LAG on lag_disable_change
    https://git.kernel.org/netdev/net-next/c/ebd629e70045
  - [net-next,V3,11/15] net/mlx5: LAG, introduce software vport LAG implementation
    https://git.kernel.org/netdev/net-next/c/98d56915eef5
  - [net-next,V3,12/15] net/mlx5: LAG, add MPESW over SD LAG support
    https://git.kernel.org/netdev/net-next/c/de464720489c
  - [net-next,V3,13/15] net/mlx5: E-Switch, Tie rep load/unload to SD LAG state
    https://git.kernel.org/netdev/net-next/c/68c2dd59a6c7
  - [net-next,V3,14/15] net/mlx5: SD, defer vport metadata init until SD is ready
    https://git.kernel.org/netdev/net-next/c/e3a02f3ecb13
  - [net-next,V3,15/15] net/mlx5: SD, enable SD over ECPF and allow switchdev transition
    https://git.kernel.org/netdev/net-next/c/7bcfb19465fc

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



^ permalink raw reply

* Re: [PATCH v4 1/6] pds_core: add support for quiet devcmd failures
From: Rao, Nikhil @ 2026-06-15 18:53 UTC (permalink / raw)
  To: Simon Horman
  Cc: netdev, brett.creeley, andrew+netdev, davem, edumazet, kuba,
	pabeni, eric.joyner, Nikhil P. Rao
In-Reply-To: <20260615153400.772876-3-horms@kernel.org>


On 6/15/2026 8:34 AM, Simon Horman wrote:
> This is an AI-generated review of your patch. The human sending this
> email has considered the AI review valid, or at least plausible.
> Full review at: https://sashiko.dev
> ---
> pds_core: add support for quiet devcmd failures
> 
> This commit introduces support for suppressing error messages during device
> commands by adding a boolean parameter to wait and lock functions. It changes
> pdsc_devcmd_wait and pdsc_devcmd_locked into internal __pdsc_devcmd_wait and
> __pdsc_devcmd_locked variants that handle the new messaging flag. This
> functionality is intended for negotiating the PDS_CORE_IDENTITY_VERSION_2.
> 
>> diff --git a/drivers/net/ethernet/amd/pds_core/dev.c b/drivers/net/ethernet/amd/pds_core/dev.c
>> index bded6b33289ce..dd9989cfe6b3f 100644
>> --- a/drivers/net/ethernet/amd/pds_core/dev.c
>> +++ b/drivers/net/ethernet/amd/pds_core/dev.c
> 
> [ ... ]
> 
>> -int pdsc_devcmd_locked(struct pdsc *pdsc, union pds_core_dev_cmd *cmd,
>> -                    union pds_core_dev_comp *comp, int max_seconds)
>> +static int __pdsc_devcmd_locked(struct pdsc *pdsc, union pds_core_dev_cmd *cmd,
>> +                             union pds_core_dev_comp *comp, int max_seconds,
>> +                             const bool do_msg)
>>   {
>>        int err;
>>
>> @@ -197,7 +199,7 @@ int pdsc_devcmd_locked(struct pdsc *pdsc, union pds_core_dev_cmd *cmd,
>>
>>        memcpy_toio(&pdsc->cmd_regs->cmd, cmd, sizeof(*cmd));
>>        pdsc_devcmd_dbell(pdsc);
>> -     err = pdsc_devcmd_wait(pdsc, cmd->opcode, max_seconds);
>> +     err = __pdsc_devcmd_wait(pdsc, cmd->opcode, max_seconds, do_msg);
>>
>>        if ((err == -ENXIO || err == -ETIMEDOUT) && pdsc->wq)
>>                queue_work(pdsc->wq, &pdsc->health_work);
> 
> [Severity: Critical]
> This isn't a bug introduced by this patch, but it occurs in the function
> modified here.
> 
> Can this queue_work() call trigger a use-after-free during driver removal?
> 
> Looking at pdsc_remove() in drivers/net/ethernet/amd/pds_core/main.c,
> destroy_workqueue() is called but the pdsc->wq pointer is not cleared:
> 
> pdsc_remove() {
>      ...
>      if (pdsc->wq)
>          destroy_workqueue(pdsc->wq);
> 
>      mutex_lock(&pdsc->config_lock);
>      set_bit(PDSC_S_STOPPING_DRIVER, &pdsc->state);
> 
>      pdsc_stop(pdsc);
>      pdsc_teardown(pdsc, PDSC_TEARDOWN_REMOVING);
>      ...
> }
> 
> Subsequently, pdsc_teardown() issues a RESET command to the firmware.
> If the firmware is unresponsive and the command times out, we reach this
> error path in __pdsc_devcmd_locked(). Since the pdsc->wq pointer was never
> set to NULL, the check here succeeds, and it attempts to queue work to a
> destroyed workqueue.
> 
> Should pdsc->wq be explicitly set to NULL immediately after being destroyed
> in pdsc_remove() to prevent this?

Yes, this is a valid bug. I've already submitted a fix for this 
(Message-ID: 20260610025952.196470-1-nikhil.rao@amd.com)

The initial fix sets pdsc->wq = NULL after destruction, but sashiko 
raised a valid concern about a  NotifyQ ISR race window.

This is a pre-existing bug not introduced by this series, so I'll submit 
the reworked fix separately to -net.

Nikhil

^ permalink raw reply

* Re: [RESEND PATCH v1] net: dsa: motorcomm: add yt92xx dsa driver
From: David Yang @ 2026-06-15 18:55 UTC (permalink / raw)
  To: Kyle Switch
  Cc: andrew, olteanv, davem, edumazet, kuba, pabeni, horms, netdev,
	linux-kernel, ming.xu, xiaolin.xu, jianmin.wang, de.ge
In-Reply-To: <20260615111235.3544282-1-kyle.switch@motor-comm.com>

On Mon, Jun 15, 2026 at 7:12 PM Kyle Switch <kyle.switch@motor-comm.com> wrote:
>
> Add yt92xx dsa driver supports yt921x and yt922x switch series.
> To support more switch series in the future (e.g., yt923x), the most common configurations are abstracted into switch operation interfaces, due to yt921x and yt922x share similar register layouts and operational logic.

You are blindly plugging existing code into your SDK, without sorting
out register operations (for example in set_mac_eee and
port_change_mtu).

Do not post code you don't understand. Ask if you are not sure.

> +#define CMM_PARAM_CHK(expr, err_code)    \
> +       do {                             \
> +               if ((u32)(expr)) {       \
> +                       return err_code; \
> +               }                        \
> +       } while (0)
> +
> +#define CMM_ERR_CHK(op, ret)           \
> +       do {                           \
> +               ret = (op);            \
> +               if (ret != CMM_ERR_OK) \
> +                       return ret;    \
> +       } while (0)

Do not use macros like this.

> +#define GET_FIELD(value, low_bit, width) \
> +       (((value) >> (low_bit)) & ((1U << (width)) - 1))
> +#define CLR_FIELD(value, low_bit, width) \
> +       ((value) & (~(((1U << (width)) - 1) << (low_bit))))
> +
> +#define HAL_FIELD_SET(low_bit, width, entry, data)                    \
> +       do {                                                          \
> +               *(entry) &= (~(((1UL << (width)) - 1) << (low_bit))); \
> +               *(entry) |= ((data) << (low_bit));                    \
> +       } while (0)
> +
> +#define HAL_FIELD_GET(low_bit, width, entry, pdata) \
> +       (*(pdata) = (((*(entry)) >> (low_bit)) & ((1UL << (width)) - 1)))

FIELD_PREP() and FIELD_GET().

> +/*
> + * Macro Definition
> + */
> +#ifndef NULL
> +#define NULL 0
> +#endif
> +
> +#ifndef FALSE
> +#define FALSE 0
> +#endif
> +
> +#ifndef TRUE
> +#define TRUE 1
> +#endif

Nonsense.

> +       /* Print chipid here since we are interested in lower 16 bits */
> +       dev_info(dev,
> +                "Motorcomm %s ethernet switch.\n",
> +                info->name);

Stop copy-n-paste.

Please, start with a minimal patch that only marks functions which use
different registers/procedures and makes them virtual, and implement
them for yt922x in the future.

> +       {
> +               .compatible = "motorcomm,yt9215,8bytes",
> +               .data = &yt92xx_chip_info[YT9215_8B],
> +       },

Do not change devicetree compatible strings.

> --- a/include/uapi/linux/if_ether.h
> +++ b/include/uapi/linux/if_ether.h
> @@ -118,7 +118,7 @@
>  #define ETH_P_QINQ1    0x9100          /* deprecated QinQ VLAN [ NOT AN OFFICIALLY REGISTERED ID ] */
>  #define ETH_P_QINQ2    0x9200          /* deprecated QinQ VLAN [ NOT AN OFFICIALLY REGISTERED ID ] */
>  #define ETH_P_QINQ3    0x9300          /* deprecated QinQ VLAN [ NOT AN OFFICIALLY REGISTERED ID ] */
> -#define ETH_P_YT921X   0x9988          /* Motorcomm YT921x DSA [ NOT AN OFFICIALLY REGISTERED ID ] */
> +#define ETH_P_YT92XX   0x9988          /* Motorcomm YT92xx DSA [ NOT AN OFFICIALLY REGISTERED ID ] */
>  #define ETH_P_EDSA     0xDADA          /* Ethertype DSA [ NOT AN OFFICIALLY REGISTERED ID ] */
>  #define ETH_P_DSA_8021Q        0xDADB          /* Fake VLAN Header for DSA [ NOT AN OFFICIALLY REGISTERED ID ] */
>  #define ETH_P_DSA_A5PSW        0xE001          /* A5PSW Tag Value [ NOT AN OFFICIALLY REGISTERED ID ] */

UAPI stands for User-space API. Do not change it unless there is a
very very good reason.

> +/* To define the from cpu tag format 8 bytes:
> + *
> + * 0 1 2 3 4 5 6 7 | 0 1 2 3 4 5 6 7
> + *|<----------TPID 0x9988---------->|
> + *|<--RESERVE-->|<-----DST PORT---->|
> + *|-|<---------RESERVE------------->|
> + *|<------------------------------->|
> + */
> +#define YT922X_TAG_FORMAT2_NAME "yt922x-8b"
> +#define YT922X_FORMAT2_TAG_LEN                  8
> +#define YT922X_PKT_TYPE          GENMASK(15, 14)
> +#define YT922X_8B_CPUTAG_PKT_FROM_CPU      0x1
> +#define YT922X_8B_CPUTAG_SRC_PORT          GENMASK(6, 2)
> +#define YT922X_8B_CPUTAG_DST_PORTMASK      GENMASK(8, 0)
> +#define YT922X_8B_CPUTAG_DST_PORTMASK_0      BIT(15)
> +#define YT922X_8B_CPUTAG_DST_PORTMASK_0_EN      0x1
> +#define YT922X_8B_CPUTAG_FORCE_DST         BIT(9)
> +#define YT922X_8B_CPUTAG_FORCE_DST_EN      0x1

If yt922x tag format shares no common with yt921x, make a new tag driver.

> +static struct dsa_tag_driver *dsa_tag_driver_array[] = {
> +       &DSA_TAG_DRIVER_NAME(yt921x_netdev_ops),
> +       &DSA_TAG_DRIVER_NAME(yt922x_4b_netdev_ops),
> +       &DSA_TAG_DRIVER_NAME(yt922x_8b_netdev_ops),
> +};

If both are supported by the chip and 4b does nothing more than 8b
does, do not bother with it.

^ permalink raw reply

* Re: [PATCH v4 3/6] pds_core: add PLDM firmware update support via devlink flash
From: Rao, Nikhil @ 2026-06-15 19:04 UTC (permalink / raw)
  To: Simon Horman
  Cc: netdev, brett.creeley, andrew+netdev, davem, edumazet, kuba,
	pabeni, eric.joyner, nikhil.rao
In-Reply-To: <20260615153620.775599-1-horms@kernel.org>


On 6/15/2026 8:36 AM, Simon Horman wrote:
> This is an AI-generated review of your patch. The human sending this
> email has considered the AI review valid, or at least plausible.
> Full review at:https://sashiko.dev
> ---
> pds_core: add PLDM firmware update support via devlink flash
> 
> Implement PLDM FW Update in the pds_core driver using the upstream
> pldmfw API. This allows updating an entire PLDM FW package at once
> or updating specific firmware components by name.
> 
>> diff --git a/drivers/net/ethernet/amd/pds_core/fw.c b/drivers/net/ethernet/amd/pds_core/fw.c
>> --- a/drivers/net/ethernet/amd/pds_core/fw.c
>> +++ b/drivers/net/ethernet/amd/pds_core/fw.c
>> [ ... ]
>> @@ -195,3 +239,720 @@ int pdsc_firmware_update(struct pdsc *pdsc, const struct firmware *fw,
>> [ ... ]
>> +static int pdsc_flash_component_chunk(struct pdsc *pdsc, struct device *dev,
>> [ ... ]
>> +     err = pdsc_devcmd_send_component(pdsc, info, info_sz, dma_addr,
>> +                                      copy_sz, offset, slot_id, comp);
>> +     if (err == -ETIMEDOUT || err == -EAGAIN) {
>> +             pdsc_deferred_dma_add(pdsc, deferred, dma_addr,
>> +                                   component_data, copy_sz, DMA_TO_DEVICE);
>> +             return err;
>> +     }
> [Severity: High]
> Can this lead to a race condition that leaks the DMA mapping and memory?
> 
> If pdsc_devcmd_send_component() encounters a timeout in the lower level
> __pdsc_devcmd_locked() function, it will queue pdsc->health_work. The wrapper
> function __pdsc_devcmd_with_data_nomsg() will then release the devcmd_lock
> before returning the timeout error back here.
> 
> If the scheduled health_work runs and acquires devcmd_lock before this code
> reaches pdsc_deferred_dma_add(), it could execute a recovery devcmd and
> call pdsc_deferred_dma_free() on an empty list. When this thread resumes,
> it adds the timed-out buffer to the deferred DMA list, but its cleanup
> trigger has already fired, leaving the buffer leaked.
> 
>> [ ... ]
>> +int pdsc_firmware_update(struct pdsc *pdsc,
>> +                      struct devlink_flash_update_params *params,
>> +                      struct netlink_ext_ack *extack)
>> +{
>> +     int err;
>> +
>> +     if (pdsc->dev_ident.version >= PDS_CORE_IDENTITY_VERSION_2 &&
>> +         pdsc->dev_ident.capabilities &
>> +             cpu_to_le64(PDS_CORE_DEV_CAP_PLDM_FW_UPDATE))
>> +             err = pdsc_pldm_firmware_update(pdsc, params, extack,
>> +                                             params->fw);
>> +     else
>> +             err = pdsc_legacy_firmware_update(pdsc, params->fw, extack);

The race scenario is technically possible but does not cause a leak.

The deferred DMA cleanup is guaranteed by explicit calls in teardown paths:

1. pdsc_reset_prepare() calls pdsc_fw_down() then explicitly calls
    pdsc_deferred_dma_free() afterward
2. pdsc_remove() explicitly calls pdsc_deferred_dma_free() at the end

Even if health_work runs on an empty list, the deferred cleanup will
happen either on the next successful devcmd or in the explicit teardown 
paths.

> [Severity: High]
> Does this fallback path ignore the requested component name?
> 
> If the device does not support PLDM, the driver falls back to
> pdsc_legacy_firmware_update() which only takes the params->fw pointer.
> If a user requested a targeted component update using devlink, this would
> ignore the component filter and flash the entire monolithic image onto
> the device.
> 
> Should this explicitly check if params->component is set before falling
> back, and return -EOPNOTSUPP if a component is specified on legacy
> firmware?
> 

Yes, this is a valid bug - but it's pre-existing, not introduced by this
series. Before this patch, pdsc_dl_flash_update() already ignored
params->component. I'll submit a fix to -net as a standalone patch.

Thanks,
Nikhil

^ permalink raw reply

* Re: [PATCH net] sctp: hold socket lock when dumping endpoints in sctp_diag
From: Xin Long @ 2026-06-15 19:13 UTC (permalink / raw)
  To: Willy Tarreau
  Cc: network dev, linux-sctp, davem, kuba, Eric Dumazet, Paolo Abeni,
	Simon Horman, Marcelo Ricardo Leitner, Zero Day Initiative
In-Reply-To: <ai0CcdDCkhBO_RF2@1wt.eu>

On Sat, Jun 13, 2026 at 3:10 AM Willy Tarreau <w@1wt.eu> wrote:
>
> Hi,
>
> On Fri, Jun 12, 2026 at 01:59:38PM -0400, Xin Long wrote:
> > SCTP_DIAG endpoint dumping currently walks the endpoint hash table
> > without taking the socket lock before calling inet_sctp_diag_fill().
> >
> > This is problematic because inet_sctp_diag_fill() eventually calls
> > inet_diag_msg_sctpladdrs_fill(), which traverses the endpoint's local
> > address list twice: once to count entries for nla_reserve(), and once
> > again to copy the addresses into the netlink buffer.
> >
> > Since these two traversals are protected only by separate RCU read-side
> > critical sections, concurrent socket operations such as
> > SCTP_SOCKOPT_BINDX_REM may remove entries from the address list between
> > them. In that case, the number of copied addresses becomes smaller than
> > the originally reserved buffer size, leaving part of the netlink payload
> > uninitialized and potentially leaking kernel memory to user space.
> >
> > Fix this by changing sctp_for_each_endpoint() to iterate with net and
> > position awareness while taking a reference on each socket, then release
> > the endpoint hash bucket read_lock_bh() before invoking the callback.
> >
> > A socket reference is required because the callback acquires lock_sock(),
> > which must be called outside of read_lock_bh() since lock_sock() may
> > sleep. Holding a socket reference ensures the socket remains valid after
> > dropping the bucket lock and before acquiring the socket lock.
> >
> > With the socket lock held, concurrent bind-address modifications are
> > serialized against the diagnostic dump, ensuring the local address list
> > remains stable during buffer sizing and initialization.
> >
> > This also simplifies endpoint traversal by removing the temporary
> > callback local position tracking args[4] and moving dump progress
> > tracking into sctp_for_each_endpoint() itself.
> >
> > While at it, fix the idiag_states check in sctp_ep_dump() and skip ep
> > dumping when non LISTEN|CLOSE states are also requested and the ep has
> > assocs, since such cases will be handled later by sctp_sock_dump().
> >
> > Reported-by: Zero Day Initiative <zdi-disclosures@trendmicro.com>
>
> Please note that the original report suggested this reporter:
>
>    Nico Yip (@_cyeaa_) working with TrendAI Zero Day Initiative
>
I could find a public email for Nico Yip (@_cyeaa_), and I will
add this into the changelog as:

    This issue was reported by Nico Yip (@_cyeaa_) working with TrendAI Zero
    Day Initiative.

Thanks.

> > Fixes: 8f840e47f190 ("sctp: add the sctp_diag.c file")
> > Signed-off-by: Xin Long <lucien.xin@gmail.com>
> > ---
> >  include/net/sctp/sctp.h |  3 +-
> >  net/sctp/diag.c         | 62 +++++++++++++++++++----------------------
> >  net/sctp/socket.c       | 34 +++++++++++++++++-----
> >  3 files changed, 57 insertions(+), 42 deletions(-)
> >
> > diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h
> > index 58242b37b47a..cd82b05354a3 100644
> > --- a/include/net/sctp/sctp.h
> > +++ b/include/net/sctp/sctp.h
> > @@ -111,7 +111,8 @@ int sctp_transport_lookup_process(sctp_callback_t cb, struct net *net,
> >                                 const union sctp_addr *paddr, void *p, int dif);
> >  int sctp_transport_traverse_process(sctp_callback_t cb, sctp_callback_t cb_done,
> >                                   struct net *net, int *pos, void *p);
> > -int sctp_for_each_endpoint(int (*cb)(struct sctp_endpoint *, void *), void *p);
> > +int sctp_for_each_endpoint(int (*cb)(struct sctp_endpoint *, void *),
> > +                        struct net *net, int *pos, void *p);
> >  int sctp_get_sctp_info(struct sock *sk, struct sctp_association *asoc,
> >                      struct sctp_info *info);
> >
> > diff --git a/net/sctp/diag.c b/net/sctp/diag.c
> > index d758f5c3e06e..9108272ca527 100644
> > --- a/net/sctp/diag.c
> > +++ b/net/sctp/diag.c
> > @@ -92,6 +92,7 @@ static int inet_diag_msg_sctpladdrs_fill(struct sk_buff *skb,
> >               if (!--addrcnt)
> >                       break;
> >       }
> > +     WARN_ON_ONCE(addrcnt);
> >       rcu_read_unlock();
> >
> >       return 0;
> > @@ -373,42 +374,36 @@ static int sctp_ep_dump(struct sctp_endpoint *ep, void *p)
> >       struct sk_buff *skb = commp->skb;
> >       struct netlink_callback *cb = commp->cb;
> >       const struct inet_diag_req_v2 *r = commp->r;
> > -     struct net *net = sock_net(skb->sk);
> >       struct inet_sock *inet = inet_sk(sk);
> >       int err = 0;
> >
> > -     if (!net_eq(sock_net(sk), net))
> > +     lock_sock(sk);
> > +     if (sctp_sstate(sk, CLOSED))
> >               goto out;
> >
> > -     if (cb->args[4] < cb->args[1])
> > -             goto next;
> > -
> > -     if (!(r->idiag_states & TCPF_LISTEN) && !list_empty(&ep->asocs))
> > -             goto next;
> > +     if ((r->idiag_states & ~(TCPF_LISTEN | TCPF_CLOSE)) &&
> > +         !list_empty(&ep->asocs))
> > +             goto out;
> >
> >       if (r->sdiag_family != AF_UNSPEC &&
> >           sk->sk_family != r->sdiag_family)
> > -             goto next;
> > +             goto out;
> >
> >       if (r->id.idiag_sport != inet->inet_sport &&
> >           r->id.idiag_sport)
> > -             goto next;
> > +             goto out;
> >
> >       if (r->id.idiag_dport != inet->inet_dport &&
> >           r->id.idiag_dport)
> > -             goto next;
> > -
> > -     if (inet_sctp_diag_fill(sk, NULL, skb, r,
> > -                             sk_user_ns(NETLINK_CB(cb->skb).sk),
> > -                             NETLINK_CB(cb->skb).portid,
> > -                             cb->nlh->nlmsg_seq, NLM_F_MULTI,
> > -                             cb->nlh, commp->net_admin) < 0) {
> > -             err = 2;
> >               goto out;
> > -     }
> > -next:
> > -     cb->args[4]++;
> > +
> > +     err = inet_sctp_diag_fill(sk, NULL, skb, r,
> > +                               sk_user_ns(NETLINK_CB(cb->skb).sk),
> > +                               NETLINK_CB(cb->skb).portid,
> > +                               cb->nlh->nlmsg_seq, NLM_F_MULTI,
> > +                               cb->nlh, commp->net_admin);
> >  out:
> > +     release_sock(sk);
> >       return err;
> >  }
> >
> > @@ -479,41 +474,40 @@ static void sctp_diag_dump(struct sk_buff *skb, struct netlink_callback *cb,
> >               .r = r,
> >               .net_admin = netlink_net_capable(cb->skb, CAP_NET_ADMIN),
> >       };
> > -     int pos = cb->args[2];
> > +     int pos;
> >
> >       /* eps hashtable dumps
> >        * args:
> >        * 0 : if it will traversal listen sock
> >        * 1 : to record the sock pos of this time's traversal
> > -      * 4 : to work as a temporary variable to traversal list
> >        */
> >       if (cb->args[0] == 0) {
> > -             if (!(idiag_states & TCPF_LISTEN))
> > -                     goto skip;
> > -             if (sctp_for_each_endpoint(sctp_ep_dump, &commp))
> > -                     goto done;
> > -skip:
> > +             if (idiag_states & TCPF_LISTEN) {
> > +                     pos = cb->args[1];
> > +                     if (sctp_for_each_endpoint(sctp_ep_dump, net, &pos,
> > +                                                &commp)) {
> > +                             cb->args[1] = pos;
> > +                             return;
> > +                     }
> > +             }
> >               cb->args[0] = 1;
> >               cb->args[1] = 0;
> > -             cb->args[4] = 0;
> >       }
> >
> > +     if (!(idiag_states & ~(TCPF_LISTEN | TCPF_CLOSE)))
> > +             return;
> > +
> >       /* asocs by transport hashtable dump
> >        * args:
> >        * 1 : to record the assoc pos of this time's traversal
> >        * 2 : to record the transport pos of this time's traversal
> >        * 3 : to mark if we have dumped the ep info of the current asoc
> >        * 4 : to work as a temporary variable to traversal list
> > -      * 5 : to save the sk we get from travelsing the tsp list.
> >        */
> > -     if (!(idiag_states & ~(TCPF_LISTEN | TCPF_CLOSE)))
> > -             goto done;
> > -
> > +     pos = cb->args[2];
> >       sctp_transport_traverse_process(sctp_sock_filter, sctp_sock_dump,
> >                                       net, &pos, &commp);
> >       cb->args[2] = pos;
> > -
> > -done:
> >       cb->args[1] = cb->args[4];
> >       cb->args[4] = 0;
> >  }
> > diff --git a/net/sctp/socket.c b/net/sctp/socket.c
> > index 66e12fb0c646..1ed405dedc01 100644
> > --- a/net/sctp/socket.c
> > +++ b/net/sctp/socket.c
> > @@ -5369,24 +5369,44 @@ struct sctp_transport *sctp_transport_get_idx(struct net *net,
> >  }
> >
> >  int sctp_for_each_endpoint(int (*cb)(struct sctp_endpoint *, void *),
> > -                        void *p) {
> > -     int err = 0;
> > -     int hash = 0;
> > -     struct sctp_endpoint *ep;
> > +                        struct net *net, int *pos, void *p) {
> > +     int err, hash = 0, idx = 0, start;
> >       struct sctp_hashbucket *head;
> > +     struct sctp_endpoint *ep;
> > +     struct sock *sk;
> >
> >       for (head = sctp_ep_hashtable; hash < sctp_ep_hashsize;
> >            hash++, head++) {
> > +             start = idx;
> > +again:
> > +             sk = NULL;
> >               read_lock_bh(&head->lock);
> >               sctp_for_each_hentry(ep, &head->chain) {
> > -                     err = cb(ep, p);
> > -                     if (err)
> > +                     if (sock_net(ep->base.sk) != net)
> > +                             continue;
> > +                     if (idx++ >= *pos) {
> > +                             sk = ep->base.sk;
> > +                             sock_hold(sk);
> >                               break;
> > +                     }
> >               }
> >               read_unlock_bh(&head->lock);
> > +
> > +             if (sk) {
> > +                     err = cb(ep, p);
> > +                     if (err) {
> > +                             sock_put(sk);
> > +                             return err;
> > +                     }
> > +                     sock_put(sk);
> > +                     (*pos)++;
> > +
> > +                     idx = start;
> > +                     goto again;
> > +             }
> >       }
> >
> > -     return err;
> > +     return 0;
> >  }
> >  EXPORT_SYMBOL_GPL(sctp_for_each_endpoint);
> >
> > --
> > 2.47.1

^ permalink raw reply

* [RFC PATCH v1] PCI: Remove pcie_flr() and convert all callers to use pcie_reset_flr()
From: Farhan Ali @ 2026-06-15 19:21 UTC (permalink / raw)
  To: linux-kernel, linux-pci
  Cc: helgaas, giovanni.cabiddu, alifm, herbert, davem,
	dennis.dalessandro, jgg, leon, vikas.gupta, edumazet, kuba,
	pabeni, michael.chan, pavan.chebbi, claudiu.manoil,
	vladimir.oltean, wei.fang, xiaoning.wang, anthony.l.nguyen,
	przemyslaw.kitszel, kys, haiyangz, wei.liu, decui, longli,
	richardcochran, Andrew Lunn, Bjorn Helgaas, open list:QAT DRIVER,
	open list:CRYPTO API, open list:HFI1 DRIVER,
	open list:BROADCOM BNG_EN 800 GIGABIT ETHERNET DRIVER,
	open list:FREESCALE ENETC ETHERNET DRIVERS,
	moderated list:INTEL ETHERNET DRIVERS,
	open list:Hyper-V/Azure CORE AND DRIVERS

The pcie_reset_flr() function includes validation checks to verify FLR
support before performing the reset, while pcie_flr() performs the reset
unconditionally. Having both functions creates unnecessary complexity.

Commit 56f107d7813f ("PCI: Add pcie_reset_flr() with 'probe' argument")
introduced pcie_reset_flr() and removed pcie_has_flr(), converting callers
that previously used the pcie_has_flr() + pcie_flr() to use
pcie_reset_flr() instead. However, it did not convert all pcie_flr()
callers, leaving two different FLR mechanisms in the kernel.

One of the callers of pcie_flr(), the Intel 82599 Virtual Function has a
defect where FLR works despite not advertising FLR support in the PCIe
Device Capability register.  Rather than using pcie_flr() to work around
this, enable the FLR capability bit in devcap via an early quirk. This
allows the device to use the standard pcie_reset_flr() path instead of
requiring a device-specific reset method.

Remove pcie_flr() entirely and convert all remaining callers to
pcie_reset_flr(), ensuring consistent validation across the kernel.

Signed-off-by: Farhan Ali <alifm@linux.ibm.com>
---
 drivers/crypto/intel/qat/qat_common/adf_aer.c |  2 +-
 drivers/infiniband/hw/hfi1/chip.c             |  4 +-
 .../net/ethernet/broadcom/bnge/bnge_core.c    |  2 +-
 drivers/net/ethernet/broadcom/bnxt/bnxt.c     |  4 +-
 .../ethernet/cavium/liquidio/lio_vf_main.c    |  2 +-
 .../ethernet/cavium/liquidio/octeon_mailbox.c |  3 +-
 drivers/net/ethernet/freescale/enetc/enetc.c  |  2 +-
 .../ethernet/freescale/enetc/enetc_pci_mdio.c |  2 +-
 drivers/net/ethernet/intel/ice/ice_main.c     |  2 +-
 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c |  2 +-
 drivers/net/ethernet/microsoft/mana/mana_en.c |  3 +-
 drivers/pci/pci.c                             | 38 ++++++------------
 drivers/pci/quirks.c                          | 40 +++++++++----------
 drivers/ptp/ptp_netc.c                        |  2 +-
 include/linux/pci.h                           |  1 -
 15 files changed, 49 insertions(+), 60 deletions(-)

diff --git a/drivers/crypto/intel/qat/qat_common/adf_aer.c b/drivers/crypto/intel/qat/qat_common/adf_aer.c
index ed01fb9ad74e..a2364a59bc7f 100644
--- a/drivers/crypto/intel/qat/qat_common/adf_aer.c
+++ b/drivers/crypto/intel/qat/qat_common/adf_aer.c
@@ -89,7 +89,7 @@ EXPORT_SYMBOL_GPL(adf_reset_sbr);
 
 void adf_reset_flr(struct adf_accel_dev *accel_dev)
 {
-	pcie_flr(accel_to_pci_dev(accel_dev));
+	pcie_reset_flr(accel_to_pci_dev(accel_dev), PCI_RESET_DO_RESET);
 }
 EXPORT_SYMBOL_GPL(adf_reset_flr);
 
diff --git a/drivers/infiniband/hw/hfi1/chip.c b/drivers/infiniband/hw/hfi1/chip.c
index 44c524e45396..9f53d73e5e76 100644
--- a/drivers/infiniband/hw/hfi1/chip.c
+++ b/drivers/infiniband/hw/hfi1/chip.c
@@ -14042,7 +14042,7 @@ static int init_chip(struct hfi1_devdata *dd)
 		dd_dev_info(dd, "Resetting CSRs with FLR\n");
 
 		/* do the FLR, the DC reset will remain */
-		pcie_flr(dd->pcidev);
+		pcie_reset_flr(dd->pcidev, PCI_RESET_DO_RESET);
 
 		/* restore command and BARs */
 		ret = restore_pci_variables(dd);
@@ -14054,7 +14054,7 @@ static int init_chip(struct hfi1_devdata *dd)
 
 		if (is_ax(dd)) {
 			dd_dev_info(dd, "Resetting CSRs with FLR\n");
-			pcie_flr(dd->pcidev);
+			pcie_reset_flr(dd->pcidev, PCI_RESET_DO_RESET);
 			ret = restore_pci_variables(dd);
 			if (ret) {
 				dd_dev_err(dd, "%s: Could not restore PCI variables\n",
diff --git a/drivers/net/ethernet/broadcom/bnge/bnge_core.c b/drivers/net/ethernet/broadcom/bnge/bnge_core.c
index 68b74eb2c3a2..4aec01f53e54 100644
--- a/drivers/net/ethernet/broadcom/bnge/bnge_core.c
+++ b/drivers/net/ethernet/broadcom/bnge/bnge_core.c
@@ -274,7 +274,7 @@ static int bnge_probe_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 
 	if (is_kdump_kernel()) {
 		pci_clear_master(pdev);
-		pcie_flr(pdev);
+		pcie_reset_flr(pdev, PCI_RESET_DO_RESET);
 	}
 
 	rc = bnge_pci_enable(pdev);
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
index 35e1f8f663c7..21f8dcbe671e 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
@@ -16918,7 +16918,7 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 	 */
 	if (is_kdump_kernel()) {
 		pci_clear_master(pdev);
-		pcie_flr(pdev);
+		pcie_reset_flr(pdev, PCI_RESET_DO_RESET);
 	}
 
 	max_irqs = bnxt_get_max_irq(pdev);
@@ -17203,7 +17203,7 @@ static void bnxt_shutdown(struct pci_dev *pdev)
 		netif_close(dev);
 
 	if (bnxt_hwrm_func_drv_unrgtr(bp)) {
-		pcie_flr(pdev);
+		pcie_reset_flr(pdev, PCI_RESET_DO_RESET);
 		goto shutdown_exit;
 	}
 	bnxt_ptp_clear(bp);
diff --git a/drivers/net/ethernet/cavium/liquidio/lio_vf_main.c b/drivers/net/ethernet/cavium/liquidio/lio_vf_main.c
index 43c595f3b84e..7f3557d36341 100644
--- a/drivers/net/ethernet/cavium/liquidio/lio_vf_main.c
+++ b/drivers/net/ethernet/cavium/liquidio/lio_vf_main.c
@@ -429,7 +429,7 @@ static void octeon_pci_flr(struct octeon_device *oct)
 	pci_write_config_word(oct->pci_dev, PCI_COMMAND,
 			      PCI_COMMAND_INTX_DISABLE);
 
-	pcie_flr(oct->pci_dev);
+	pcie_reset_flr(oct->pci_dev, PCI_RESET_DO_RESET);
 
 	pci_cfg_access_unlock(oct->pci_dev);
 
diff --git a/drivers/net/ethernet/cavium/liquidio/octeon_mailbox.c b/drivers/net/ethernet/cavium/liquidio/octeon_mailbox.c
index ad685f5d0a13..be08e213aa9a 100644
--- a/drivers/net/ethernet/cavium/liquidio/octeon_mailbox.c
+++ b/drivers/net/ethernet/cavium/liquidio/octeon_mailbox.c
@@ -260,7 +260,8 @@ static int octeon_mbox_process_cmd(struct octeon_mbox *mbox,
 		dev_info(&oct->pci_dev->dev,
 			 "got a request for FLR from VF that owns DPI ring %u\n",
 			 mbox->q_no);
-		pcie_flr(oct->sriov_info.dpiring_to_vfpcidev_lut[mbox->q_no]);
+		pcie_reset_flr(oct->sriov_info.dpiring_to_vfpcidev_lut[mbox->q_no],
+			       PCI_RESET_DO_RESET);
 		break;
 
 	case OCTEON_PF_CHANGED_VF_MACADDR:
diff --git a/drivers/net/ethernet/freescale/enetc/enetc.c b/drivers/net/ethernet/freescale/enetc/enetc.c
index aa8a87124b10..c1c1b523abb5 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc.c
@@ -3635,7 +3635,7 @@ int enetc_pci_probe(struct pci_dev *pdev, const char *name, int sizeof_priv)
 	size_t alloc_size;
 	int err, len;
 
-	pcie_flr(pdev);
+	pcie_reset_flr(pdev, PCI_RESET_DO_RESET);
 	err = pci_enable_device_mem(pdev);
 	if (err)
 		return dev_err_probe(&pdev->dev, err, "device enable failed\n");
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_pci_mdio.c b/drivers/net/ethernet/freescale/enetc/enetc_pci_mdio.c
index e108cac8288d..cfccfca1981d 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_pci_mdio.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc_pci_mdio.c
@@ -73,7 +73,7 @@ static int enetc_pci_mdio_probe(struct pci_dev *pdev,
 	mdio_priv->mdio_base = ENETC_EMDIO_BASE;
 	snprintf(bus->id, MII_BUS_ID_SIZE, "%s", dev_name(dev));
 
-	pcie_flr(pdev);
+	pcie_reset_flr(pdev, PCI_RESET_DO_RESET);
 	err = pci_enable_device_mem(pdev);
 	if (err) {
 		dev_err(dev, "device enable failed\n");
diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
index e2fbe111f849..14b8a90625a8 100644
--- a/drivers/net/ethernet/intel/ice/ice_main.c
+++ b/drivers/net/ethernet/intel/ice/ice_main.c
@@ -5180,7 +5180,7 @@ ice_probe(struct pci_dev *pdev, const struct pci_device_id __always_unused *ent)
 	if (is_kdump_kernel()) {
 		pci_save_state(pdev);
 		pci_clear_master(pdev);
-		err = pcie_flr(pdev);
+		err = pcie_reset_flr(pdev, PCI_RESET_DO_RESET);
 		if (err)
 			return err;
 		pci_restore_state(pdev);
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index 2646ee6f295f..d8796a68094f 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -8318,7 +8318,7 @@ static void ixgbe_check_for_bad_vf(struct ixgbe_adapter *adapter)
 		if (status_reg != IXGBE_FAILED_READ_CFG_WORD &&
 		    status_reg & PCI_STATUS_REC_MASTER_ABORT) {
 			ixgbe_bad_vf_abort(adapter, vf);
-			pcie_flr(vfdev);
+			pcie_reset_flr(vfdev, PCI_RESET_DO_RESET);
 		}
 	}
 }
diff --git a/drivers/net/ethernet/microsoft/mana/mana_en.c b/drivers/net/ethernet/microsoft/mana/mana_en.c
index c9b1df1ed109..e51c1170aba7 100644
--- a/drivers/net/ethernet/microsoft/mana/mana_en.c
+++ b/drivers/net/ethernet/microsoft/mana/mana_en.c
@@ -3305,7 +3305,8 @@ static int mana_dealloc_queues(struct net_device *ndev)
 			}
 			if (atomic_read(&txq->pending_sends)) {
 				err =
-				    pcie_flr(to_pci_dev(gd->gdma_context->dev));
+				    pcie_reset_flr(to_pci_dev(gd->gdma_context->dev),
+						   PCI_RESET_DO_RESET);
 				if (err) {
 					netdev_err(ndev, "flr failed %d with %d pkts pending in txq %u\n",
 						   err,
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index d34266651ad0..878556ea50de 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -4321,16 +4321,25 @@ int pci_wait_for_pending_transaction(struct pci_dev *dev)
 EXPORT_SYMBOL(pci_wait_for_pending_transaction);
 
 /**
- * pcie_flr - initiate a PCIe function level reset
+ * pcie_reset_flr - initiate a PCIe function level reset
  * @dev: device to reset
+ * @probe: if true, return 0 if device can be reset this way
  *
- * Initiate a function level reset unconditionally on @dev without
- * checking any flags and DEVCAP
+ * Initiate a function level reset on @dev.
  */
-int pcie_flr(struct pci_dev *dev)
+int pcie_reset_flr(struct pci_dev *dev, bool probe)
 {
 	int ret;
 
+	if (dev->dev_flags & PCI_DEV_FLAGS_NO_FLR_RESET)
+		return -ENOTTY;
+
+	if (!(dev->devcap & PCI_EXP_DEVCAP_FLR))
+		return -ENOTTY;
+
+	if (probe)
+		return 0;
+
 	if (!pci_wait_for_pending_transaction(dev))
 		pci_err(dev, "timed out waiting for pending transaction; performing function level reset anyway\n");
 
@@ -4357,28 +4366,7 @@ int pcie_flr(struct pci_dev *dev)
 done:
 	pci_dev_reset_iommu_done(dev);
 	return ret;
-}
-EXPORT_SYMBOL_GPL(pcie_flr);
-
-/**
- * pcie_reset_flr - initiate a PCIe function level reset
- * @dev: device to reset
- * @probe: if true, return 0 if device can be reset this way
- *
- * Initiate a function level reset on @dev.
- */
-int pcie_reset_flr(struct pci_dev *dev, bool probe)
-{
-	if (dev->dev_flags & PCI_DEV_FLAGS_NO_FLR_RESET)
-		return -ENOTTY;
-
-	if (!(dev->devcap & PCI_EXP_DEVCAP_FLR))
-		return -ENOTTY;
-
-	if (probe)
-		return 0;
 
-	return pcie_flr(dev);
 }
 EXPORT_SYMBOL_GPL(pcie_reset_flr);
 
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index caaed1a01dc0..564f581599b8 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -2019,6 +2019,23 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_PXH_0,	quirk_pc
 DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_PXH_1,	quirk_pcie_pxh);
 DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_PXHV,	quirk_pcie_pxh);
 
+#define PCI_DEVICE_ID_INTEL_82599_SFP_VF   0x10ed
+static void quirk_intel_82599_sfp_virtfn(struct pci_dev *dev)
+{
+	/*
+	 * http://www.intel.com/content/dam/doc/datasheet/82599-10-gbe-controller-datasheet.pdf
+	 *
+	 * The 82599 supports FLR on VFs, but FLR support is reported only
+	 * in the PF DEVCAP (sec 9.3.10.4), not in the VF DEVCAP (sec 9.5).
+	 * So enable PCI_EXP_DEVCAP_FLR directly without first checking if it is
+	 * supported.
+	 */
+
+	dev->devcap |= PCI_EXP_DEVCAP_FLR;
+}
+
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82599_SFP_VF, quirk_intel_82599_sfp_virtfn);
+
 /*
  * Some Intel PCI Express chipsets have trouble with downstream device
  * power management.
@@ -3944,20 +3961,6 @@ DECLARE_PCI_FIXUP_SUSPEND_LATE(PCI_VENDOR_ID_INTEL,
  * reset a single function if other methods (e.g. FLR, PM D0->D3) are
  * not available.
  */
-static int reset_intel_82599_sfp_virtfn(struct pci_dev *dev, bool probe)
-{
-	/*
-	 * http://www.intel.com/content/dam/doc/datasheet/82599-10-gbe-controller-datasheet.pdf
-	 *
-	 * The 82599 supports FLR on VFs, but FLR support is reported only
-	 * in the PF DEVCAP (sec 9.3.10.4), not in the VF DEVCAP (sec 9.5).
-	 * Thus we must call pcie_flr() directly without first checking if it is
-	 * supported.
-	 */
-	if (!probe)
-		pcie_flr(dev);
-	return 0;
-}
 
 #define SOUTH_CHICKEN2		0xc2004
 #define PCH_PP_STATUS		0xc7200
@@ -4058,7 +4061,7 @@ static int reset_chelsio_generic_dev(struct pci_dev *dev, bool probe)
 				      PCI_MSIX_FLAGS_ENABLE |
 				      PCI_MSIX_FLAGS_MASKALL);
 
-	pcie_flr(dev);
+	pcie_reset_flr(dev, PCI_RESET_DO_RESET);
 
 	/*
 	 * Restore the configuration information (BAR values, etc.) including
@@ -4070,7 +4073,6 @@ static int reset_chelsio_generic_dev(struct pci_dev *dev, bool probe)
 	return 0;
 }
 
-#define PCI_DEVICE_ID_INTEL_82599_SFP_VF   0x10ed
 #define PCI_DEVICE_ID_INTEL_IVB_M_VGA      0x0156
 #define PCI_DEVICE_ID_INTEL_IVB_M2_VGA     0x0166
 
@@ -4150,7 +4152,7 @@ static int nvme_disable_and_flr(struct pci_dev *dev, bool probe)
 
 	pci_iounmap(dev, bar);
 
-	pcie_flr(dev);
+	pcie_reset_flr(dev, PCI_RESET_DO_RESET);
 
 	return 0;
 }
@@ -4207,7 +4209,7 @@ static int reset_hinic_vf_dev(struct pci_dev *pdev, bool probe)
 	val = val | HINIC_VF_FLR_PROC_BIT;
 	iowrite32be(val, bar + HINIC_VF_OP);
 
-	pcie_flr(pdev);
+	pcie_reset_flr(pdev, PCI_RESET_DO_RESET);
 
 	/*
 	 * The device must recapture its Bus and Device Numbers after FLR
@@ -4238,8 +4240,6 @@ static int reset_hinic_vf_dev(struct pci_dev *pdev, bool probe)
 }
 
 static const struct pci_dev_reset_methods pci_dev_reset_methods[] = {
-	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82599_SFP_VF,
-		 reset_intel_82599_sfp_virtfn },
 	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IVB_M_VGA,
 		reset_ivb_igd },
 	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IVB_M2_VGA,
diff --git a/drivers/ptp/ptp_netc.c b/drivers/ptp/ptp_netc.c
index 94e952ee6990..24bae237926a 100644
--- a/drivers/ptp/ptp_netc.c
+++ b/drivers/ptp/ptp_netc.c
@@ -802,7 +802,7 @@ static int netc_timer_pci_probe(struct pci_dev *pdev)
 	if (!priv)
 		return -ENOMEM;
 
-	pcie_flr(pdev);
+	pcie_reset_flr(pdev, PCI_RESET_DO_RESET);
 	err = pci_enable_device_mem(pdev);
 	if (err)
 		return dev_err_probe(dev, err, "Failed to enable device\n");
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 2c4454583c11..345f0821471a 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -1468,7 +1468,6 @@ u32 pcie_bandwidth_available(struct pci_dev *dev, struct pci_dev **limiting_dev,
 int pcie_link_speed_mbps(struct pci_dev *pdev);
 void pcie_print_link_status(struct pci_dev *dev);
 int pcie_reset_flr(struct pci_dev *dev, bool probe);
-int pcie_flr(struct pci_dev *dev);
 int __pci_reset_function_locked(struct pci_dev *dev);
 int pci_reset_function(struct pci_dev *dev);
 int pci_reset_function_locked(struct pci_dev *dev);
-- 
2.43.0


^ permalink raw reply related

* Re: [PATCH net-next v10 0/2] net: mana: add ethtool private flag for full-page RX buffers
From: Dipayaan Roy @ 2026-06-15 19:25 UTC (permalink / raw)
  To: kys, haiyangz, wei.liu, decui, andrew+netdev, davem, edumazet,
	kuba, pabeni, leon, longli, kotaranov, horms, shradhagupta,
	ssengar, ernis, shirazsaleem, linux-hyperv, netdev, linux-kernel,
	linux-rdma, stephen, jacob.e.keller, dipayanroy, leitao, kees,
	john.fastabend, hawk, bpf, daniel, ast, sdf, yury.norov,
	pavan.chebbi
  Cc: kuba
In-Reply-To: <20260602202801.1873742-1-dipayanroy@linux.microsoft.com>

On Tue, Jun 02, 2026 at 01:24:37PM -0700, Dipayaan Roy wrote:
> On some ARM64 platforms with 4K PAGE_SIZE, utilizing page_pool
> fragments for allocation in the RX refill path (~2kB buffer per fragment)
> causes 15-20% throughput regression under high connection counts
> (>16 TCP streams at 180+ Gbps). Using full-page buffers on these
> platforms shows no regression and restores line-rate performance.
> 
> This behavior is observed on a single platform; other platforms
> perform better with page_pool fragments, indicating this is not a
> page_pool issue but platform-specific.
> 
> This series adds an ethtool private flag "full-page-rx" to let the
> user opt in to one RX buffer per page:
> 
>   ethtool --set-priv-flags eth0 full-page-rx on
> 
> There is no behavioral change by default. The flag can be persisted
> via udev rule for affected platforms.
> 
> This series depends on the following fixes now merged in net-next:
>   17bfe0a8c014 ("net: mana: add NULL guards in teardown path to prevent panic")
>   5b05aa36ee24 ("net: mana: skip redundant detach on already-detached port")
> 
> Changes in v10:
>   - Rebased on net-next which now includes the prerequisite fixes.
>   - Recovery logic in mana_set_priv_flags() leverages the idempotent
>     mana_detach() from the merged fixes.
> Changes in v9:
>   - Added correct tree.
> Changes in v8:
>   - Fixed queue_reset_work recovery by restoring port_is_up before
>     scheduling reset so the handler can properly re-attach.
>   - Simplified "err && schedule_port_reset" to "schedule_port_reset".
> Changes in v7:
>   - Rebased onto net-next.
>   - Retained private flag approach after David Wei's testing on
>     Grace (ARM64) confirmed that fragment mode outperforms
>     full-page mode on other platforms, validating this is a
>     single-platform workaround rather than a generic issue.
> Changes in v6:
>   - Added missed maintainers.
> Changes in v5:
>   - Split prep refactor into separate patch (patch 1/2)
> Changes in v4:
>   - Dropping the smbios string parsing and add ethtool priv flag
>     to reconfigure the queues with full page rx buffers.
> Changes in v3:
>   - changed u8* to char*
> Changes in v2:
>   - separate reading string index and the string, remove inline.
> 
> Dipayaan Roy (2):
>   net: mana: refactor mana_get_strings() and mana_get_sset_count() to
>     use switch
>   net: mana: force full-page RX buffers via ethtool private flag
> 
>  drivers/net/ethernet/microsoft/mana/mana_en.c |  22 ++-
>  .../ethernet/microsoft/mana/mana_ethtool.c    | 178 +++++++++++++++---
>  include/net/mana/mana.h                       |   8 +
>  3 files changed, 177 insertions(+), 31 deletions(-)
> 
> -- 
> 2.43.0
>

Hi Jakub,

Just a gentle ping on this series. The approach was agreed upon, and it
has picked up a few Reviewed-by tags as well.

Please let me know if you need anything else from me, or if I should
resend it to collect the tags.

Thanks,
Dipayaan Roy
 

^ permalink raw reply

* Re: [RESEND PATCH v1] net: dsa: motorcomm: add yt92xx dsa driver
From: David Yang @ 2026-06-15 19:27 UTC (permalink / raw)
  To: Kyle Switch
  Cc: andrew, olteanv, davem, edumazet, kuba, pabeni, horms, netdev,
	linux-kernel, ming.xu, xiaolin.xu, jianmin.wang, de.ge
In-Reply-To: <CAAXyoMOp8mYLUx4CQBn=9R8rNqEsb8ybWD0z+=FJgh2j-F0s8A@mail.gmail.com>

On Tue, Jun 16, 2026 at 2:55 AM David Yang <mmyangfl@gmail.com> wrote:
> Please, start with a minimal patch that only marks functions which use
> different registers/procedures and makes them virtual, and implement
> them for yt922x in the future.

Sorry, this should be sketching yt922x_dsa_switch_ops with existing
methods and filling the unimplemented later.

^ permalink raw reply

* [PATCH net v2] sctp: hold socket lock when dumping endpoints in sctp_diag
From: Xin Long @ 2026-06-15 19:36 UTC (permalink / raw)
  To: network dev, linux-sctp
  Cc: davem, kuba, Eric Dumazet, Paolo Abeni, Simon Horman,
	Marcelo Ricardo Leitner, Willy Tarreau, Zero Day Initiative

SCTP_DIAG endpoint dumping was traversing endpoint address lists without
holding lock_sock(), while those lists could change concurrently via
socket operations (e.g., bindx changes). This creates a race where
nla_reserve() counts addresses under RCU protection, but the subsequent
copy may see fewer entries, potentially leaking uninitialized memory to
userspace.

Fix this by:

- Taking a reference on each endpoint during hash traversal
- Moving socket operations (lock_sock()) outside read_lock_bh()
- Serializing address list access during dump
- Reworking sctp_for_each_endpoint() to support restart-based traversal
  with (net, pos) tracking

Also:

- Add WARN_ON_ONCE() for inconsistent address counts
- Fix idiag_states filtering for LISTEN vs association cases
- Skip dumping endpoints being freed (ep->base.dead)
- Move dump position tracking into iterator, removing cb->args[4] and
  its comment for sctp_ep_dump().,
- Update the comment for cb->args[4] and remove the comment for unused
  cb->args[5] for sctp_sock_dump().

Note: traversal is restart-based and may re-scan buckets multiple times,
but this is acceptable due to small bucket sizes and required to support
sleeping-safe callbacks.

This issue was reported by Nico Yip (@_cyeaa_) working with TrendAI Zero
Day Initiative.

Reported-by: Zero Day Initiative <zdi-disclosures@trendmicro.com>
Fixes: 8f840e47f190 ("sctp: add the sctp_diag.c file")
Signed-off-by: Xin Long <lucien.xin@gmail.com>
---
v2:
  - Improve the changelog to cover more changes.
  - Check ep->base.dead instead of sctp_sstate(sk, CLOSED) in
    sctp_ep_dump().
  - Add an inline comment for idiag_states check in sctp_ep_dump().
  - Update the inline comment for cb->args[4] for sctp_sock_dump().
  - Simplify the code a bit by holding ep instead of sk in
    sctp_for_each_endpoint().
---
 include/net/sctp/sctp.h |  3 +-
 net/sctp/diag.c         | 67 ++++++++++++++++++++---------------------
 net/sctp/socket.c       | 29 +++++++++++++-----
 3 files changed, 56 insertions(+), 43 deletions(-)

diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h
index 58242b37b47a..cd82b05354a3 100644
--- a/include/net/sctp/sctp.h
+++ b/include/net/sctp/sctp.h
@@ -111,7 +111,8 @@ int sctp_transport_lookup_process(sctp_callback_t cb, struct net *net,
 				  const union sctp_addr *paddr, void *p, int dif);
 int sctp_transport_traverse_process(sctp_callback_t cb, sctp_callback_t cb_done,
 				    struct net *net, int *pos, void *p);
-int sctp_for_each_endpoint(int (*cb)(struct sctp_endpoint *, void *), void *p);
+int sctp_for_each_endpoint(int (*cb)(struct sctp_endpoint *, void *),
+			   struct net *net, int *pos, void *p);
 int sctp_get_sctp_info(struct sock *sk, struct sctp_association *asoc,
 		       struct sctp_info *info);
 
diff --git a/net/sctp/diag.c b/net/sctp/diag.c
index d758f5c3e06e..c2a0de2adf6f 100644
--- a/net/sctp/diag.c
+++ b/net/sctp/diag.c
@@ -92,6 +92,7 @@ static int inet_diag_msg_sctpladdrs_fill(struct sk_buff *skb,
 		if (!--addrcnt)
 			break;
 	}
+	WARN_ON_ONCE(addrcnt);
 	rcu_read_unlock();
 
 	return 0;
@@ -373,42 +374,39 @@ static int sctp_ep_dump(struct sctp_endpoint *ep, void *p)
 	struct sk_buff *skb = commp->skb;
 	struct netlink_callback *cb = commp->cb;
 	const struct inet_diag_req_v2 *r = commp->r;
-	struct net *net = sock_net(skb->sk);
 	struct inet_sock *inet = inet_sk(sk);
 	int err = 0;
 
-	if (!net_eq(sock_net(sk), net))
+	lock_sock(sk);
+	if (ep->base.dead)
 		goto out;
 
-	if (cb->args[4] < cb->args[1])
-		goto next;
-
-	if (!(r->idiag_states & TCPF_LISTEN) && !list_empty(&ep->asocs))
-		goto next;
+	/* Skip eps with assocs if non-LISTEN states were requested, since
+	 * they'll be dumped by sctp_sock_dump() during assoc traversal.
+	 */
+	if ((r->idiag_states & ~(TCPF_LISTEN | TCPF_CLOSE)) &&
+	    !list_empty(&ep->asocs))
+		goto out;
 
 	if (r->sdiag_family != AF_UNSPEC &&
 	    sk->sk_family != r->sdiag_family)
-		goto next;
+		goto out;
 
 	if (r->id.idiag_sport != inet->inet_sport &&
 	    r->id.idiag_sport)
-		goto next;
+		goto out;
 
 	if (r->id.idiag_dport != inet->inet_dport &&
 	    r->id.idiag_dport)
-		goto next;
-
-	if (inet_sctp_diag_fill(sk, NULL, skb, r,
-				sk_user_ns(NETLINK_CB(cb->skb).sk),
-				NETLINK_CB(cb->skb).portid,
-				cb->nlh->nlmsg_seq, NLM_F_MULTI,
-				cb->nlh, commp->net_admin) < 0) {
-		err = 2;
 		goto out;
-	}
-next:
-	cb->args[4]++;
+
+	err = inet_sctp_diag_fill(sk, NULL, skb, r,
+				  sk_user_ns(NETLINK_CB(cb->skb).sk),
+				  NETLINK_CB(cb->skb).portid,
+				  cb->nlh->nlmsg_seq, NLM_F_MULTI,
+				  cb->nlh, commp->net_admin);
 out:
+	release_sock(sk);
 	return err;
 }
 
@@ -479,41 +477,40 @@ static void sctp_diag_dump(struct sk_buff *skb, struct netlink_callback *cb,
 		.r = r,
 		.net_admin = netlink_net_capable(cb->skb, CAP_NET_ADMIN),
 	};
-	int pos = cb->args[2];
+	int pos;
 
 	/* eps hashtable dumps
 	 * args:
 	 * 0 : if it will traversal listen sock
 	 * 1 : to record the sock pos of this time's traversal
-	 * 4 : to work as a temporary variable to traversal list
 	 */
 	if (cb->args[0] == 0) {
-		if (!(idiag_states & TCPF_LISTEN))
-			goto skip;
-		if (sctp_for_each_endpoint(sctp_ep_dump, &commp))
-			goto done;
-skip:
+		if (idiag_states & TCPF_LISTEN) {
+			pos = cb->args[1];
+			if (sctp_for_each_endpoint(sctp_ep_dump, net, &pos,
+						   &commp)) {
+				cb->args[1] = pos;
+				return;
+			}
+		}
 		cb->args[0] = 1;
 		cb->args[1] = 0;
-		cb->args[4] = 0;
 	}
 
+	if (!(idiag_states & ~(TCPF_LISTEN | TCPF_CLOSE)))
+		return;
+
 	/* asocs by transport hashtable dump
 	 * args:
 	 * 1 : to record the assoc pos of this time's traversal
 	 * 2 : to record the transport pos of this time's traversal
 	 * 3 : to mark if we have dumped the ep info of the current asoc
-	 * 4 : to work as a temporary variable to traversal list
-	 * 5 : to save the sk we get from travelsing the tsp list.
+	 * 4 : to track position within ep->asocs list in sctp_sock_dump()
 	 */
-	if (!(idiag_states & ~(TCPF_LISTEN | TCPF_CLOSE)))
-		goto done;
-
+	pos = cb->args[2];
 	sctp_transport_traverse_process(sctp_sock_filter, sctp_sock_dump,
 					net, &pos, &commp);
 	cb->args[2] = pos;
-
-done:
 	cb->args[1] = cb->args[4];
 	cb->args[4] = 0;
 }
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 66e12fb0c646..c8481461f7d8 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -5369,24 +5369,39 @@ struct sctp_transport *sctp_transport_get_idx(struct net *net,
 }
 
 int sctp_for_each_endpoint(int (*cb)(struct sctp_endpoint *, void *),
-			   void *p) {
-	int err = 0;
-	int hash = 0;
-	struct sctp_endpoint *ep;
+			   struct net *net, int *pos, void *p) {
+	int err, hash = 0, idx = 0, start;
 	struct sctp_hashbucket *head;
+	struct sctp_endpoint *ep;
 
 	for (head = sctp_ep_hashtable; hash < sctp_ep_hashsize;
 	     hash++, head++) {
+		start = idx;
+again:
 		read_lock_bh(&head->lock);
 		sctp_for_each_hentry(ep, &head->chain) {
-			err = cb(ep, p);
-			if (err)
+			if (sock_net(ep->base.sk) != net)
+				continue;
+			if (idx++ >= *pos) {
+				sctp_endpoint_hold(ep);
 				break;
+			}
 		}
 		read_unlock_bh(&head->lock);
+
+		if (ep) {
+			err = cb(ep, p);
+			sctp_endpoint_put(ep);
+			if (err)
+				return err;
+			(*pos)++;
+
+			idx = start;
+			goto again;
+		}
 	}
 
-	return err;
+	return 0;
 }
 EXPORT_SYMBOL_GPL(sctp_for_each_endpoint);
 
-- 
2.47.1


^ permalink raw reply related

* [PATCH net-next v2 0/9] atm: remove more dead code
From: Jakub Kicinski @ 2026-06-15 19:44 UTC (permalink / raw)
  To: davem
  Cc: netdev, edumazet, pabeni, andrew+netdev, horms, 3chas3, mitch,
	linux-atm-general, dwmw2, Jakub Kicinski

Commit 6deb53595092 ("net: remove unused ATM protocols and legacy
ATM device drivers") removed a good chunk of old ATM drivers.
Our goal going forward is to limit the ATM support to PPPoATM
used in ADSL deployments.

A recent burst of AI generated fixes for net/atm/signaling.c and
net/atm/svc.c made me look closer at the remaining code. PPPoATM runs
over permanent virtual circuits (PF_ATMPVC) with a statically
configured VPI/VCI. We can drop switched virtual circuits (SVCs)
and user-space signaling (atmsigd) support. While digging around
I noticed a few more obviously dead pieces of code.

Annoyingly, I have applied one "fix" to QoS config which will
now make net conflict with this series :/

v2:
 - fix build warning on patch 4
v1: https://lore.kernel.org/20260613201032.77274-1-kuba@kernel.org

Jakub Kicinski (9):
  atm: remove AAL3/4 transport support
  atm: remove the unused send_oam / push_oam callbacks
  atm: remove dead SONET PHY ioctls
  atm: remove the local ATM (NSAP) address registry
  atm: remove SVC socket support and the signaling daemon interface
  atm: remove the unused change_qos device operation
  atm: remove the unused pre_send and send_bh device operations
  atm: remove unused ATM PHY operations
  atm: remove orphaned uAPI for deleted drivers, protocols and SVCs

 net/atm/Makefile                  |   2 +-
 include/linux/atm_tcp.h           |  24 --
 include/linux/atmdev.h            |  70 +--
 include/uapi/linux/atm_eni.h      |  24 --
 include/uapi/linux/atm_he.h       |  21 -
 include/uapi/linux/atm_idt77105.h |  29 --
 include/uapi/linux/atm_nicstar.h  |  54 ---
 include/uapi/linux/atm_tcp.h      |  62 ---
 include/uapi/linux/atm_zatm.h     |  47 --
 include/uapi/linux/atmarp.h       |  42 --
 include/uapi/linux/atmclip.h      |  22 -
 include/uapi/linux/atmdev.h       |  18 -
 include/uapi/linux/atmlec.h       |  92 ----
 include/uapi/linux/atmmpc.h       | 127 ------
 include/uapi/linux/atmsvc.h       |  56 ---
 net/atm/addr.h                    |  21 -
 net/atm/common.h                  |   5 -
 net/atm/protocols.h               |   1 -
 net/atm/signaling.h               |  31 --
 drivers/atm/solos-pci.c           |   4 -
 net/atm/addr.c                    | 162 -------
 net/atm/atm_sysfs.c               |  25 --
 net/atm/br2684.c                  |   3 +-
 net/atm/common.c                  |  73 +---
 net/atm/ioctl.c                   |  58 ---
 net/atm/pppoatm.c                 |   3 +-
 net/atm/proc.c                    |  56 ---
 net/atm/raw.c                     |  21 +-
 net/atm/resources.c               |  59 +--
 net/atm/signaling.c               | 297 -------------
 net/atm/svc.c                     | 695 ------------------------------
 31 files changed, 15 insertions(+), 2189 deletions(-)
 delete mode 100644 include/linux/atm_tcp.h
 delete mode 100644 include/uapi/linux/atm_eni.h
 delete mode 100644 include/uapi/linux/atm_he.h
 delete mode 100644 include/uapi/linux/atm_idt77105.h
 delete mode 100644 include/uapi/linux/atm_nicstar.h
 delete mode 100644 include/uapi/linux/atm_tcp.h
 delete mode 100644 include/uapi/linux/atm_zatm.h
 delete mode 100644 include/uapi/linux/atmarp.h
 delete mode 100644 include/uapi/linux/atmclip.h
 delete mode 100644 include/uapi/linux/atmlec.h
 delete mode 100644 include/uapi/linux/atmmpc.h
 delete mode 100644 include/uapi/linux/atmsvc.h
 delete mode 100644 net/atm/addr.h
 delete mode 100644 net/atm/signaling.h
 delete mode 100644 net/atm/addr.c
 delete mode 100644 net/atm/signaling.c
 delete mode 100644 net/atm/svc.c

-- 
2.54.0


^ permalink raw reply

* [PATCH net-next v2 1/9] atm: remove AAL3/4 transport support
From: Jakub Kicinski @ 2026-06-15 19:44 UTC (permalink / raw)
  To: davem
  Cc: netdev, edumazet, pabeni, andrew+netdev, horms, 3chas3, mitch,
	linux-atm-general, dwmw2, Jakub Kicinski
In-Reply-To: <20260615194416.752559-1-kuba@kernel.org>

AAL3/4 is an obsolete connection-oriented ATM adaptation layer that has
seen no real use since the SMDS-era hardware it was designed for (90s?).
We are only maintaining ATM support in-tree to keep PPPoATM running,
and PPPoATM runs over AAL5.

Drop the "raw" AAL3/4 transport (atm_init_aal34()) and the ATM_AAL34
cases in the connect and traffic-parameter paths. A vcc_connect() with
qos.aal == ATM_AAL34 now fails with -EPROTOTYPE.

uAPI cleanup is performed later, separately.

Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
 net/atm/protocols.h |  1 -
 net/atm/common.c    |  7 -------
 net/atm/raw.c       | 12 ------------
 3 files changed, 20 deletions(-)

diff --git a/net/atm/protocols.h b/net/atm/protocols.h
index 18d4d008bac3..30158efb5e1a 100644
--- a/net/atm/protocols.h
+++ b/net/atm/protocols.h
@@ -8,7 +8,6 @@
 #define NET_ATM_PROTOCOLS_H
 
 int atm_init_aal0(struct atm_vcc *vcc);	/* "raw" AAL0 */
-int atm_init_aal34(struct atm_vcc *vcc);/* "raw" AAL3/4 transport */
 int atm_init_aal5(struct atm_vcc *vcc);	/* "raw" AAL5 transport */
 
 #endif
diff --git a/net/atm/common.c b/net/atm/common.c
index 60132de4eebe..913f7e32ce41 100644
--- a/net/atm/common.c
+++ b/net/atm/common.c
@@ -293,9 +293,6 @@ static int adjust_tp(struct atm_trafprm *tp, unsigned char aal)
 	case ATM_AAL0:
 		max_sdu = ATM_CELL_SIZE-1;
 		break;
-	case ATM_AAL34:
-		max_sdu = ATM_MAX_AAL34_PDU;
-		break;
 	default:
 		pr_warn("AAL problems ... (%d)\n", aal);
 		fallthrough;
@@ -411,10 +408,6 @@ static int __vcc_connect(struct atm_vcc *vcc, struct atm_dev *dev, short vpi,
 		error = atm_init_aal0(vcc);
 		vcc->stats = &dev->stats.aal0;
 		break;
-	case ATM_AAL34:
-		error = atm_init_aal34(vcc);
-		vcc->stats = &dev->stats.aal34;
-		break;
 	case ATM_NO_AAL:
 		/* ATM_AAL5 is also used in the "0 for default" case */
 		vcc->qos.aal = ATM_AAL5;
diff --git a/net/atm/raw.c b/net/atm/raw.c
index 1e6511ec842c..0d36aeb3671b 100644
--- a/net/atm/raw.c
+++ b/net/atm/raw.c
@@ -68,18 +68,6 @@ int atm_init_aal0(struct atm_vcc *vcc)
 	return 0;
 }
 
-int atm_init_aal34(struct atm_vcc *vcc)
-{
-	vcc->push = atm_push_raw;
-	vcc->pop = atm_pop_raw;
-	vcc->push_oam = NULL;
-	if (vcc->dev->ops->send_bh)
-		vcc->send = vcc->dev->ops->send_bh;
-	else
-		vcc->send = vcc->dev->ops->send;
-	return 0;
-}
-
 int atm_init_aal5(struct atm_vcc *vcc)
 {
 	vcc->push = atm_push_raw;
-- 
2.54.0


^ permalink raw reply related

* [PATCH net-next v2 2/9] atm: remove the unused send_oam / push_oam callbacks
From: Jakub Kicinski @ 2026-06-15 19:44 UTC (permalink / raw)
  To: davem
  Cc: netdev, edumazet, pabeni, andrew+netdev, horms, 3chas3, mitch,
	linux-atm-general, dwmw2, Jakub Kicinski
In-Reply-To: <20260615194416.752559-1-kuba@kernel.org>

The atmdev_ops::send_oam device operation and the atm_vcc::push_oam
callback were the kernel's interface for raw F4/F5 OAM cell exchange.
Nothing assigns them a non-NULL value and nothing ever invokes them:
the core only ever initialises push_oam to NULL (in vcc_create() and the
AAL init helpers) and the Solos driver only lists send_oam = NULL for
documentation. The drivers that actually drove OAM through these hooks
were removed along with the legacy ATM adapters.

Drop both callbacks and the NULL initialisers.

Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
 include/linux/atmdev.h  | 8 --------
 drivers/atm/solos-pci.c | 1 -
 net/atm/common.c        | 1 -
 net/atm/raw.c           | 2 --
 4 files changed, 12 deletions(-)

diff --git a/include/linux/atmdev.h b/include/linux/atmdev.h
index 82a32526df64..71c5bf6950e3 100644
--- a/include/linux/atmdev.h
+++ b/include/linux/atmdev.h
@@ -104,7 +104,6 @@ struct atm_vcc {
 	void (*release_cb)(struct atm_vcc *vcc); /* release_sock callback */
 	void (*push)(struct atm_vcc *vcc,struct sk_buff *skb);
 	void (*pop)(struct atm_vcc *vcc,struct sk_buff *skb); /* optional */
-	int (*push_oam)(struct atm_vcc *vcc,void *cell);
 	int (*send)(struct atm_vcc *vcc,struct sk_buff *skb);
 	void		*dev_data;	/* per-device data */
 	void		*proto_data;	/* per-protocol data */
@@ -170,12 +169,6 @@ struct atm_dev {
 	struct list_head dev_list;	/* linkage */
 };
 
- 
-/* OF: send_Oam Flags */
-
-#define ATM_OF_IMMED  1		/* Attempt immediate delivery */
-#define ATM_OF_INRATE 2		/* Attempt in-rate delivery */
-
 struct atmdev_ops { /* only send is required */
 	void (*dev_close)(struct atm_dev *dev);
 	int (*open)(struct atm_vcc *vcc);
@@ -188,7 +181,6 @@ struct atmdev_ops { /* only send is required */
 	int (*pre_send)(struct atm_vcc *vcc, struct sk_buff *skb);
 	int (*send)(struct atm_vcc *vcc,struct sk_buff *skb);
 	int (*send_bh)(struct atm_vcc *vcc, struct sk_buff *skb);
-	int (*send_oam)(struct atm_vcc *vcc,void *cell,int flags);
 	void (*phy_put)(struct atm_dev *dev,unsigned char value,
 	    unsigned long addr);
 	unsigned char (*phy_get)(struct atm_dev *dev,unsigned long addr);
diff --git a/drivers/atm/solos-pci.c b/drivers/atm/solos-pci.c
index bcb1353877e4..4ad170a858ee 100644
--- a/drivers/atm/solos-pci.c
+++ b/drivers/atm/solos-pci.c
@@ -1180,7 +1180,6 @@ static const struct atmdev_ops fpga_ops = {
 	.close =	pclose,
 	.ioctl =	NULL,
 	.send =		psend,
-	.send_oam =	NULL,
 	.phy_put =	NULL,
 	.phy_get =	NULL,
 	.change_qos =	NULL,
diff --git a/net/atm/common.c b/net/atm/common.c
index 913f7e32ce41..c6e87fc9bbfc 100644
--- a/net/atm/common.c
+++ b/net/atm/common.c
@@ -163,7 +163,6 @@ int vcc_create(struct net *net, struct socket *sock, int protocol, int family, i
 	vcc->push = NULL;
 	vcc->pop = NULL;
 	vcc->owner = NULL;
-	vcc->push_oam = NULL;
 	vcc->release_cb = NULL;
 	vcc->vpi = vcc->vci = 0; /* no VCI/VPI yet */
 	vcc->atm_options = vcc->aal_options = 0;
diff --git a/net/atm/raw.c b/net/atm/raw.c
index 0d36aeb3671b..1d6ac7b0c4e5 100644
--- a/net/atm/raw.c
+++ b/net/atm/raw.c
@@ -63,7 +63,6 @@ int atm_init_aal0(struct atm_vcc *vcc)
 {
 	vcc->push = atm_push_raw;
 	vcc->pop = atm_pop_raw;
-	vcc->push_oam = NULL;
 	vcc->send = atm_send_aal0;
 	return 0;
 }
@@ -72,7 +71,6 @@ int atm_init_aal5(struct atm_vcc *vcc)
 {
 	vcc->push = atm_push_raw;
 	vcc->pop = atm_pop_raw;
-	vcc->push_oam = NULL;
 	if (vcc->dev->ops->send_bh)
 		vcc->send = vcc->dev->ops->send_bh;
 	else
-- 
2.54.0


^ permalink raw reply related

* [PATCH net-next v2 3/9] atm: remove dead SONET PHY ioctls
From: Jakub Kicinski @ 2026-06-15 19:44 UTC (permalink / raw)
  To: davem
  Cc: netdev, edumazet, pabeni, andrew+netdev, horms, 3chas3, mitch,
	linux-atm-general, dwmw2, Jakub Kicinski
In-Reply-To: <20260615194416.752559-1-kuba@kernel.org>

The SONET_* ioctls are SONET/SDH PHY controls that atm_dev_ioctl() and
the compat path only ever forwarded to the driver's ->ioctl() handler.
The PHY drivers that implemented them (the S/UNI library and the framers
on the removed PCI/SBUS adapters) are gone, and neither surviving driver
services them: solos-pci has no ->ioctl, and usbatm handles only
ATM_QUERYLOOP. They now uniformly return an error regardless.

Drop the SONET compat passthrough and the SONET cases in atm_dev_ioctl(),
along with the now-unused linux/sonet.h includes. The SONET_* uAPI
definitions are untouched.

Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
 net/atm/ioctl.c     | 13 -------------
 net/atm/resources.c |  5 -----
 2 files changed, 18 deletions(-)

diff --git a/net/atm/ioctl.c b/net/atm/ioctl.c
index 0f3f9ad8301f..4f2d185bf2f0 100644
--- a/net/atm/ioctl.c
+++ b/net/atm/ioctl.c
@@ -13,7 +13,6 @@
 #include <linux/atmdev.h>
 #include <linux/atmarp.h>	/* manifest constants */
 #include <linux/capability.h>
-#include <linux/sonet.h>	/* for ioctls */
 #include <linux/atmsvc.h>
 #include <linux/mutex.h>
 #include <asm/ioctls.h>
@@ -290,18 +289,6 @@ static int do_atm_ioctl(struct socket *sock, unsigned int cmd32,
 	int i;
 	unsigned int cmd = 0;
 
-	switch (cmd32) {
-	case SONET_GETSTAT:
-	case SONET_GETSTATZ:
-	case SONET_GETDIAG:
-	case SONET_SETDIAG:
-	case SONET_CLRDIAG:
-	case SONET_SETFRAMING:
-	case SONET_GETFRAMING:
-	case SONET_GETFRSENSE:
-		return do_atmif_sioc(sock, cmd32, arg);
-	}
-
 	for (i = 0; i < NR_ATM_IOCTL; i++) {
 		if (cmd32 == atm_ioctl_map[i].cmd32) {
 			cmd = atm_ioctl_map[i].cmd;
diff --git a/net/atm/resources.c b/net/atm/resources.c
index 939452a610c0..7aac25e917b4 100644
--- a/net/atm/resources.c
+++ b/net/atm/resources.c
@@ -13,7 +13,6 @@
 #include <linux/ctype.h>
 #include <linux/string.h>
 #include <linux/atmdev.h>
-#include <linux/sonet.h>
 #include <linux/kernel.h> /* for barrier */
 #include <linux/module.h>
 #include <linux/bitops.h>
@@ -361,10 +360,6 @@ int atm_dev_ioctl(unsigned int cmd, void __user *buf, int __user *sioc_len,
 		}
 		fallthrough;
 	case ATM_SETCIRANGE:
-	case SONET_GETSTATZ:
-	case SONET_SETDIAG:
-	case SONET_CLRDIAG:
-	case SONET_SETFRAMING:
 		if (!capable(CAP_NET_ADMIN)) {
 			error = -EPERM;
 			goto done;
-- 
2.54.0


^ permalink raw reply related

* [PATCH net-next v2 4/9] atm: remove the local ATM (NSAP) address registry
From: Jakub Kicinski @ 2026-06-15 19:44 UTC (permalink / raw)
  To: davem
  Cc: netdev, edumazet, pabeni, andrew+netdev, horms, 3chas3, mitch,
	linux-atm-general, dwmw2, Jakub Kicinski
In-Reply-To: <20260615194416.752559-1-kuba@kernel.org>

net/atm/addr.c maintained the per-device lists of local NSAP addresses
(dev->local) and ILMI-learned LECS addresses (dev->lecs). These exist
solely to serve SVC signaling: the lists are populated through the
ATM_{ADD,DEL,RST}ADDR / ATM_{ADD,DEL,GET}LECSADDR ioctls used by the
atmsigd / ILMI daemons, and consumed when registering addresses with the
signaling daemon. The LECS list belonged to LAN Emulation, which has
been removed.

With no SVC users in a DSL-only configuration these lists are always
empty, so drop the registry entirely:

 - remove the ADDR/LECSADDR/RSTADDR ioctls
 - drop the now-always-empty "atmaddress" sysfs attribute
 - remove the dev->local / dev->lecs lists, structs and enums
 - delete net/atm/addr.c and net/atm/addr.h

The device ESI ("MAC" address) and its ATM_{G,S}ETESI ioctls and
"address" sysfs attribute are retained - the USB DSL modems populate
the ESI.

Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
v2:
 - delete the get_user(sioc_len), technically this is a behavior change
   since we no longer validate the access to sioc_len before executing
   the ioctl, but I suspect this level of bug-wards compatibility is
   theoretical
v1: https://lore.kernel.org/20260613201032.77274-5-kuba@kernel.org
---
 net/atm/Makefile       |   2 +-
 include/linux/atmdev.h |   9 ---
 net/atm/addr.h         |  21 ------
 net/atm/addr.c         | 162 -----------------------------------------
 net/atm/atm_sysfs.c    |  25 -------
 net/atm/common.c       |   1 -
 net/atm/ioctl.c        |  12 ---
 net/atm/resources.c    |  53 +-------------
 net/atm/svc.c          |   1 -
 9 files changed, 2 insertions(+), 284 deletions(-)
 delete mode 100644 net/atm/addr.h
 delete mode 100644 net/atm/addr.c

diff --git a/net/atm/Makefile b/net/atm/Makefile
index 484a1b1552cc..5ed48d50df35 100644
--- a/net/atm/Makefile
+++ b/net/atm/Makefile
@@ -3,7 +3,7 @@
 # Makefile for the ATM Protocol Families.
 #
 
-atm-y		:= addr.o pvc.o signaling.o svc.o ioctl.o common.o atm_misc.o raw.o resources.o atm_sysfs.o
+atm-y		:= pvc.o signaling.o svc.o ioctl.o common.o atm_misc.o raw.o resources.o atm_sysfs.o
 
 obj-$(CONFIG_ATM) += atm.o
 obj-$(CONFIG_ATM_BR2684) += br2684.o
diff --git a/include/linux/atmdev.h b/include/linux/atmdev.h
index 71c5bf6950e3..7abbd23fada6 100644
--- a/include/linux/atmdev.h
+++ b/include/linux/atmdev.h
@@ -136,13 +136,6 @@ static inline struct sock *sk_atm(struct atm_vcc *vcc)
 	return (struct sock *)vcc;
 }
 
-struct atm_dev_addr {
-	struct sockaddr_atmsvc addr;	/* ATM address */
-	struct list_head entry;		/* next address */
-};
-
-enum atm_addr_type_t { ATM_ADDR_LOCAL, ATM_ADDR_LECS };
-
 struct atm_dev {
 	const struct atmdev_ops *ops;	/* device operations; NULL if unused */
 	const struct atmphy_ops *phy;	/* PHY operations, may be undefined */
@@ -152,8 +145,6 @@ struct atm_dev {
 	void		*dev_data;	/* per-device data */
 	void		*phy_data;	/* private PHY data */
 	unsigned long	flags;		/* device flags (ATM_DF_*) */
-	struct list_head local;		/* local ATM addresses */
-	struct list_head lecs;		/* LECS ATM addresses learned via ILMI */
 	unsigned char	esi[ESI_LEN];	/* ESI ("MAC" addr) */
 	struct atm_cirange ci_range;	/* VPI/VCI range */
 	struct k_atm_dev_stats stats;	/* statistics */
diff --git a/net/atm/addr.h b/net/atm/addr.h
deleted file mode 100644
index da3f848411a0..000000000000
--- a/net/atm/addr.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* net/atm/addr.h - Local ATM address registry */
-
-/* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */
-
-
-#ifndef NET_ATM_ADDR_H
-#define NET_ATM_ADDR_H
-
-#include <linux/atm.h>
-#include <linux/atmdev.h>
-
-void atm_reset_addr(struct atm_dev *dev, enum atm_addr_type_t type);
-int atm_add_addr(struct atm_dev *dev, const struct sockaddr_atmsvc *addr,
-		 enum atm_addr_type_t type);
-int atm_del_addr(struct atm_dev *dev, const struct sockaddr_atmsvc *addr,
-		 enum atm_addr_type_t type);
-int atm_get_addr(struct atm_dev *dev, struct sockaddr_atmsvc __user *buf,
-		 size_t size, enum atm_addr_type_t type);
-
-#endif
diff --git a/net/atm/addr.c b/net/atm/addr.c
deleted file mode 100644
index 938f360ae230..000000000000
--- a/net/atm/addr.c
+++ /dev/null
@@ -1,162 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* net/atm/addr.c - Local ATM address registry */
-
-/* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */
-
-#include <linux/atm.h>
-#include <linux/atmdev.h>
-#include <linux/slab.h>
-#include <linux/uaccess.h>
-
-#include "signaling.h"
-#include "addr.h"
-
-static int check_addr(const struct sockaddr_atmsvc *addr)
-{
-	int i;
-
-	if (addr->sas_family != AF_ATMSVC)
-		return -EAFNOSUPPORT;
-	if (!*addr->sas_addr.pub)
-		return *addr->sas_addr.prv ? 0 : -EINVAL;
-	for (i = 1; i < ATM_E164_LEN + 1; i++)	/* make sure it's \0-terminated */
-		if (!addr->sas_addr.pub[i])
-			return 0;
-	return -EINVAL;
-}
-
-static int identical(const struct sockaddr_atmsvc *a, const struct sockaddr_atmsvc *b)
-{
-	if (*a->sas_addr.prv)
-		if (memcmp(a->sas_addr.prv, b->sas_addr.prv, ATM_ESA_LEN))
-			return 0;
-	if (!*a->sas_addr.pub)
-		return !*b->sas_addr.pub;
-	if (!*b->sas_addr.pub)
-		return 0;
-	return !strcmp(a->sas_addr.pub, b->sas_addr.pub);
-}
-
-static void notify_sigd(const struct atm_dev *dev)
-{
-	struct sockaddr_atmpvc pvc;
-
-	pvc.sap_addr.itf = dev->number;
-	sigd_enq(NULL, as_itf_notify, NULL, &pvc, NULL);
-}
-
-void atm_reset_addr(struct atm_dev *dev, enum atm_addr_type_t atype)
-{
-	unsigned long flags;
-	struct atm_dev_addr *this, *p;
-	struct list_head *head;
-
-	spin_lock_irqsave(&dev->lock, flags);
-	if (atype == ATM_ADDR_LECS)
-		head = &dev->lecs;
-	else
-		head = &dev->local;
-	list_for_each_entry_safe(this, p, head, entry) {
-		list_del(&this->entry);
-		kfree(this);
-	}
-	spin_unlock_irqrestore(&dev->lock, flags);
-	if (head == &dev->local)
-		notify_sigd(dev);
-}
-
-int atm_add_addr(struct atm_dev *dev, const struct sockaddr_atmsvc *addr,
-		 enum atm_addr_type_t atype)
-{
-	unsigned long flags;
-	struct atm_dev_addr *this;
-	struct list_head *head;
-	int error;
-
-	error = check_addr(addr);
-	if (error)
-		return error;
-	spin_lock_irqsave(&dev->lock, flags);
-	if (atype == ATM_ADDR_LECS)
-		head = &dev->lecs;
-	else
-		head = &dev->local;
-	list_for_each_entry(this, head, entry) {
-		if (identical(&this->addr, addr)) {
-			spin_unlock_irqrestore(&dev->lock, flags);
-			return -EEXIST;
-		}
-	}
-	this = kmalloc_obj(struct atm_dev_addr, GFP_ATOMIC);
-	if (!this) {
-		spin_unlock_irqrestore(&dev->lock, flags);
-		return -ENOMEM;
-	}
-	this->addr = *addr;
-	list_add(&this->entry, head);
-	spin_unlock_irqrestore(&dev->lock, flags);
-	if (head == &dev->local)
-		notify_sigd(dev);
-	return 0;
-}
-
-int atm_del_addr(struct atm_dev *dev, const struct sockaddr_atmsvc *addr,
-		 enum atm_addr_type_t atype)
-{
-	unsigned long flags;
-	struct atm_dev_addr *this;
-	struct list_head *head;
-	int error;
-
-	error = check_addr(addr);
-	if (error)
-		return error;
-	spin_lock_irqsave(&dev->lock, flags);
-	if (atype == ATM_ADDR_LECS)
-		head = &dev->lecs;
-	else
-		head = &dev->local;
-	list_for_each_entry(this, head, entry) {
-		if (identical(&this->addr, addr)) {
-			list_del(&this->entry);
-			spin_unlock_irqrestore(&dev->lock, flags);
-			kfree(this);
-			if (head == &dev->local)
-				notify_sigd(dev);
-			return 0;
-		}
-	}
-	spin_unlock_irqrestore(&dev->lock, flags);
-	return -ENOENT;
-}
-
-int atm_get_addr(struct atm_dev *dev, struct sockaddr_atmsvc __user * buf,
-		 size_t size, enum atm_addr_type_t atype)
-{
-	unsigned long flags;
-	struct atm_dev_addr *this;
-	struct list_head *head;
-	int total = 0, error;
-	struct sockaddr_atmsvc *tmp_buf, *tmp_bufp;
-
-	spin_lock_irqsave(&dev->lock, flags);
-	if (atype == ATM_ADDR_LECS)
-		head = &dev->lecs;
-	else
-		head = &dev->local;
-	list_for_each_entry(this, head, entry)
-	    total += sizeof(struct sockaddr_atmsvc);
-	tmp_buf = tmp_bufp = kmalloc(total, GFP_ATOMIC);
-	if (!tmp_buf) {
-		spin_unlock_irqrestore(&dev->lock, flags);
-		return -ENOMEM;
-	}
-	list_for_each_entry(this, head, entry)
-	    memcpy(tmp_bufp++, &this->addr, sizeof(struct sockaddr_atmsvc));
-	spin_unlock_irqrestore(&dev->lock, flags);
-	error = total > size ? -E2BIG : total;
-	if (copy_to_user(buf, tmp_buf, total < size ? total : size))
-		error = -EFAULT;
-	kfree(tmp_buf);
-	return error;
-}
diff --git a/net/atm/atm_sysfs.c b/net/atm/atm_sysfs.c
index 54e7fb1a4ee5..0676a9c333ff 100644
--- a/net/atm/atm_sysfs.c
+++ b/net/atm/atm_sysfs.c
@@ -27,29 +27,6 @@ static ssize_t address_show(struct device *cdev,
 	return scnprintf(buf, PAGE_SIZE, "%pM\n", adev->esi);
 }
 
-static ssize_t atmaddress_show(struct device *cdev,
-			       struct device_attribute *attr, char *buf)
-{
-	unsigned long flags;
-	struct atm_dev *adev = to_atm_dev(cdev);
-	struct atm_dev_addr *aaddr;
-	int count = 0;
-
-	spin_lock_irqsave(&adev->lock, flags);
-	list_for_each_entry(aaddr, &adev->local, entry) {
-		count += scnprintf(buf + count, PAGE_SIZE - count,
-				   "%1phN.%2phN.%10phN.%6phN.%1phN\n",
-				   &aaddr->addr.sas_addr.prv[0],
-				   &aaddr->addr.sas_addr.prv[1],
-				   &aaddr->addr.sas_addr.prv[3],
-				   &aaddr->addr.sas_addr.prv[13],
-				   &aaddr->addr.sas_addr.prv[19]);
-	}
-	spin_unlock_irqrestore(&adev->lock, flags);
-
-	return count;
-}
-
 static ssize_t atmindex_show(struct device *cdev,
 			     struct device_attribute *attr, char *buf)
 {
@@ -91,14 +68,12 @@ static ssize_t link_rate_show(struct device *cdev,
 }
 
 static DEVICE_ATTR_RO(address);
-static DEVICE_ATTR_RO(atmaddress);
 static DEVICE_ATTR_RO(atmindex);
 static DEVICE_ATTR_RO(carrier);
 static DEVICE_ATTR_RO(type);
 static DEVICE_ATTR_RO(link_rate);
 
 static struct device_attribute *atm_attrs[] = {
-	&dev_attr_atmaddress,
 	&dev_attr_address,
 	&dev_attr_atmindex,
 	&dev_attr_carrier,
diff --git a/net/atm/common.c b/net/atm/common.c
index c6e87fc9bbfc..7d5b7c39b80b 100644
--- a/net/atm/common.c
+++ b/net/atm/common.c
@@ -30,7 +30,6 @@
 #include "resources.h"		/* atm_find_dev */
 #include "common.h"		/* prototypes */
 #include "protocols.h"		/* atm_init_<transport> */
-#include "addr.h"		/* address registry */
 #include "signaling.h"		/* for WAITING and sigd_attach */
 
 struct hlist_head vcc_hash[VCC_HTABLE_SIZE];
diff --git a/net/atm/ioctl.c b/net/atm/ioctl.c
index 4f2d185bf2f0..97f20cd051ed 100644
--- a/net/atm/ioctl.c
+++ b/net/atm/ioctl.c
@@ -220,10 +220,6 @@ int vcc_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
 #define ATM_GETNAMES32    _IOW('a', ATMIOC_ITF+3, struct compat_atm_iobuf)
 #define ATM_GETTYPE32     _IOW('a', ATMIOC_ITF+4, struct compat_atmif_sioc)
 #define ATM_GETESI32	  _IOW('a', ATMIOC_ITF+5, struct compat_atmif_sioc)
-#define ATM_GETADDR32	  _IOW('a', ATMIOC_ITF+6, struct compat_atmif_sioc)
-#define ATM_RSTADDR32	  _IOW('a', ATMIOC_ITF+7, struct compat_atmif_sioc)
-#define ATM_ADDADDR32	  _IOW('a', ATMIOC_ITF+8, struct compat_atmif_sioc)
-#define ATM_DELADDR32	  _IOW('a', ATMIOC_ITF+9, struct compat_atmif_sioc)
 #define ATM_GETCIRANGE32  _IOW('a', ATMIOC_ITF+10, struct compat_atmif_sioc)
 #define ATM_SETCIRANGE32  _IOW('a', ATMIOC_ITF+11, struct compat_atmif_sioc)
 #define ATM_SETESI32      _IOW('a', ATMIOC_ITF+12, struct compat_atmif_sioc)
@@ -242,10 +238,6 @@ static struct {
 	{ ATM_GETNAMES32,    ATM_GETNAMES },
 	{ ATM_GETTYPE32,     ATM_GETTYPE },
 	{ ATM_GETESI32,	     ATM_GETESI },
-	{ ATM_GETADDR32,     ATM_GETADDR },
-	{ ATM_RSTADDR32,     ATM_RSTADDR },
-	{ ATM_ADDADDR32,     ATM_ADDADDR },
-	{ ATM_DELADDR32,     ATM_DELADDR },
 	{ ATM_GETCIRANGE32,  ATM_GETCIRANGE },
 	{ ATM_SETCIRANGE32,  ATM_SETCIRANGE },
 	{ ATM_SETESI32,	     ATM_SETESI },
@@ -305,10 +297,6 @@ static int do_atm_ioctl(struct socket *sock, unsigned int cmd32,
 	case ATM_GETLINKRATE:
 	case ATM_GETTYPE:
 	case ATM_GETESI:
-	case ATM_GETADDR:
-	case ATM_RSTADDR:
-	case ATM_ADDADDR:
-	case ATM_DELADDR:
 	case ATM_GETCIRANGE:
 	case ATM_SETCIRANGE:
 	case ATM_SETESI:
diff --git a/net/atm/resources.c b/net/atm/resources.c
index 7aac25e917b4..12aef5542263 100644
--- a/net/atm/resources.c
+++ b/net/atm/resources.c
@@ -25,7 +25,6 @@
 
 #include "common.h"
 #include "resources.h"
-#include "addr.h"
 
 
 LIST_HEAD(atm_devs);
@@ -42,8 +41,6 @@ static struct atm_dev *__alloc_atm_dev(const char *type)
 	dev->signal = ATM_PHY_SIG_UNKNOWN;
 	dev->link_rate = ATM_OC3_PCR;
 	spin_lock_init(&dev->lock);
-	INIT_LIST_HEAD(&dev->local);
-	INIT_LIST_HEAD(&dev->lecs);
 
 	return dev;
 }
@@ -227,11 +224,8 @@ int atm_getnames(void __user *buf, int __user *iobuf_len)
 int atm_dev_ioctl(unsigned int cmd, void __user *buf, int __user *sioc_len,
 		  int number, int compat)
 {
-	int error, len, size = 0;
 	struct atm_dev *dev;
-
-	if (get_user(len, sioc_len))
-		return -EFAULT;
+	int error, size = 0;
 
 	dev = try_then_request_module(atm_dev_lookup(number), "atm-device-%d",
 				      number);
@@ -306,51 +300,6 @@ int atm_dev_ioctl(unsigned int cmd, void __user *buf, int __user *sioc_len,
 			goto done;
 		}
 		break;
-	case ATM_RSTADDR:
-		if (!capable(CAP_NET_ADMIN)) {
-			error = -EPERM;
-			goto done;
-		}
-		atm_reset_addr(dev, ATM_ADDR_LOCAL);
-		break;
-	case ATM_ADDADDR:
-	case ATM_DELADDR:
-	case ATM_ADDLECSADDR:
-	case ATM_DELLECSADDR:
-	{
-		struct sockaddr_atmsvc addr;
-
-		if (!capable(CAP_NET_ADMIN)) {
-			error = -EPERM;
-			goto done;
-		}
-
-		if (copy_from_user(&addr, buf, sizeof(addr))) {
-			error = -EFAULT;
-			goto done;
-		}
-		if (cmd == ATM_ADDADDR || cmd == ATM_ADDLECSADDR)
-			error = atm_add_addr(dev, &addr,
-					     (cmd == ATM_ADDADDR ?
-					      ATM_ADDR_LOCAL : ATM_ADDR_LECS));
-		else
-			error = atm_del_addr(dev, &addr,
-					     (cmd == ATM_DELADDR ?
-					      ATM_ADDR_LOCAL : ATM_ADDR_LECS));
-		goto done;
-	}
-	case ATM_GETADDR:
-	case ATM_GETLECSADDR:
-		error = atm_get_addr(dev, buf, len,
-				     (cmd == ATM_GETADDR ?
-				      ATM_ADDR_LOCAL : ATM_ADDR_LECS));
-		if (error < 0)
-			goto done;
-		size = error;
-		/* may return 0, but later on size == 0 means "don't
-		   write the length" */
-		error = put_user(size, sioc_len) ? -EFAULT : 0;
-		goto done;
 	case ATM_SETLOOP:
 		if (__ATM_LM_XTRMT((int) (unsigned long) buf) &&
 		    __ATM_LM_XTLOC((int) (unsigned long) buf) >
diff --git a/net/atm/svc.c b/net/atm/svc.c
index 7c5559f50a99..270e95154a2b 100644
--- a/net/atm/svc.c
+++ b/net/atm/svc.c
@@ -27,7 +27,6 @@
 #include "resources.h"
 #include "common.h"		/* common for PVCs and SVCs */
 #include "signaling.h"
-#include "addr.h"
 
 #ifdef CONFIG_COMPAT
 /* It actually takes struct sockaddr_atmsvc, not struct atm_iobuf */
-- 
2.54.0


^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox