diff options
author | Jean-Marc Lenoir | 2022-11-19 18:52:56 +0100 |
---|---|---|
committer | Jean-Marc Lenoir | 2022-11-19 18:52:56 +0100 |
commit | 34bac73728073542c1178731f7e7e6b5bc9b6bef (patch) | |
tree | ec9aa610ddeb7c1a43a6c229a87f81207859394d | |
parent | 072b4ea4c99c0b4ae87961ac9316b2a7e439d84c (diff) | |
download | aur-34bac73728073542c1178731f7e7e6b5bc9b6bef.tar.gz |
Sync with vmware-workstation 17.0.0
-rw-r--r-- | .SRCINFO | 6 | ||||
-rw-r--r-- | PKGBUILD | 6 | ||||
-rw-r--r-- | vmmon.patch | 36 | ||||
-rw-r--r-- | vmnet.patch | 395 |
4 files changed, 145 insertions, 298 deletions
@@ -1,7 +1,7 @@ pkgbase = vmware-workstation11 pkgdesc = The industry standard for running multiple operating systems as virtual machines on a single Linux PC. pkgver = 11.1.4 - pkgrel = 21 + pkgrel = 22 url = https://www.vmware.com/products/workstation-for-linux.html install = vmware-workstation.install arch = x86_64 @@ -84,7 +84,7 @@ pkgbase = vmware-workstation11 sha256sums = fe1b1be8297f4170406f97dd1f8b385d911faf45afe19cbc0c26b8092b3ddf8d sha256sums = 10562d11d50edab9abc2b29c8948714edcb9b084f99b3766d07ddd21259e372e sha256sums = 273d4357599a3e54259c78cc49054fef8ecfd2c2eda35cbcde3a53a62777a5ac - sha256sums = ed12d146cf6ddf53510c8ea4fb59c2c038a316c38daaf334138bad6cedb26bef - sha256sums = 684944d16b79eca6f4017a30d9b5b6dc7cb746897914e90bf3483b1635aaeb1e + sha256sums = 1e9f151b97b19661f4d4fb4276bc252087047bf557f87ceacb374811d612b436 + sha256sums = fc2538eec6e688932e55eaccf82a55e276d867566e8380c8825253003b768c7b pkgname = vmware-workstation11 @@ -16,7 +16,7 @@ pkgname=vmware-workstation11 pkgver=11.1.4 _buildver=3848939 _pkgver=${pkgver}_${_buildver} -pkgrel=21 +pkgrel=22 pkgdesc='The industry standard for running multiple operating systems as virtual machines on a single Linux PC.' arch=(x86_64) url='https://www.vmware.com/products/workstation-for-linux.html' @@ -121,8 +121,8 @@ sha256sums=( '10562d11d50edab9abc2b29c8948714edcb9b084f99b3766d07ddd21259e372e' '273d4357599a3e54259c78cc49054fef8ecfd2c2eda35cbcde3a53a62777a5ac' - 'ed12d146cf6ddf53510c8ea4fb59c2c038a316c38daaf334138bad6cedb26bef' - '684944d16b79eca6f4017a30d9b5b6dc7cb746897914e90bf3483b1635aaeb1e' + '1e9f151b97b19661f4d4fb4276bc252087047bf557f87ceacb374811d612b436' + 'fc2538eec6e688932e55eaccf82a55e276d867566e8380c8825253003b768c7b' ) options=(!strip emptydirs) diff --git a/vmmon.patch b/vmmon.patch index 13fba9829e7a..08806a4eec67 100644 --- a/vmmon.patch +++ b/vmmon.patch @@ -1462,7 +1462,7 @@ ret = vPgAddr | (((VA)p) & (PAGE_SIZE - 1)); -@@ -2273,16 +2372,22 @@ HostIF_VMLockIsHeld(VMDriver *vm) // IN +@@ -2273,16 +2372,26 @@ HostIF_VMLockIsHeld(VMDriver *vm) // IN static Bool isVAReadable(VA r) // IN: { @@ -1470,7 +1470,11 @@ uint32 dummy; int ret; -+#ifdef HAVE_GET_KERNEL_NOFAULT ++#if defined(HAVE_GET_KERNEL_NOFAULT) || LINUX_VERSION_CODE >= KERNEL_VERSION(5, 17, 0) ++ /* ++ * Exists from 5.10, first indicated by HAVE_GET_KERNEL_NOFAULT, ++ * and from post-5.17 just existing everywhere. ++ */ + ret = get_kernel_nofault(dummy, (void *)r); +#else + { @@ -1859,31 +1863,3 @@ break; } -From 16d490ae022d7fc4ca867971e20e2dcd59e6ca5a Mon Sep 17 00:00:00 2001 -From: Michal Kubecek <mkubecek@suse.cz> -Date: Mon, 4 Apr 2022 01:57:28 +0200 -Subject: [PATCH] vmmon: do not rely on HAVE_GET_KERNEL_NOFAULT - -Mainline commit 34737e269803 ("uaccess: add generic -__{get,put}_kernel_nofault") in 5.18-rc1 removes HAVE_GET_KERNEL_NOFAULT -macro as all architectures can use get_kernel_nofault() now. Check for -existence of __get_kernel_nofault() instead and add also a version check in -case it stops being a macro or is removed in the future. ---- - vmmon-only/linux/hostif.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/vmmon-only/linux/hostif.c b/vmmon-only/linux/hostif.c -index a21c300..b6326e9 100644 ---- a/vmmon-only/linux/hostif.c -+++ b/vmmon-only/linux/hostif.c -@@ -2382,7 +2382,8 @@ isVAReadable(VA r) // IN: - uint32 dummy; - int ret; - --#ifdef HAVE_GET_KERNEL_NOFAULT -+#if defined(HAVE_GET_KERNEL_NOFAULT) || defined(__get_kernel_nofault) || \ -+ (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 18, 0)) - ret = get_kernel_nofault(dummy, (void *)r); - #else - { diff --git a/vmnet.patch b/vmnet.patch index e313a4370afb..eed7b499fe13 100644 --- a/vmnet.patch +++ b/vmnet.patch @@ -55,9 +55,23 @@ clone->dev = dev; clone->protocol = eth_type_trans(clone, dev); -@@ -696,7 +696,7 @@ VNetBridgeReceiveFromVNet(VNetJack - - netif_rx_ni(clone); +@@ -687,16 +687,13 @@ + } + spin_unlock_irqrestore(&bridge->historyLock, flags); + +- /* +- * We used to cli() before calling netif_rx() here. It was probably +- * unneeded (as we never did it in netif.c, and the code worked). In +- * any case, now that we are using netif_rx_ni(), we should certainly +- * not do it, or netif_rx_ni() will deadlock on the cli() lock --hpreg +- */ +- +- netif_rx_ni(clone); ++#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 18, 0) ++ netif_rx_ni(clone); ++#else ++ netif_rx(clone); ++#endif # if LOGLEVEL >= 4 - do_gettimeofday(&vnetTime); + vnetTime = ktime_get_ns(); @@ -125,6 +139,30 @@ dev = alloc_netdev(sizeof *netIf, deviceName, NET_NAME_USER, VNetNetIfSetup); #else dev = alloc_netdev(sizeof *netIf, deviceName, VNetNetIfSetup); +@@ -219,7 +219,11 @@ + + memset(&netIf->stats, 0, sizeof netIf->stats); + ++#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0) + memcpy(dev->dev_addr, netIf->port.paddr, sizeof netIf->port.paddr); ++#else ++ eth_hw_addr_set(dev, netIf->port.paddr); ++#endif + + if (register_netdev(dev) != 0) { + LOG(0, (KERN_NOTICE "%s: could not register network device\n", +@@ -311,7 +315,11 @@ + /* send to the host interface */ + skb->dev = netIf->dev; + skb->protocol = eth_type_trans(skb, netIf->dev); ++#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 18, 0) + netif_rx_ni(skb); ++#else ++ netif_rx(skb); ++#endif + netIf->stats.rx_packets++; + + return; @@ -465,7 +465,7 @@ VNetNetifStartXmit(struct sk_buff *sk VNetSend(&netIf->port.jack, skb); @@ -134,6 +172,19 @@ return 0; } +@@ -498,7 +506,11 @@ + return -EINVAL; + } + memcpy(netIf->port.paddr, addr->sa_data, dev->addr_len); +- memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); ++#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0) ++ memcpy(dev->dev_addr, netIf->port.paddr, dev->addr_len); ++#else ++ eth_hw_addr_set(dev, netIf->port.paddr); ++#endif + return 0; + } + --- a/vmnet/procfs.c +++ a/vmnet/procfs.c @@ -137,6 +137,7 @@ VNetProcShow(struct seq_file *p, // IN: @@ -165,6 +216,28 @@ } if (ent->pde != NULL) { *ret = ent; +--- a/vmnet/smac.c ++++ b/vmnet/smac.c +@@ -4115,7 +4115,7 @@ + + void SMACINT + SMAC_SetMac(SMACState *state, // IN: state to update +- uint8 *mac) // IN: pointer to host adapter's MAC ++ const uint8 *mac) // IN: pointer to host adapter's MAC + { + VNETKdPrintCall(("SMAC_SetMac")); + ASSERT(state); +--- a/vmnet/smac.h ++++ b/vmnet/smac.h +@@ -72,7 +72,7 @@ + void SMACINT + SMAC_InitState(struct SMACState **ptr); // IN: state to alloc/init + void SMACINT +-SMAC_SetMac(struct SMACState *state, uint8 *mac); // IN: state, and host MAC ++SMAC_SetMac(struct SMACState *state, const uint8 *mac); // IN: state, and host MAC + void SMACINT + SMAC_CleanupState(struct SMACState **ptr); // IN: state to cleanup/dealloc + --- a/vmnet/userif.c +++ b/vmnet/userif.c @@ -36,6 +36,9 @@ @@ -259,20 +332,67 @@ &recvClusterPage, &recvClusterCount)) < 0) { goto error_free; -@@ -576,7 +581,12 @@ VNetCsumCopyDatagram(const struct sk_buf - return -EINVAL; - } - +@@ -537,6 +542,50 @@ + /* + *---------------------------------------------------------------------- + * ++ * VNetCsumAndCopyToUser -- ++ * ++ * Checksum data and copy them to userspace. ++ * ++ * Results: ++ * folded checksum (non-zero value) on success, ++ * err set to 0 on success, negative errno on failure. ++ * ++ * Side effects: ++ * Data copied to the buffer. ++ * ++ *---------------------------------------------------------------------- ++ */ ++ ++static unsigned int ++VNetCsumAndCopyToUser(const void *src, // IN: Source ++ void *dst, // IN: Destination ++ int len, // IN: Bytes to copy ++ int *err) // OUT: Error code ++{ ++ unsigned int csum; ++ +#if COMPAT_LINUX_VERSION_CHECK_LT(5, 10, 0) - csum = csum_and_copy_to_user(skb->data + offset, curr, len, 0, &err); ++ csum = csum_and_copy_to_user(src, dst, len, 0, err); ++#elif LINUX_VERSION_CODE < KERNEL_VERSION(5, 19, 0) ++ csum = csum_and_copy_to_user(src, dst, len); ++ *err = (csum == 0) ? -EFAULT : 0; +#else -+ csum = csum_and_copy_to_user(skb->data + offset, curr, len); -+ err = (csum == 0) ? -EFAULT : 0; ++ if (!user_access_begin(dst, len)) { ++ *err = -EFAULT; ++ csum = 0; ++ } else { ++ *err = 0; ++ csum = csum_partial_copy_nocheck(src, dst, len); ++ user_access_end(); ++ } +#endif ++ return csum; ++} ++ ++ ++/* ++ *---------------------------------------------------------------------- ++ * + * VNetCsumCopyDatagram -- + * + * Copy part of datagram to userspace doing checksum at same time. +@@ -576,7 +581,7 @@ VNetCsumCopyDatagram(const struct sk_buf + return -EINVAL; + } + +- csum = csum_and_copy_to_user(skb->data + offset, curr, len, 0, &err); ++ csum = VNetCsumAndCopyToUser(skb->data + offset, curr, len, &err); if (err) { return err; } -@@ -585,20 +595,26 @@ VNetCsumCopyDatagram(const struct sk_buf +@@ -585,20 +595,20 @@ VNetCsumCopyDatagram(const struct sk_buf for (frag = skb_shinfo(skb)->frags; frag != skb_shinfo(skb)->frags + skb_shinfo(skb)->nr_frags; frag++) { @@ -286,14 +406,8 @@ - curr, frag->size, 0, &err); - compat_kunmap(frag->page); + vaddr = kmap(skb_frag_page(frag)); -+#if COMPAT_LINUX_VERSION_CHECK_LT(5, 10, 0) -+ tmpCsum = csum_and_copy_to_user(vaddr + skb_frag_off(frag), -+ curr, skb_frag_size(frag), 0, &err); -+#else -+ tmpCsum = csum_and_copy_to_user(vaddr + skb_frag_off(frag), -+ curr, skb_frag_size(frag)); -+ err = (tmpCsum == 0) ? -EFAULT : 0; -+#endif ++ tmpCsum = VNetCsumAndCopyToUser(vaddr + skb_frag_off(frag), ++ curr, skb_frag_size(frag), &err); + kunmap(skb_frag_page(frag)); if (err) { @@ -327,246 +441,3 @@ # define compat_sk_alloc(_bri, _pri) sk_alloc(&init_net, \ PF_NETLINK, _pri, &vmnet_proto, 1) #elif defined(VMW_NETDEV_HAS_NET) -From 4af1a71978962f9805fe2e7e6ceb05c24f42c7f0 Mon Sep 17 00:00:00 2001 -From: Michal Kubecek <mkubecek@suse.cz> -Date: Tue, 11 Jan 2022 17:25:45 +0100 -Subject: [PATCH] vmnet: use accessors for net_device::dev_addr - -Mainline commit adeef3e32146 ("net: constify netdev->dev_addr") in 5.17-rc1 -makes dev_addr member of struct net_device const but accessors should be -used to modify it since 5.15 to make sure rbtree with hardware address list -is updated properly. - -Use dev_addr_set() and __dev_addr_set() in VNetNetifSetMAC() and -VNetNetIf_Create(). For kernels before 5.15 provide our own version of the -accessors. As SMAC_SetMac() only reads dev_addr, constify the corresponding -argument. ---- - vmnet-only/netif.c | 18 +++++++++++++++--- - vmnet-only/smac.c | 2 +- - vmnet-only/smac.h | 2 +- - 3 files changed, 17 insertions(+), 5 deletions(-) - -diff --git a/vmnet-only/netif.c b/vmnet-only/netif.c -index c70f7f4..8c3bbf8 100644 ---- a/vmnet-only/netif.c -+++ b/vmnet-only/netif.c -@@ -65,6 +64,19 @@ static int VNetNetIfProcRead(char *page, char **start, off_t off, - static int VNetNetIfProcRead(char *page, char **start, off_t off, - int count, int *eof, void *data); - -+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0) -+static void -+__dev_addr_set(struct net_device *dev, const void *addr, size_t len) -+{ -+ memcpy(dev->dev_addr, addr, len); -+} -+ -+static void dev_addr_set(struct net_device *dev, const u8 *addr) -+{ -+ __dev_addr_set(dev, addr, dev->addr_len); -+} -+#endif -+ - /* - *---------------------------------------------------------------------- - * -@@ -219,7 +232,7 @@ VNetNetIf_Create(char *devName, // IN: - - memset(&netIf->stats, 0, sizeof netIf->stats); - -- memcpy(dev->dev_addr, netIf->port.paddr, sizeof netIf->port.paddr); -+ __dev_addr_set(dev, netIf->port.paddr, sizeof(netIf->port.paddr)); - - if (register_netdev(dev) != 0) { - LOG(0, (KERN_NOTICE "%s: could not register network device\n", -@@ -498,7 +511,7 @@ VNetNetifSetMAC(struct net_device *dev, // IN: - return -EINVAL; - } - memcpy(netIf->port.paddr, addr->sa_data, dev->addr_len); -- memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); -+ dev_addr_set(dev, addr->sa_data); - return 0; - } - -diff --git a/vmnet-only/smac.c b/vmnet-only/smac.c -index f18be8a..7f38e7a 100644 ---- a/vmnet-only/smac.c -+++ b/vmnet-only/smac.c -@@ -4115,7 +4115,7 @@ SMAC_InitState(SMACState **ptr) // OUT: pointer to alloced/inited state - - void SMACINT - SMAC_SetMac(SMACState *state, // IN: state to update -- uint8 *mac) // IN: pointer to host adapter's MAC -+ const uint8 *mac) // IN: pointer to host adapter's MAC - { - VNETKdPrintCall(("SMAC_SetMac")); - ASSERT(state); -diff --git a/vmnet-only/smac.h b/vmnet-only/smac.h -index c8df9d2..f03fd3f 100644 ---- a/vmnet-only/smac.h -+++ b/vmnet-only/smac.h -@@ -72,7 +72,7 @@ Bool BridgeIPv4MatchAddrMAC(const ULONG ipAddr, const uint8 *mac); - void SMACINT - SMAC_InitState(struct SMACState **ptr); // IN: state to alloc/init - void SMACINT --SMAC_SetMac(struct SMACState *state, uint8 *mac); // IN: state, and host MAC -+SMAC_SetMac(struct SMACState *state, const uint8 *mac); // IN: state, and host MAC - void SMACINT - SMAC_CleanupState(struct SMACState **ptr); // IN: state to cleanup/dealloc - -From 409623bd4693afada659af82e823a6291f70797a Mon Sep 17 00:00:00 2001 -From: Michal Kubecek <mkubecek@suse.cz> -Date: Mon, 4 Apr 2022 02:05:17 +0200 -Subject: [PATCH] vmnet: use netif_rx() on newer kernels - -In mainline 5.18-rc1, commit baebdf48c360 ("net: dev: Makes sure netif_rx() -can be invoked in any context.") allows calling netif_rx() from any context -and commit 2655926aea9b ("net: Remove netif_rx_any_context() and -netif_rx_ni().") drops netif_rx_ni() as it is no longer needed. - -Replace calls of netif_rx_ni() in VNetBridgeReceiveFromVNet() and -VNetNetIfReceive() by netif_rx() when building against kernel 5.18 and -newer. ---- - vmnet-only/bridge.c | 2 +- - vmnet-only/compat_netdevice.h | 9 +++++++++ - vmnet-only/netif.c | 2 +- - 3 files changed, 11 insertions(+), 2 deletions(-) - -diff --git a/vmnet-only/bridge.c b/vmnet-only/bridge.c -index c84f8ee..d6bd3c4 100644 ---- a/vmnet-only/bridge.c -+++ b/vmnet-only/bridge.c -@@ -694,7 +694,7 @@ VNetBridgeReceiveFromVNet(VNetJack *this, // IN: jack - * not do it, or netif_rx_ni() will deadlock on the cli() lock --hpreg - */ - -- netif_rx_ni(clone); -+ compat_netif_rx_ni(clone); - # if LOGLEVEL >= 4 - vnetTime = ktime_get_ns(); - # endif -diff --git a/vmnet-only/compat_netdevice.h b/vmnet-only/compat_netdevice.h -index bb5001b..c6cc706 100644 ---- a/vmnet-only/compat_netdevice.h -+++ b/vmnet-only/compat_netdevice.h -@@ -344,4 +344,13 @@ typedef u32 compat_netdev_features_t; - #define compat_netif_trans_update(d) do { (d)->trans_start = jiffies; } while (0) - #endif - -+static inline int compat_netif_rx_ni(struct sk_buff *skb) -+{ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 18, 0) -+ return netif_rx(skb); -+#else -+ return netif_rx_ni(skb); -+#endif -+} -+ - #endif /* __COMPAT_NETDEVICE_H__ */ -diff --git a/vmnet-only/netif.c b/vmnet-only/netif.c -index 8c3bbf8..35256a0 100644 ---- a/vmnet-only/netif.c -+++ b/vmnet-only/netif.c -@@ -324,7 +324,7 @@ VNetNetIfReceive(VNetJack *this, // IN: jack - /* send to the host interface */ - skb->dev = netIf->dev; - skb->protocol = eth_type_trans(skb, netIf->dev); -- netif_rx_ni(skb); -+ compat_netif_rx_ni(skb); - netIf->stats.rx_packets++; - - return; -From e02b540ab528917c1afd7848ef64ca146a634994 Mon Sep 17 00:00:00 2001 -From: Michal Kubecek <mkubecek@suse.cz> -Date: Tue, 31 May 2022 23:29:42 +0200 -Subject: [PATCH] vmnet: open code csum_and_copy_to_user on kernel >= 5.19 - -Mainline commit 6308499b5e99 ("net: unexport csum_and_copy_{from,to}_user") -in 5.19-rc1 unexports csum_and_copy_to_user as no in-tree module is using -it. A clean solution would probably be rewriting the code to use iovec -iterator as csum_and_copy_to_iter() is still exported (or perhaps -skb_copy_and_csum_datagram() might be used instead). Anything like this -would be way too intrusive so it would have to wait for VMware developers. - -For now, use the simplest solution and replace the calls to -csum_and_copy_to_user() on 5.19 and newer with open coded implementation. -As the optimized x86 version uses csum_partial_copy_generic() which is not -exported on x86_64 either, copy the generic one from include/net/checksum.h -instead. This will be less efficient but hopefully the performace hit will -not be noticeable. ---- - vmnet-only/userif.c | 45 +++++++++++++++++++++++++++++++-------------- - 1 file changed, 31 insertions(+), 14 deletions(-) - -diff --git a/vmnet-only/userif.c b/vmnet-only/userif.c -index e99c436..2c5a24a 100644 ---- a/vmnet-only/userif.c -+++ b/vmnet-only/userif.c -@@ -91,6 +91,33 @@ extern unsigned int vnet_max_qlen; - # define skb_frag_off(frag) (frag)->page_offset - #endif - -+#if COMPAT_LINUX_VERSION_CHECK_LT(5, 10, 0) -+static inline unsigned int -+compat_csum_and_copy_to_user(const void *src, void __user *dst, int len, -+ int *err) -+{ -+ return csum_and_copy_to_user(src, dst, len, 0, err); -+} -+#else -+static inline unsigned int -+compat_csum_and_copy_to_user(const void *src, void __user *dst, int len, -+ int *err) -+{ -+ unsigned int csum; -+ -+#if COMPAT_LINUX_VERSION_CHECK_LT(5, 19, 0) -+ csum = csum_and_copy_to_user(src, dst, len); -+#else -+ csum = csum_partial(src, len, ~0U); -+ if (copy_to_user(dst, src, len)) -+ csum = 0; -+#endif /* 5.19 */ -+ -+ *err = (csum == 0 ? -EFAULT : 0); -+ return csum; -+} -+#endif /* 5.10 */ -+ - /* - *----------------------------------------------------------------------------- - * -@@ -581,12 +608,7 @@ VNetCsumCopyDatagram(const struct sk_buff *skb, // IN: skb to copy - return -EINVAL; - } - --#if COMPAT_LINUX_VERSION_CHECK_LT(5, 10, 0) -- csum = csum_and_copy_to_user(skb->data + offset, curr, len, 0, &err); --#else -- csum = csum_and_copy_to_user(skb->data + offset, curr, len); -- err = (csum == 0) ? -EFAULT : 0; --#endif -+ csum = compat_csum_and_copy_to_user(skb->data + offset, curr, len, &err); - if (err) { - return err; - } -@@ -600,14 +622,9 @@ VNetCsumCopyDatagram(const struct sk_buff *skb, // IN: skb to copy - const void *vaddr; - - vaddr = kmap(skb_frag_page(frag)); --#if COMPAT_LINUX_VERSION_CHECK_LT(5, 10, 0) -- tmpCsum = csum_and_copy_to_user(vaddr + skb_frag_off(frag), -- curr, skb_frag_size(frag), 0, &err); --#else -- tmpCsum = csum_and_copy_to_user(vaddr + skb_frag_off(frag), -- curr, skb_frag_size(frag)); -- err = (tmpCsum == 0) ? -EFAULT : 0; --#endif -+ tmpCsum = compat_csum_and_copy_to_user(vaddr + skb_frag_off(frag), -+ curr, skb_frag_size(frag), -+ &err); - kunmap(skb_frag_page(frag)); - - if (err) { |