]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
ppp: consolidate refcount decrements
authorQingfang Deng <qingfang.deng@linux.dev>
Tue, 7 Apr 2026 09:40:56 +0000 (17:40 +0800)
committerJakub Kicinski <kuba@kernel.org>
Fri, 10 Apr 2026 03:03:48 +0000 (20:03 -0700)
ppp_destroy_{channel,interface} are always called after
refcount_dec_and_test().

To reduce boilerplate code, consolidate the decrements by moving them
into the two functions. To reflect this change in semantics, rename the
functions to ppp_release_*.

Signed-off-by: Qingfang Deng <qingfang.deng@linux.dev>
Link: https://patch.msgid.link/20260407094058.257246-1-qingfang.deng@linux.dev
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ppp/ppp_generic.c

index cb29a6968c6332263c58c52dcd0f9c02b5f396c9..b097d1b38ac9cba6bc9f3431d7f52e013c45f041 100644 (file)
@@ -286,12 +286,12 @@ static struct compressor *find_compressor(int type);
 static void ppp_get_stats(struct ppp *ppp, struct ppp_stats *st);
 static int ppp_create_interface(struct net *net, struct file *file, int *unit);
 static void init_ppp_file(struct ppp_file *pf, int kind);
-static void ppp_destroy_interface(struct ppp *ppp);
+static void ppp_release_interface(struct ppp *ppp);
 static struct ppp *ppp_find_unit(struct ppp_net *pn, int unit);
 static struct channel *ppp_find_channel(struct ppp_net *pn, int unit);
 static int ppp_connect_channel(struct channel *pch, int unit);
 static int ppp_disconnect_channel(struct channel *pch);
-static void ppp_destroy_channel(struct channel *pch);
+static void ppp_release_channel(struct channel *pch);
 static int unit_get(struct idr *p, void *ptr, int min);
 static int unit_set(struct idr *p, void *ptr, int n);
 static void unit_put(struct idr *p, int n);
@@ -407,22 +407,18 @@ static int ppp_release(struct inode *unused, struct file *file)
 
        if (pf) {
                file->private_data = NULL;
-               if (pf->kind == INTERFACE) {
+               switch (pf->kind) {
+               case INTERFACE:
                        ppp = PF_TO_PPP(pf);
                        rtnl_lock();
                        if (file == ppp->owner)
                                unregister_netdevice(ppp->dev);
                        rtnl_unlock();
-               }
-               if (refcount_dec_and_test(&pf->refcnt)) {
-                       switch (pf->kind) {
-                       case INTERFACE:
-                               ppp_destroy_interface(PF_TO_PPP(pf));
-                               break;
-                       case CHANNEL:
-                               ppp_destroy_channel(PF_TO_CHANNEL(pf));
-                               break;
-                       }
+                       ppp_release_interface(ppp);
+                       break;
+               case CHANNEL:
+                       ppp_release_channel(PF_TO_CHANNEL(pf));
+                       break;
                }
        }
        return 0;
@@ -675,8 +671,7 @@ err_unset:
        synchronize_rcu();
 
        if (pchb)
-               if (refcount_dec_and_test(&pchb->file.refcnt))
-                       ppp_destroy_channel(pchb);
+               ppp_release_channel(pchb);
 
        return -EALREADY;
 }
@@ -708,11 +703,9 @@ static int ppp_unbridge_channels(struct channel *pch)
        synchronize_rcu();
 
        if (pchbb == pch)
-               if (refcount_dec_and_test(&pch->file.refcnt))
-                       ppp_destroy_channel(pch);
+               ppp_release_channel(pch);
 
-       if (refcount_dec_and_test(&pchb->file.refcnt))
-               ppp_destroy_channel(pchb);
+       ppp_release_channel(pchb);
 
        return 0;
 }
@@ -786,8 +779,7 @@ static long ppp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
                                break;
                        err = ppp_bridge_channels(pch, pchb);
                        /* Drop earlier refcount now bridge establishment is complete */
-                       if (refcount_dec_and_test(&pchb->file.refcnt))
-                               ppp_destroy_channel(pchb);
+                       ppp_release_channel(pchb);
                        break;
 
                case PPPIOCUNBRIDGECHAN:
@@ -1584,8 +1576,7 @@ static void ppp_dev_priv_destructor(struct net_device *dev)
        struct ppp *ppp;
 
        ppp = netdev_priv(dev);
-       if (refcount_dec_and_test(&ppp->file.refcnt))
-               ppp_destroy_interface(ppp);
+       ppp_release_interface(ppp);
 }
 
 static int ppp_fill_forward_path(struct net_device_path_ctx *ctx,
@@ -3022,8 +3013,7 @@ ppp_unregister_channel(struct ppp_channel *chan)
        pch->file.dead = 1;
        wake_up_interruptible(&pch->file.rwait);
 
-       if (refcount_dec_and_test(&pch->file.refcnt))
-               ppp_destroy_channel(pch);
+       ppp_release_channel(pch);
 }
 
 /*
@@ -3404,12 +3394,14 @@ init_ppp_file(struct ppp_file *pf, int kind)
 }
 
 /*
- * Free the memory used by a ppp unit.  This is only called once
- * there are no channels connected to the unit and no file structs
- * that reference the unit.
+ * Drop a reference to a ppp unit and free its memory if the refcount reaches
+ * zero.
  */
-static void ppp_destroy_interface(struct ppp *ppp)
+static void ppp_release_interface(struct ppp *ppp)
 {
+       if (!refcount_dec_and_test(&ppp->file.refcnt))
+               return;
+
        atomic_dec(&ppp_unit_count);
 
        if (!ppp->file.dead || ppp->n_channels) {
@@ -3561,18 +3553,21 @@ ppp_disconnect_channel(struct channel *pch)
                        wake_up_interruptible(&ppp->file.rwait);
                ppp_unlock(ppp);
                synchronize_net();
-               if (refcount_dec_and_test(&ppp->file.refcnt))
-                       ppp_destroy_interface(ppp);
+               ppp_release_interface(ppp);
                err = 0;
        }
        return err;
 }
 
 /*
- * Free up the resources used by a ppp channel.
+ * Drop a reference to a ppp channel and free its memory if the refcount reaches
+ * zero.
  */
-static void ppp_destroy_channel(struct channel *pch)
+static void ppp_release_channel(struct channel *pch)
 {
+       if (!refcount_dec_and_test(&pch->file.refcnt))
+               return;
+
        put_net_track(pch->chan_net, &pch->ns_tracker);
        pch->chan_net = NULL;