From nobody Sat Feb 7 15:11:09 2026 Received: from mail-ej1-f47.google.com (mail-ej1-f47.google.com [209.85.218.47]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0976E18859B for ; Sat, 7 Feb 2026 06:47:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.47 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770446834; cv=none; b=cupIhbdbJi+GKpjMndHGsSw656ft97I3i65DbEzsPorsPhHa5UA4Kla7mFMy/SvcrX9sFufjJAw9cfi/Jhetaa0VDiRkFmU/eizJlp24AV5EZXGmMNus84rLrwTJDF21EWoJSLkP1jh9vGrPnV59S1Int5CVrs2g1api2ePEwbY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770446834; c=relaxed/simple; bh=2G6hV+wVZg6o//MYI5fkbIvZjfnqpl+ixHuzDnkOF/M=; h=From:To:Subject:Date:Message-ID:MIME-Version; b=jpUHHLFL3sdfsDyUl8q9azNaVkpVMqjZHWnNwFv+SBuPelop5iMCYnazkDTmBglXMeVAeDMed7olO2kEb/FrUa56bpkiIBqJDU+bVHZGFSASsoKOr8vKz7626guwYcuOCJI0zzRDT+XFXgqJ8/Fsn5Ic7YQAUY4T58fMLDJqXVM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=TpCgepgz; arc=none smtp.client-ip=209.85.218.47 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="TpCgepgz" Received: by mail-ej1-f47.google.com with SMTP id a640c23a62f3a-b88593aa4dcso387997766b.3 for ; Fri, 06 Feb 2026 22:47:13 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1770446832; x=1771051632; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:to :from:from:to:cc:subject:date:message-id:reply-to; bh=ttpBhaYPGwPNPTXRachj9WVFxsA4zzdO/ofWQNu6xMY=; b=TpCgepgzzb0Kb3Sp9fu7bumoSsPXZfw7xOlq4AZ7la0O7VMkl2ZIGgd7EZ0030J47N jCVLqTS8+2p/dFGIk5KILQU1cBfGwN2HzKbUAdPl68yPVGxUYl6rv2v4pWGkCx1q1jKp 2lqy6/1+MG1pUbRJB6dPsu1eQppor/cP5YR+bywoR5cCmFdVPojjNOtJAD37OMmHd0AM nFLjY1NGYMhb81Y0QLjBIalL9+Gdmba5g/GGDz9vLZl100EPMerUBpnObqwRSPdAmnX/ HWNncCW0n1RbAyYo9Jc1kM8jbvf0ubEmOxY0whxGJgUX+VIPrzu3RIP+9kRe6IAAi7s/ xzwg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1770446832; x=1771051632; h=content-transfer-encoding:mime-version:message-id:date:subject:to :from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=ttpBhaYPGwPNPTXRachj9WVFxsA4zzdO/ofWQNu6xMY=; b=q/2951J+OzYNAviVAg3I80UCIApuNqjbVNsNcvwFuKbh603pm1TUex2G6W7Ao/Kkje qgtYcAw5km6iXw+P4CAKPoBTC85cDglMRFqvLx1f50wqYUJySJ1Ru33y54rKr2tZw4ul Uum9wZy5ny8r3HaDU3DuIbDMq/vvAvhX9BUobExuWqfDfRgfBgiIow+VRRvK9O3K8di3 CywhAXaJ6GVaAjgptyTltwBBYC34u717C0aVvD2xZi8qawmze3ssprDDFDS0b1UqrESr QQVTswmKaPhaEgD0TAOYXfQUujqDJEoxBW/pzEViBGpdYJKxE8ThlRn9v5HgP2OzZSX5 MwrQ== X-Forwarded-Encrypted: i=1; AJvYcCU9tI0x4J3fNpZf1F3CX2+UrmPuf6mKOjkKtaRuBEo0igufbb4VG5/AUfMLwsehiaE0eRABLk9X3oCHVJw=@vger.kernel.org X-Gm-Message-State: AOJu0Yy8jKbqGRwsbuNt6JLO5F0iNc9QPRlfKOaX+Ah/Ux+s0dD1Gjiv xe99Y+X16YsqHu9xOgU1Vq/0sjdbjPV94lW2lHvh2B8d4bGRjZZeIsPC X-Gm-Gg: AZuq6aIzzrtrR3jpFs/tmTeMXFGGA7LpbLhNMeniBPJZJ0/Yc9lVFFqb/7f5DFuSEyT Zx56KfBXn22o36g6y4yrayqaA7GaZ/t+EChH+nLh74v+tBK9QVhcBC8UIGIwOjKpVVQxa2ODIWo QSSisHWnq+mvT+XK8FO4ej7XNDt97nfU5QZ5C2yVlEGevCFFYOg7yFE9hBMUUQ/XkRVAT2+fDZN ypCGNEo63kz9TLEPg4aa3vNsQpq7i+/n8idpGB1lSkjFljf3mRQ0bfRfvdbdrqMmrkBLFyPz0r4 eIzi4Ld4dcSKU37qbydSDV/0ZdWi3H8QmL3NWykuONI6IPS0yjZVFMgIcQ6t0KGNugbN1bUapeZ V2W/EF5ninVOpkv/FWx1ZRr3bL7ZNQa66JXo3h8+oyKJ2Y7Nkf6bxcJUUAiIbAwLyXqHcybg= X-Received: by 2002:a17:907:2d8e:b0:b88:5bd7:63b3 with SMTP id a640c23a62f3a-b8edf1a9b51mr279203966b.19.1770446832197; Fri, 06 Feb 2026 22:47:12 -0800 (PST) Received: from gmail.com ([2a09:bac1:5500::3e3:36]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-b8eda7e6577sm145405466b.30.2026.02.06.22.47.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 06 Feb 2026 22:47:10 -0800 (PST) From: Qingfang Deng To: Andrew Lunn , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , linux-ppp@vger.kernel.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH net-next] ppp: don't byte-swap at run time Date: Sat, 7 Feb 2026 14:47:04 +0800 Message-ID: <20260207064705.208612-1-dqfext@gmail.com> X-Mailer: git-send-email 2.43.0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Currently, the code loads the protocol number from a skb and converts it to host-endian for comparison. This requires runtime byte swapping on little-endian architectures. Optimize this by comparing the protocol number directly to constant-folded big-endian values. This reduces code size, and slightly improves performance in the fastpath. ppp_ioctl() still takes a host-endian int, so keep the old function for it. bloat-o-meter analysis on a x86_64 build: add/remove: 0/0 grow/shrink: 0/6 up/down: 0/-131 (-131) Function old new delta ppp_receive_nonmp_frame 2002 2000 -2 ppp_input 641 639 -2 npindex_to_proto 24 12 -12 npindex_to_ethertype 24 12 -12 ppp_start_xmit 375 344 -31 __ppp_xmit_process 1881 1809 -72 Total: Before=3D22998, After=3D22867, chg -0.57% Signed-off-by: Qingfang Deng --- drivers/net/ppp/ppp_generic.c | 109 ++++++++++++++++++++-------------- 1 file changed, 65 insertions(+), 44 deletions(-) diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c index f8814d7be6f1..eca9cd6f3a87 100644 --- a/drivers/net/ppp/ppp_generic.c +++ b/drivers/net/ppp/ppp_generic.c @@ -239,7 +239,7 @@ struct ppp_net { }; =20 /* Get the PPP protocol number from a skb */ -#define PPP_PROTO(skb) get_unaligned_be16((skb)->data) +#define PPP_PROTO(skb) get_unaligned((__be16 *)(skb)->data) =20 /* We limit the length of ppp->file.rq to this (arbitrary) value */ #define PPP_MAX_RQLEN 32 @@ -312,7 +312,26 @@ static inline struct ppp_net *ppp_pernet(struct net *n= et) } =20 /* Translates a PPP protocol number to a NP index (NP =3D=3D network proto= col) */ -static inline int proto_to_npindex(int proto) +static __always_inline int proto_to_npindex(__be16 proto) +{ + switch (proto) { + case htons(PPP_IP): + return NP_IP; + case htons(PPP_IPV6): + return NP_IPV6; + case htons(PPP_IPX): + return NP_IPX; + case htons(PPP_AT): + return NP_AT; + case htons(PPP_MPLS_UC): + return NP_MPLS_UC; + case htons(PPP_MPLS_MC): + return NP_MPLS_MC; + } + return -EINVAL; +} + +static __always_inline int proto_to_npindex_user(int proto) { switch (proto) { case PPP_IP: @@ -332,44 +351,44 @@ static inline int proto_to_npindex(int proto) } =20 /* Translates an NP index into a PPP protocol number */ -static const int npindex_to_proto[NUM_NP] =3D { - PPP_IP, - PPP_IPV6, - PPP_IPX, - PPP_AT, - PPP_MPLS_UC, - PPP_MPLS_MC, +static const __be16 npindex_to_proto[NUM_NP] =3D { + htons(PPP_IP), + htons(PPP_IPV6), + htons(PPP_IPX), + htons(PPP_AT), + htons(PPP_MPLS_UC), + htons(PPP_MPLS_MC), }; =20 /* Translates an ethertype into an NP index */ -static inline int ethertype_to_npindex(int ethertype) +static inline int ethertype_to_npindex(__be16 ethertype) { switch (ethertype) { - case ETH_P_IP: + case htons(ETH_P_IP): return NP_IP; - case ETH_P_IPV6: + case htons(ETH_P_IPV6): return NP_IPV6; - case ETH_P_IPX: + case htons(ETH_P_IPX): return NP_IPX; - case ETH_P_PPPTALK: - case ETH_P_ATALK: + case htons(ETH_P_PPPTALK): + case htons(ETH_P_ATALK): return NP_AT; - case ETH_P_MPLS_UC: + case htons(ETH_P_MPLS_UC): return NP_MPLS_UC; - case ETH_P_MPLS_MC: + case htons(ETH_P_MPLS_MC): return NP_MPLS_MC; } return -1; } =20 /* Translates an NP index into an ethertype */ -static const int npindex_to_ethertype[NUM_NP] =3D { - ETH_P_IP, - ETH_P_IPV6, - ETH_P_IPX, - ETH_P_PPPTALK, - ETH_P_MPLS_UC, - ETH_P_MPLS_MC, +static const __be16 npindex_to_ethertype[NUM_NP] =3D { + htons(ETH_P_IP), + htons(ETH_P_IPV6), + htons(ETH_P_IPX), + htons(ETH_P_PPPTALK), + htons(ETH_P_MPLS_UC), + htons(ETH_P_MPLS_MC), }; =20 /* @@ -504,7 +523,7 @@ static bool ppp_check_packet(struct sk_buff *skb, size_= t count) /* LCP packets must include LCP header which 4 bytes long: * 1-byte code, 1-byte identifier, and 2-byte length. */ - return get_unaligned_be16(skb->data) !=3D PPP_LCP || + return PPP_PROTO(skb) !=3D htons(PPP_LCP) || count >=3D PPP_PROTO_LEN + PPP_LCP_HDRLEN; } =20 @@ -914,7 +933,7 @@ static long ppp_ioctl(struct file *file, unsigned int c= md, unsigned long arg) case PPPIOCSNPMODE: if (copy_from_user(&npi, argp, sizeof(npi))) break; - err =3D proto_to_npindex(npi.protocol); + err =3D proto_to_npindex_user(npi.protocol); if (err < 0) break; i =3D err; @@ -1451,10 +1470,10 @@ static netdev_tx_t ppp_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct ppp *ppp =3D netdev_priv(dev); - int npi, proto; - unsigned char *pp; + __be16 *pp, proto; + int npi; =20 - npi =3D ethertype_to_npindex(ntohs(skb->protocol)); + npi =3D ethertype_to_npindex(skb->protocol); if (npi < 0) goto outf; =20 @@ -1478,7 +1497,7 @@ ppp_start_xmit(struct sk_buff *skb, struct net_device= *dev) =20 pp =3D skb_push(skb, 2); proto =3D npindex_to_proto[npi]; - put_unaligned_be16(proto, pp); + put_unaligned(proto, pp); =20 skb_scrub_packet(skb, !net_eq(ppp->ppp_net, dev_net(dev))); ppp_xmit_process(ppp, skb); @@ -1764,14 +1783,14 @@ pad_compress_skb(struct ppp *ppp, struct sk_buff *s= kb) static void ppp_send_frame(struct ppp *ppp, struct sk_buff *skb) { - int proto =3D PPP_PROTO(skb); + __be16 proto =3D PPP_PROTO(skb); struct sk_buff *new_skb; int len; unsigned char *cp; =20 skb->dev =3D ppp->dev; =20 - if (proto < 0x8000) { + if (!(proto & htons(0x8000))) { #ifdef CONFIG_PPP_FILTER /* check if the packet passes the pass and active filters. * See comment for PPP_FILTER_OUTBOUND_TAG above. @@ -2324,7 +2343,7 @@ ppp_input(struct ppp_channel *chan, struct sk_buff *s= kb) { struct channel *pch =3D chan->ppp; struct ppp *ppp; - int proto; + __be16 proto; =20 if (!pch) { kfree_skb(skb); @@ -2347,7 +2366,8 @@ ppp_input(struct ppp_channel *chan, struct sk_buff *s= kb) } =20 proto =3D PPP_PROTO(skb); - if (!ppp || proto >=3D 0xc000 || proto =3D=3D PPP_CCPFRAG) { + if (!ppp || (proto & htons(0xc000)) =3D=3D htons(0xc000) || + proto =3D=3D htons(PPP_CCPFRAG)) { /* put it on the channel queue */ skb_queue_tail(&pch->file.rq, skb); /* drop old frames if queue too long */ @@ -2399,7 +2419,7 @@ ppp_receive_frame(struct ppp *ppp, struct sk_buff *sk= b, struct channel *pch) skb_checksum_complete_unset(skb); #ifdef CONFIG_PPP_MULTILINK /* XXX do channel-level decompression here */ - if (PPP_PROTO(skb) =3D=3D PPP_MP) + if (PPP_PROTO(skb) =3D=3D htons(PPP_MP)) ppp_receive_mp_frame(ppp, skb, pch); else #endif /* CONFIG_PPP_MULTILINK */ @@ -2422,7 +2442,8 @@ static void ppp_receive_nonmp_frame(struct ppp *ppp, struct sk_buff *skb) { struct sk_buff *ns; - int proto, len, npi; + int len, npi; + __be16 proto; =20 /* * Decompress the frame, if compressed. @@ -2441,7 +2462,7 @@ ppp_receive_nonmp_frame(struct ppp *ppp, struct sk_bu= ff *skb) */ proto =3D PPP_PROTO(skb); switch (proto) { - case PPP_VJC_COMP: + case htons(PPP_VJC_COMP): /* decompress VJ compressed packets */ if (!ppp->vj || (ppp->flags & SC_REJ_COMP_TCP)) goto err; @@ -2473,10 +2494,10 @@ ppp_receive_nonmp_frame(struct ppp *ppp, struct sk_= buff *skb) skb_put(skb, len - skb->len); else if (len < skb->len) skb_trim(skb, len); - proto =3D PPP_IP; + proto =3D htons(PPP_IP); break; =20 - case PPP_VJC_UNCOMP: + case htons(PPP_VJC_UNCOMP): if (!ppp->vj || (ppp->flags & SC_REJ_COMP_TCP)) goto err; =20 @@ -2490,10 +2511,10 @@ ppp_receive_nonmp_frame(struct ppp *ppp, struct sk_= buff *skb) netdev_err(ppp->dev, "PPP: VJ uncompressed error\n"); goto err; } - proto =3D PPP_IP; + proto =3D htons(PPP_IP); break; =20 - case PPP_CCP: + case htons(PPP_CCP): ppp_ccp_peek(ppp, skb, 1); break; } @@ -2546,7 +2567,7 @@ ppp_receive_nonmp_frame(struct ppp *ppp, struct sk_bu= ff *skb) /* chop off protocol */ skb_pull_rcsum(skb, 2); skb->dev =3D ppp->dev; - skb->protocol =3D htons(npindex_to_ethertype[npi]); + skb->protocol =3D npindex_to_ethertype[npi]; skb_reset_mac_header(skb); skb_scrub_packet(skb, !net_eq(ppp->ppp_net, dev_net(ppp->dev))); @@ -2563,7 +2584,7 @@ ppp_receive_nonmp_frame(struct ppp *ppp, struct sk_bu= ff *skb) static struct sk_buff * ppp_decompress_frame(struct ppp *ppp, struct sk_buff *skb) { - int proto =3D PPP_PROTO(skb); + __be16 proto =3D PPP_PROTO(skb); struct sk_buff *ns; int len; =20 @@ -2573,7 +2594,7 @@ ppp_decompress_frame(struct ppp *ppp, struct sk_buff = *skb) if (!pskb_may_pull(skb, skb->len)) goto err; =20 - if (proto =3D=3D PPP_COMP) { + if (proto =3D=3D htons(PPP_COMP)) { int obuff_size; =20 switch(ppp->rcomp->compress_proto) { --=20 2.43.0