This is the 5.10.179 stable release
-----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEEZH8oZUiU471FcZm+ONu9yGCSaT4FAmRI7pUACgkQONu9yGCS aT4cCRAA0YwtiFA5PDxWdBVW2f/6ad7NL4cCUATt7yd68j22SKifIxmsI4J3WnmT K8p7yvc7WstuvCyoRT+9LpR969jDa/ao5jQQDky+9nFn39RK2pUQ1S4tQhRr0QWP /QrVbecT4X3rn126JhEMauR97Ma5yp0XMj9lOVIac40irf0UyRrvNHciGLfL37Zy 2Q7AOOJGrA9IREpj+uaG4r8QWZtvVYMCZkIgqZDdnEgfjZew+2w8j+4boL6anxpM 0f+6ZFT5OHUabwuBsw+4ee6eRE0K3iaAzde8pIZ2y1/ihYgQ+VlMwcLRncuE/34X dUG1aQyfbcMdukzWO2fay0on/7NF/U2ljS8WTFjWeCGWXzKRxxbmgXD/WRpBba6V NZQB/LroXv+8HVAzlfnZoHD9ojRg8b3exxjy70hUvgAING2CXMqX7KILalFKQvBz Ish5e5cxUBP2khMo1caPCU04dy3t/CF68UBrx4s8+RJFvGBmTykhfUx+DhS8usmu y0GrvyBfCXb1CW56ZZaip2jLv5IiOUL9KzKpPli1PV9K+He6aa2mTtvKzVBUalZf qVzMTifW6JskpxW58I0xKqiaHY5pZVfv0EX65Gs0gVYskSpSLu5MINMvBl5F1sDf DdrJ+ZivMUNU5eGUf99IQgXuYFPWigEzsXQRfwHr78kFP4wIPxg= =Ubp5 -----END PGP SIGNATURE----- Merge 5.10.179 into android12-5.10-lts Changes in 5.10.179 ARM: dts: rockchip: fix a typo error for rk3288 spdif node arm64: dts: qcom: ipq8074-hk01: enable QMP device, not the PHY node arm64: dts: meson-g12-common: specify full DMC range arm64: dts: imx8mm-evk: correct pmic clock source netfilter: br_netfilter: fix recent physdev match breakage regulator: fan53555: Explicitly include bits header net: sched: sch_qfq: prevent slab-out-of-bounds in qfq_activate_agg virtio_net: bugfix overflow inside xdp_linearize_page() sfc: Split STATE_READY in to STATE_NET_DOWN and STATE_NET_UP. sfc: Fix use-after-free due to selftest_work netfilter: nf_tables: fix ifdef to also consider nf_tables=m i40e: fix accessing vsi->active_filters without holding lock i40e: fix i40e_setup_misc_vector() error handling mlxfw: fix null-ptr-deref in mlxfw_mfa2_tlv_next() net: rpl: fix rpl header size calculation mlxsw: pci: Fix possible crash during initialization bpf: Fix incorrect verifier pruning due to missing register precision taints e1000e: Disable TSO on i219-LM card to increase speed f2fs: Fix f2fs_truncate_partial_nodes ftrace event Input: i8042 - add quirk for Fujitsu Lifebook A574/H selftests: sigaltstack: fix -Wuninitialized scsi: megaraid_sas: Fix fw_crash_buffer_show() scsi: core: Improve scsi_vpd_inquiry() checks net: dsa: b53: mmap: add phy ops s390/ptrace: fix PTRACE_GET_LAST_BREAK error handling nvme-tcp: fix a possible UAF when failing to allocate an io queue xen/netback: use same error messages for same errors powerpc/doc: Fix htmldocs errors xfs: drop submit side trans alloc for append ioends iio: light: tsl2772: fix reading proximity-diodes from device tree nilfs2: initialize unused bytes in segment summary blocks memstick: fix memory leak if card device is never registered kernel/sys.c: fix and improve control flow in __sys_setres[ug]id() mmc: sdhci_am654: Set HIGH_SPEED_ENA for SDR12 and SDR25 mm/khugepaged: check again on anon uffd-wp during isolation sched/uclamp: Make task_fits_capacity() use util_fits_cpu() sched/uclamp: Fix fits_capacity() check in feec() sched/uclamp: Make select_idle_capacity() use util_fits_cpu() sched/uclamp: Make asym_fits_capacity() use util_fits_cpu() sched/uclamp: Make cpu_overutilized() use util_fits_cpu() sched/uclamp: Cater for uclamp in find_energy_efficient_cpu()'s early exit condition sched/fair: Detect capacity inversion sched/fair: Consider capacity inversion in util_fits_cpu() sched/uclamp: Fix a uninitialized variable warnings sched/fair: Fixes for capacity inversion detection MIPS: Define RUNTIME_DISCARD_EXIT in LD script docs: futex: Fix kernel-doc references after code split-up preparation purgatory: fix disabling debug info virtiofs: clean up error handling in virtio_fs_get_tree() virtiofs: split requests that exceed virtqueue size fuse: check s_root when destroying sb fuse: fix attr version comparison in fuse_read_update_size() fuse: always revalidate rename target dentry fuse: fix deadlock between atomic O_TRUNC and page invalidation Revert "ext4: fix use-after-free in ext4_xattr_set_entry" ext4: remove duplicate definition of ext4_xattr_ibody_inline_set() ext4: fix use-after-free in ext4_xattr_set_entry udp: Call inet6_destroy_sock() in setsockopt(IPV6_ADDRFORM). tcp/udp: Call inet6_destroy_sock() in IPv6 sk->sk_destruct(). inet6: Remove inet6_destroy_sock() in sk->sk_prot->destroy(). dccp: Call inet6_destroy_sock() via sk->sk_destruct(). sctp: Call inet6_destroy_sock() via sk->sk_destruct(). pwm: meson: Explicitly set .polarity in .get_state() pwm: iqs620a: Explicitly set .polarity in .get_state() pwm: hibvt: Explicitly set .polarity in .get_state() iio: adc: at91-sama5d2_adc: fix an error code in at91_adc_allocate_trigger() ASoC: fsl_asrc_dma: fix potential null-ptr-deref ASN.1: Fix check for strdup() success Linux 5.10.179 Change-Id: I54e476aa9b199a4711a091c77583739ed82af5ad Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
commit
4c20c2c837
@ -1358,7 +1358,7 @@ Mutex API reference
|
||||
Futex API reference
|
||||
===================
|
||||
|
||||
.. kernel-doc:: kernel/futex.c
|
||||
.. kernel-doc:: kernel/futex/core.c
|
||||
:internal:
|
||||
|
||||
Further reading
|
||||
|
@ -1,6 +1,6 @@
|
||||
============================
|
||||
NUMA resource associativity
|
||||
=============================
|
||||
============================
|
||||
|
||||
Associativity represents the groupings of the various platform resources into
|
||||
domains of substantially similar mean performance relative to resources outside
|
||||
@ -20,11 +20,11 @@ A value of 1 indicates the usage of Form 1 associativity. For Form 2 associativi
|
||||
bit 2 of byte 5 in the "ibm,architecture-vec-5" property is used.
|
||||
|
||||
Form 0
|
||||
-----
|
||||
------
|
||||
Form 0 associativity supports only two NUMA distances (LOCAL and REMOTE).
|
||||
|
||||
Form 1
|
||||
-----
|
||||
------
|
||||
With Form 1 a combination of ibm,associativity-reference-points, and ibm,associativity
|
||||
device tree properties are used to determine the NUMA distance between resource groups/domains.
|
||||
|
||||
@ -78,17 +78,18 @@ numa-lookup-index-table.
|
||||
|
||||
For ex:
|
||||
ibm,numa-lookup-index-table = <3 0 8 40>;
|
||||
ibm,numa-distace-table = <9>, /bits/ 8 < 10 20 80
|
||||
20 10 160
|
||||
80 160 10>;
|
||||
| 0 8 40
|
||||
--|------------
|
||||
|
|
||||
0 | 10 20 80
|
||||
|
|
||||
8 | 20 10 160
|
||||
|
|
||||
40| 80 160 10
|
||||
ibm,numa-distace-table = <9>, /bits/ 8 < 10 20 80 20 10 160 80 160 10>;
|
||||
|
||||
::
|
||||
|
||||
| 0 8 40
|
||||
--|------------
|
||||
|
|
||||
0 | 10 20 80
|
||||
|
|
||||
8 | 20 10 160
|
||||
|
|
||||
40| 80 160 10
|
||||
|
||||
A possible "ibm,associativity" property for resources in node 0, 8 and 40
|
||||
|
||||
|
@ -7,6 +7,7 @@ powerpc
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
associativity
|
||||
booting
|
||||
bootwrapper
|
||||
cpu_families
|
||||
|
@ -1400,7 +1400,7 @@ Riferimento per l'API dei Mutex
|
||||
Riferimento per l'API dei Futex
|
||||
===============================
|
||||
|
||||
.. kernel-doc:: kernel/futex.c
|
||||
.. kernel-doc:: kernel/futex/core.c
|
||||
:internal:
|
||||
|
||||
Approfondimenti
|
||||
|
2
Makefile
2
Makefile
@ -1,7 +1,7 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
VERSION = 5
|
||||
PATCHLEVEL = 10
|
||||
SUBLEVEL = 178
|
||||
SUBLEVEL = 179
|
||||
EXTRAVERSION =
|
||||
NAME = Dare mighty things
|
||||
|
||||
|
@ -959,7 +959,7 @@ wdt: watchdog@ff800000 {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
spdif: sound@ff88b0000 {
|
||||
spdif: sound@ff8b0000 {
|
||||
compatible = "rockchip,rk3288-spdif", "rockchip,rk3066-spdif";
|
||||
reg = <0x0 0xff8b0000 0x0 0x10000>;
|
||||
#sound-dai-cells = <0>;
|
||||
|
@ -1604,10 +1604,9 @@ usb2_phy0: phy@36000 {
|
||||
|
||||
dmc: bus@38000 {
|
||||
compatible = "simple-bus";
|
||||
reg = <0x0 0x38000 0x0 0x400>;
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
ranges = <0x0 0x0 0x0 0x38000 0x0 0x400>;
|
||||
ranges = <0x0 0x0 0x0 0x38000 0x0 0x2000>;
|
||||
|
||||
canvas: video-lut@48 {
|
||||
compatible = "amlogic,canvas";
|
||||
|
@ -128,7 +128,7 @@ pmic@4b {
|
||||
rohm,reset-snvs-powered;
|
||||
|
||||
#clock-cells = <0>;
|
||||
clocks = <&osc_32k 0>;
|
||||
clocks = <&osc_32k>;
|
||||
clock-output-names = "clk-32k-out";
|
||||
|
||||
regulators {
|
||||
|
@ -60,11 +60,11 @@ &pcie1 {
|
||||
perst-gpio = <&tlmm 58 0x1>;
|
||||
};
|
||||
|
||||
&pcie_phy0 {
|
||||
&pcie_qmp0 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&pcie_phy1 {
|
||||
&pcie_qmp1 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
|
@ -15,6 +15,8 @@
|
||||
#define EMITS_PT_NOTE
|
||||
#endif
|
||||
|
||||
#define RUNTIME_DISCARD_EXIT
|
||||
|
||||
#include <asm-generic/vmlinux.lds.h>
|
||||
|
||||
#undef mips
|
||||
|
@ -500,9 +500,7 @@ long arch_ptrace(struct task_struct *child, long request,
|
||||
}
|
||||
return 0;
|
||||
case PTRACE_GET_LAST_BREAK:
|
||||
put_user(child->thread.last_break,
|
||||
(unsigned long __user *) data);
|
||||
return 0;
|
||||
return put_user(child->thread.last_break, (unsigned long __user *)data);
|
||||
case PTRACE_ENABLE_TE:
|
||||
if (!MACHINE_HAS_TE)
|
||||
return -EIO;
|
||||
@ -854,9 +852,7 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
|
||||
}
|
||||
return 0;
|
||||
case PTRACE_GET_LAST_BREAK:
|
||||
put_user(child->thread.last_break,
|
||||
(unsigned int __user *) data);
|
||||
return 0;
|
||||
return put_user(child->thread.last_break, (unsigned int __user *)data);
|
||||
}
|
||||
return compat_ptrace_request(child, request, addr, data);
|
||||
}
|
||||
|
@ -64,8 +64,7 @@ CFLAGS_sha256.o += $(PURGATORY_CFLAGS)
|
||||
CFLAGS_REMOVE_string.o += $(PURGATORY_CFLAGS_REMOVE)
|
||||
CFLAGS_string.o += $(PURGATORY_CFLAGS)
|
||||
|
||||
AFLAGS_REMOVE_setup-x86_$(BITS).o += -Wa,-gdwarf-2
|
||||
AFLAGS_REMOVE_entry64.o += -Wa,-gdwarf-2
|
||||
asflags-remove-y += -g -Wa,-gdwarf-2
|
||||
|
||||
$(obj)/purgatory.ro: $(PURGATORY_OBJS) FORCE
|
||||
$(call if_changed,ld)
|
||||
|
@ -1002,7 +1002,7 @@ static struct iio_trigger *at91_adc_allocate_trigger(struct iio_dev *indio,
|
||||
trig = devm_iio_trigger_alloc(&indio->dev, "%s-dev%d-%s", indio->name,
|
||||
indio->id, trigger_name);
|
||||
if (!trig)
|
||||
return NULL;
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
trig->dev.parent = indio->dev.parent;
|
||||
iio_trigger_set_drvdata(trig, indio);
|
||||
|
@ -606,6 +606,7 @@ static int tsl2772_read_prox_diodes(struct tsl2772_chip *chip)
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
chip->settings.prox_diode = prox_diode_mask;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -601,6 +601,14 @@ static const struct dmi_system_id i8042_dmi_quirk_table[] __initconst = {
|
||||
},
|
||||
.driver_data = (void *)(SERIO_QUIRK_NOMUX)
|
||||
},
|
||||
{
|
||||
/* Fujitsu Lifebook A574/H */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "FMVA0501PZ"),
|
||||
},
|
||||
.driver_data = (void *)(SERIO_QUIRK_NOMUX)
|
||||
},
|
||||
{
|
||||
/* Gigabyte M912 */
|
||||
.matches = {
|
||||
|
@ -412,6 +412,7 @@ static struct memstick_dev *memstick_alloc_card(struct memstick_host *host)
|
||||
return card;
|
||||
err_out:
|
||||
host->card = old_card;
|
||||
kfree_const(card->dev.kobj.name);
|
||||
kfree(card);
|
||||
return NULL;
|
||||
}
|
||||
@ -470,8 +471,10 @@ static void memstick_check(struct work_struct *work)
|
||||
put_device(&card->dev);
|
||||
host->card = NULL;
|
||||
}
|
||||
} else
|
||||
} else {
|
||||
kfree_const(card->dev.kobj.name);
|
||||
kfree(card);
|
||||
}
|
||||
}
|
||||
|
||||
out_power_off:
|
||||
|
@ -351,8 +351,6 @@ static void sdhci_am654_write_b(struct sdhci_host *host, u8 val, int reg)
|
||||
*/
|
||||
case MMC_TIMING_SD_HS:
|
||||
case MMC_TIMING_MMC_HS:
|
||||
case MMC_TIMING_UHS_SDR12:
|
||||
case MMC_TIMING_UHS_SDR25:
|
||||
val &= ~SDHCI_CTRL_HISPD;
|
||||
}
|
||||
}
|
||||
|
@ -215,6 +215,18 @@ static int b53_mmap_write64(struct b53_device *dev, u8 page, u8 reg,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int b53_mmap_phy_read16(struct b53_device *dev, int addr, int reg,
|
||||
u16 *value)
|
||||
{
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
static int b53_mmap_phy_write16(struct b53_device *dev, int addr, int reg,
|
||||
u16 value)
|
||||
{
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
static const struct b53_io_ops b53_mmap_ops = {
|
||||
.read8 = b53_mmap_read8,
|
||||
.read16 = b53_mmap_read16,
|
||||
@ -226,6 +238,8 @@ static const struct b53_io_ops b53_mmap_ops = {
|
||||
.write32 = b53_mmap_write32,
|
||||
.write48 = b53_mmap_write48,
|
||||
.write64 = b53_mmap_write64,
|
||||
.phy_read16 = b53_mmap_phy_read16,
|
||||
.phy_write16 = b53_mmap_phy_write16,
|
||||
};
|
||||
|
||||
static int b53_mmap_probe(struct platform_device *pdev)
|
||||
|
@ -5294,31 +5294,6 @@ static void e1000_watchdog_task(struct work_struct *work)
|
||||
ew32(TARC(0), tarc0);
|
||||
}
|
||||
|
||||
/* disable TSO for pcie and 10/100 speeds, to avoid
|
||||
* some hardware issues
|
||||
*/
|
||||
if (!(adapter->flags & FLAG_TSO_FORCE)) {
|
||||
switch (adapter->link_speed) {
|
||||
case SPEED_10:
|
||||
case SPEED_100:
|
||||
e_info("10/100 speed: disabling TSO\n");
|
||||
netdev->features &= ~NETIF_F_TSO;
|
||||
netdev->features &= ~NETIF_F_TSO6;
|
||||
break;
|
||||
case SPEED_1000:
|
||||
netdev->features |= NETIF_F_TSO;
|
||||
netdev->features |= NETIF_F_TSO6;
|
||||
break;
|
||||
default:
|
||||
/* oops */
|
||||
break;
|
||||
}
|
||||
if (hw->mac.type == e1000_pch_spt) {
|
||||
netdev->features &= ~NETIF_F_TSO;
|
||||
netdev->features &= ~NETIF_F_TSO6;
|
||||
}
|
||||
}
|
||||
|
||||
/* enable transmits in the hardware, need to do this
|
||||
* after setting TARC(0)
|
||||
*/
|
||||
@ -7477,6 +7452,32 @@ static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
NETIF_F_RXCSUM |
|
||||
NETIF_F_HW_CSUM);
|
||||
|
||||
/* disable TSO for pcie and 10/100 speeds to avoid
|
||||
* some hardware issues and for i219 to fix transfer
|
||||
* speed being capped at 60%
|
||||
*/
|
||||
if (!(adapter->flags & FLAG_TSO_FORCE)) {
|
||||
switch (adapter->link_speed) {
|
||||
case SPEED_10:
|
||||
case SPEED_100:
|
||||
e_info("10/100 speed: disabling TSO\n");
|
||||
netdev->features &= ~NETIF_F_TSO;
|
||||
netdev->features &= ~NETIF_F_TSO6;
|
||||
break;
|
||||
case SPEED_1000:
|
||||
netdev->features |= NETIF_F_TSO;
|
||||
netdev->features |= NETIF_F_TSO6;
|
||||
break;
|
||||
default:
|
||||
/* oops */
|
||||
break;
|
||||
}
|
||||
if (hw->mac.type == e1000_pch_spt) {
|
||||
netdev->features &= ~NETIF_F_TSO;
|
||||
netdev->features &= ~NETIF_F_TSO6;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set user-changeable features (subset of all device features) */
|
||||
netdev->hw_features = netdev->features;
|
||||
netdev->hw_features |= NETIF_F_RXFCS;
|
||||
|
@ -10448,8 +10448,11 @@ static void i40e_rebuild(struct i40e_pf *pf, bool reinit, bool lock_acquired)
|
||||
pf->hw.aq.asq_last_status));
|
||||
}
|
||||
/* reinit the misc interrupt */
|
||||
if (pf->flags & I40E_FLAG_MSIX_ENABLED)
|
||||
if (pf->flags & I40E_FLAG_MSIX_ENABLED) {
|
||||
ret = i40e_setup_misc_vector(pf);
|
||||
if (ret)
|
||||
goto end_unlock;
|
||||
}
|
||||
|
||||
/* Add a filter to drop all Flow control frames from any VSI from being
|
||||
* transmitted. By doing so we stop a malicious VF from sending out
|
||||
@ -13458,15 +13461,15 @@ static int i40e_add_vsi(struct i40e_vsi *vsi)
|
||||
vsi->id = ctxt.vsi_number;
|
||||
}
|
||||
|
||||
vsi->active_filters = 0;
|
||||
clear_bit(__I40E_VSI_OVERFLOW_PROMISC, vsi->state);
|
||||
spin_lock_bh(&vsi->mac_filter_hash_lock);
|
||||
vsi->active_filters = 0;
|
||||
/* If macvlan filters already exist, force them to get loaded */
|
||||
hash_for_each_safe(vsi->mac_filter_hash, bkt, h, f, hlist) {
|
||||
f->state = I40E_FILTER_NEW;
|
||||
f_count++;
|
||||
}
|
||||
spin_unlock_bh(&vsi->mac_filter_hash_lock);
|
||||
clear_bit(__I40E_VSI_OVERFLOW_PROMISC, vsi->state);
|
||||
|
||||
if (f_count) {
|
||||
vsi->flags |= I40E_VSI_FLAG_FILTER_CHANGED;
|
||||
|
@ -31,6 +31,8 @@ mlxfw_mfa2_tlv_next(const struct mlxfw_mfa2_file *mfa2_file,
|
||||
|
||||
if (tlv->type == MLXFW_MFA2_TLV_MULTI_PART) {
|
||||
multi = mlxfw_mfa2_tlv_multi_get(mfa2_file, tlv);
|
||||
if (!multi)
|
||||
return NULL;
|
||||
tlv_len = NLA_ALIGN(tlv_len + be16_to_cpu(multi->total_len));
|
||||
}
|
||||
|
||||
|
@ -26,7 +26,7 @@
|
||||
#define MLXSW_PCI_CIR_TIMEOUT_MSECS 1000
|
||||
|
||||
#define MLXSW_PCI_SW_RESET_TIMEOUT_MSECS 900000
|
||||
#define MLXSW_PCI_SW_RESET_WAIT_MSECS 200
|
||||
#define MLXSW_PCI_SW_RESET_WAIT_MSECS 400
|
||||
#define MLXSW_PCI_FW_READY 0xA1844
|
||||
#define MLXSW_PCI_FW_READY_MASK 0xFFFF
|
||||
#define MLXSW_PCI_FW_READY_MAGIC 0x5E
|
||||
|
@ -96,6 +96,8 @@ static int ef100_net_stop(struct net_device *net_dev)
|
||||
efx_mcdi_free_vis(efx);
|
||||
efx_remove_interrupts(efx);
|
||||
|
||||
efx->state = STATE_NET_DOWN;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -172,6 +174,8 @@ static int ef100_net_open(struct net_device *net_dev)
|
||||
efx_link_status_changed(efx);
|
||||
mutex_unlock(&efx->mac_lock);
|
||||
|
||||
efx->state = STATE_NET_UP;
|
||||
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
@ -272,7 +276,7 @@ int ef100_register_netdev(struct efx_nic *efx)
|
||||
/* Always start with carrier off; PHY events will detect the link */
|
||||
netif_carrier_off(net_dev);
|
||||
|
||||
efx->state = STATE_READY;
|
||||
efx->state = STATE_NET_DOWN;
|
||||
rtnl_unlock();
|
||||
efx_init_mcdi_logging(efx);
|
||||
|
||||
|
@ -105,14 +105,6 @@ static int efx_xdp(struct net_device *dev, struct netdev_bpf *xdp);
|
||||
static int efx_xdp_xmit(struct net_device *dev, int n, struct xdp_frame **xdpfs,
|
||||
u32 flags);
|
||||
|
||||
#define EFX_ASSERT_RESET_SERIALISED(efx) \
|
||||
do { \
|
||||
if ((efx->state == STATE_READY) || \
|
||||
(efx->state == STATE_RECOVERY) || \
|
||||
(efx->state == STATE_DISABLED)) \
|
||||
ASSERT_RTNL(); \
|
||||
} while (0)
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* Port handling
|
||||
@ -377,6 +369,8 @@ static int efx_probe_all(struct efx_nic *efx)
|
||||
if (rc)
|
||||
goto fail5;
|
||||
|
||||
efx->state = STATE_NET_DOWN;
|
||||
|
||||
return 0;
|
||||
|
||||
fail5:
|
||||
@ -543,7 +537,9 @@ int efx_net_open(struct net_device *net_dev)
|
||||
efx_start_all(efx);
|
||||
if (efx->state == STATE_DISABLED || efx->reset_pending)
|
||||
netif_device_detach(efx->net_dev);
|
||||
efx_selftest_async_start(efx);
|
||||
else
|
||||
efx->state = STATE_NET_UP;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -721,8 +717,6 @@ static int efx_register_netdev(struct efx_nic *efx)
|
||||
* already requested. If so, the NIC is probably hosed so we
|
||||
* abort.
|
||||
*/
|
||||
efx->state = STATE_READY;
|
||||
smp_mb(); /* ensure we change state before checking reset_pending */
|
||||
if (efx->reset_pending) {
|
||||
netif_err(efx, probe, efx->net_dev,
|
||||
"aborting probe due to scheduled reset\n");
|
||||
@ -750,6 +744,8 @@ static int efx_register_netdev(struct efx_nic *efx)
|
||||
|
||||
efx_associate(efx);
|
||||
|
||||
efx->state = STATE_NET_DOWN;
|
||||
|
||||
rtnl_unlock();
|
||||
|
||||
rc = device_create_file(&efx->pci_dev->dev, &dev_attr_phy_type);
|
||||
@ -851,7 +847,7 @@ static void efx_pci_remove_main(struct efx_nic *efx)
|
||||
/* Flush reset_work. It can no longer be scheduled since we
|
||||
* are not READY.
|
||||
*/
|
||||
BUG_ON(efx->state == STATE_READY);
|
||||
WARN_ON(efx_net_active(efx->state));
|
||||
efx_flush_reset_workqueue(efx);
|
||||
|
||||
efx_disable_interrupts(efx);
|
||||
@ -1196,13 +1192,13 @@ static int efx_pm_freeze(struct device *dev)
|
||||
|
||||
rtnl_lock();
|
||||
|
||||
if (efx->state != STATE_DISABLED) {
|
||||
efx->state = STATE_UNINIT;
|
||||
|
||||
if (efx_net_active(efx->state)) {
|
||||
efx_device_detach_sync(efx);
|
||||
|
||||
efx_stop_all(efx);
|
||||
efx_disable_interrupts(efx);
|
||||
|
||||
efx->state = efx_freeze(efx->state);
|
||||
}
|
||||
|
||||
rtnl_unlock();
|
||||
@ -1217,7 +1213,7 @@ static int efx_pm_thaw(struct device *dev)
|
||||
|
||||
rtnl_lock();
|
||||
|
||||
if (efx->state != STATE_DISABLED) {
|
||||
if (efx_frozen(efx->state)) {
|
||||
rc = efx_enable_interrupts(efx);
|
||||
if (rc)
|
||||
goto fail;
|
||||
@ -1230,7 +1226,7 @@ static int efx_pm_thaw(struct device *dev)
|
||||
|
||||
efx_device_attach_if_not_resetting(efx);
|
||||
|
||||
efx->state = STATE_READY;
|
||||
efx->state = efx_thaw(efx->state);
|
||||
|
||||
efx->type->resume_wol(efx);
|
||||
}
|
||||
|
@ -542,6 +542,8 @@ void efx_start_all(struct efx_nic *efx)
|
||||
/* Start the hardware monitor if there is one */
|
||||
efx_start_monitor(efx);
|
||||
|
||||
efx_selftest_async_start(efx);
|
||||
|
||||
/* Link state detection is normally event-driven; we have
|
||||
* to poll now because we could have missed a change
|
||||
*/
|
||||
@ -897,7 +899,7 @@ static void efx_reset_work(struct work_struct *data)
|
||||
* have changed by now. Now that we have the RTNL lock,
|
||||
* it cannot change again.
|
||||
*/
|
||||
if (efx->state == STATE_READY)
|
||||
if (efx_net_active(efx->state))
|
||||
(void)efx_reset(efx, method);
|
||||
|
||||
rtnl_unlock();
|
||||
@ -907,7 +909,7 @@ void efx_schedule_reset(struct efx_nic *efx, enum reset_type type)
|
||||
{
|
||||
enum reset_type method;
|
||||
|
||||
if (efx->state == STATE_RECOVERY) {
|
||||
if (efx_recovering(efx->state)) {
|
||||
netif_dbg(efx, drv, efx->net_dev,
|
||||
"recovering: skip scheduling %s reset\n",
|
||||
RESET_TYPE(type));
|
||||
@ -942,7 +944,7 @@ void efx_schedule_reset(struct efx_nic *efx, enum reset_type type)
|
||||
/* If we're not READY then just leave the flags set as the cue
|
||||
* to abort probing or reschedule the reset later.
|
||||
*/
|
||||
if (READ_ONCE(efx->state) != STATE_READY)
|
||||
if (!efx_net_active(READ_ONCE(efx->state)))
|
||||
return;
|
||||
|
||||
/* efx_process_channel() will no longer read events once a
|
||||
@ -1214,7 +1216,7 @@ static pci_ers_result_t efx_io_error_detected(struct pci_dev *pdev,
|
||||
rtnl_lock();
|
||||
|
||||
if (efx->state != STATE_DISABLED) {
|
||||
efx->state = STATE_RECOVERY;
|
||||
efx->state = efx_recover(efx->state);
|
||||
efx->reset_pending = 0;
|
||||
|
||||
efx_device_detach_sync(efx);
|
||||
@ -1268,7 +1270,7 @@ static void efx_io_resume(struct pci_dev *pdev)
|
||||
netif_err(efx, hw, efx->net_dev,
|
||||
"efx_reset failed after PCI error (%d)\n", rc);
|
||||
} else {
|
||||
efx->state = STATE_READY;
|
||||
efx->state = efx_recovered(efx->state);
|
||||
netif_dbg(efx, hw, efx->net_dev,
|
||||
"Done resetting and resuming IO after PCI error.\n");
|
||||
}
|
||||
|
@ -45,9 +45,7 @@ int efx_reconfigure_port(struct efx_nic *efx);
|
||||
|
||||
#define EFX_ASSERT_RESET_SERIALISED(efx) \
|
||||
do { \
|
||||
if ((efx->state == STATE_READY) || \
|
||||
(efx->state == STATE_RECOVERY) || \
|
||||
(efx->state == STATE_DISABLED)) \
|
||||
if (efx->state != STATE_UNINIT) \
|
||||
ASSERT_RTNL(); \
|
||||
} while (0)
|
||||
|
||||
@ -64,7 +62,7 @@ void efx_port_dummy_op_void(struct efx_nic *efx);
|
||||
|
||||
static inline int efx_check_disabled(struct efx_nic *efx)
|
||||
{
|
||||
if (efx->state == STATE_DISABLED || efx->state == STATE_RECOVERY) {
|
||||
if (efx->state == STATE_DISABLED || efx_recovering(efx->state)) {
|
||||
netif_err(efx, drv, efx->net_dev,
|
||||
"device is disabled due to earlier errors\n");
|
||||
return -EIO;
|
||||
|
@ -137,7 +137,7 @@ void efx_ethtool_self_test(struct net_device *net_dev,
|
||||
if (!efx_tests)
|
||||
goto fail;
|
||||
|
||||
if (efx->state != STATE_READY) {
|
||||
if (!efx_net_active(efx->state)) {
|
||||
rc = -EBUSY;
|
||||
goto out;
|
||||
}
|
||||
|
@ -627,12 +627,54 @@ enum efx_int_mode {
|
||||
#define EFX_INT_MODE_USE_MSI(x) (((x)->interrupt_mode) <= EFX_INT_MODE_MSI)
|
||||
|
||||
enum nic_state {
|
||||
STATE_UNINIT = 0, /* device being probed/removed or is frozen */
|
||||
STATE_READY = 1, /* hardware ready and netdev registered */
|
||||
STATE_DISABLED = 2, /* device disabled due to hardware errors */
|
||||
STATE_RECOVERY = 3, /* device recovering from PCI error */
|
||||
STATE_UNINIT = 0, /* device being probed/removed */
|
||||
STATE_NET_DOWN, /* hardware probed and netdev registered */
|
||||
STATE_NET_UP, /* ready for traffic */
|
||||
STATE_DISABLED, /* device disabled due to hardware errors */
|
||||
|
||||
STATE_RECOVERY = 0x100,/* recovering from PCI error */
|
||||
STATE_FROZEN = 0x200, /* frozen by power management */
|
||||
};
|
||||
|
||||
static inline bool efx_net_active(enum nic_state state)
|
||||
{
|
||||
return state == STATE_NET_DOWN || state == STATE_NET_UP;
|
||||
}
|
||||
|
||||
static inline bool efx_frozen(enum nic_state state)
|
||||
{
|
||||
return state & STATE_FROZEN;
|
||||
}
|
||||
|
||||
static inline bool efx_recovering(enum nic_state state)
|
||||
{
|
||||
return state & STATE_RECOVERY;
|
||||
}
|
||||
|
||||
static inline enum nic_state efx_freeze(enum nic_state state)
|
||||
{
|
||||
WARN_ON(!efx_net_active(state));
|
||||
return state | STATE_FROZEN;
|
||||
}
|
||||
|
||||
static inline enum nic_state efx_thaw(enum nic_state state)
|
||||
{
|
||||
WARN_ON(!efx_frozen(state));
|
||||
return state & ~STATE_FROZEN;
|
||||
}
|
||||
|
||||
static inline enum nic_state efx_recover(enum nic_state state)
|
||||
{
|
||||
WARN_ON(!efx_net_active(state));
|
||||
return state | STATE_RECOVERY;
|
||||
}
|
||||
|
||||
static inline enum nic_state efx_recovered(enum nic_state state)
|
||||
{
|
||||
WARN_ON(!efx_recovering(state));
|
||||
return state & ~STATE_RECOVERY;
|
||||
}
|
||||
|
||||
/* Forward declaration */
|
||||
struct efx_nic;
|
||||
|
||||
|
@ -646,8 +646,13 @@ static struct page *xdp_linearize_page(struct receive_queue *rq,
|
||||
int page_off,
|
||||
unsigned int *len)
|
||||
{
|
||||
struct page *page = alloc_page(GFP_ATOMIC);
|
||||
int tailroom = SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
|
||||
struct page *page;
|
||||
|
||||
if (page_off + *len + tailroom > PAGE_SIZE)
|
||||
return NULL;
|
||||
|
||||
page = alloc_page(GFP_ATOMIC);
|
||||
if (!page)
|
||||
return NULL;
|
||||
|
||||
@ -655,7 +660,6 @@ static struct page *xdp_linearize_page(struct receive_queue *rq,
|
||||
page_off += *len;
|
||||
|
||||
while (--*num_buf) {
|
||||
int tailroom = SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
|
||||
unsigned int buflen;
|
||||
void *buf;
|
||||
int off;
|
||||
|
@ -996,10 +996,8 @@ static void xenvif_tx_build_gops(struct xenvif_queue *queue,
|
||||
|
||||
/* No crossing a page as the payload mustn't fragment. */
|
||||
if (unlikely((txreq.offset + txreq.size) > XEN_PAGE_SIZE)) {
|
||||
netdev_err(queue->vif->dev,
|
||||
"txreq.offset: %u, size: %u, end: %lu\n",
|
||||
txreq.offset, txreq.size,
|
||||
(unsigned long)(txreq.offset&~XEN_PAGE_MASK) + txreq.size);
|
||||
netdev_err(queue->vif->dev, "Cross page boundary, txreq.offset: %u, size: %u\n",
|
||||
txreq.offset, txreq.size);
|
||||
xenvif_fatal_tx_err(queue->vif);
|
||||
break;
|
||||
}
|
||||
|
@ -1535,22 +1535,7 @@ static int nvme_tcp_alloc_queue(struct nvme_ctrl *nctrl,
|
||||
if (ret)
|
||||
goto err_init_connect;
|
||||
|
||||
queue->rd_enabled = true;
|
||||
set_bit(NVME_TCP_Q_ALLOCATED, &queue->flags);
|
||||
nvme_tcp_init_recv_ctx(queue);
|
||||
|
||||
write_lock_bh(&queue->sock->sk->sk_callback_lock);
|
||||
queue->sock->sk->sk_user_data = queue;
|
||||
queue->state_change = queue->sock->sk->sk_state_change;
|
||||
queue->data_ready = queue->sock->sk->sk_data_ready;
|
||||
queue->write_space = queue->sock->sk->sk_write_space;
|
||||
queue->sock->sk->sk_data_ready = nvme_tcp_data_ready;
|
||||
queue->sock->sk->sk_state_change = nvme_tcp_state_change;
|
||||
queue->sock->sk->sk_write_space = nvme_tcp_write_space;
|
||||
#ifdef CONFIG_NET_RX_BUSY_POLL
|
||||
queue->sock->sk->sk_ll_usec = 1;
|
||||
#endif
|
||||
write_unlock_bh(&queue->sock->sk->sk_callback_lock);
|
||||
|
||||
return 0;
|
||||
|
||||
@ -1569,7 +1554,7 @@ static int nvme_tcp_alloc_queue(struct nvme_ctrl *nctrl,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void nvme_tcp_restore_sock_calls(struct nvme_tcp_queue *queue)
|
||||
static void nvme_tcp_restore_sock_ops(struct nvme_tcp_queue *queue)
|
||||
{
|
||||
struct socket *sock = queue->sock;
|
||||
|
||||
@ -1584,7 +1569,7 @@ static void nvme_tcp_restore_sock_calls(struct nvme_tcp_queue *queue)
|
||||
static void __nvme_tcp_stop_queue(struct nvme_tcp_queue *queue)
|
||||
{
|
||||
kernel_sock_shutdown(queue->sock, SHUT_RDWR);
|
||||
nvme_tcp_restore_sock_calls(queue);
|
||||
nvme_tcp_restore_sock_ops(queue);
|
||||
cancel_work_sync(&queue->io_work);
|
||||
}
|
||||
|
||||
@ -1599,21 +1584,42 @@ static void nvme_tcp_stop_queue(struct nvme_ctrl *nctrl, int qid)
|
||||
mutex_unlock(&queue->queue_lock);
|
||||
}
|
||||
|
||||
static void nvme_tcp_setup_sock_ops(struct nvme_tcp_queue *queue)
|
||||
{
|
||||
write_lock_bh(&queue->sock->sk->sk_callback_lock);
|
||||
queue->sock->sk->sk_user_data = queue;
|
||||
queue->state_change = queue->sock->sk->sk_state_change;
|
||||
queue->data_ready = queue->sock->sk->sk_data_ready;
|
||||
queue->write_space = queue->sock->sk->sk_write_space;
|
||||
queue->sock->sk->sk_data_ready = nvme_tcp_data_ready;
|
||||
queue->sock->sk->sk_state_change = nvme_tcp_state_change;
|
||||
queue->sock->sk->sk_write_space = nvme_tcp_write_space;
|
||||
#ifdef CONFIG_NET_RX_BUSY_POLL
|
||||
queue->sock->sk->sk_ll_usec = 1;
|
||||
#endif
|
||||
write_unlock_bh(&queue->sock->sk->sk_callback_lock);
|
||||
}
|
||||
|
||||
static int nvme_tcp_start_queue(struct nvme_ctrl *nctrl, int idx)
|
||||
{
|
||||
struct nvme_tcp_ctrl *ctrl = to_tcp_ctrl(nctrl);
|
||||
struct nvme_tcp_queue *queue = &ctrl->queues[idx];
|
||||
int ret;
|
||||
|
||||
queue->rd_enabled = true;
|
||||
nvme_tcp_init_recv_ctx(queue);
|
||||
nvme_tcp_setup_sock_ops(queue);
|
||||
|
||||
if (idx)
|
||||
ret = nvmf_connect_io_queue(nctrl, idx, false);
|
||||
else
|
||||
ret = nvmf_connect_admin_queue(nctrl);
|
||||
|
||||
if (!ret) {
|
||||
set_bit(NVME_TCP_Q_LIVE, &ctrl->queues[idx].flags);
|
||||
set_bit(NVME_TCP_Q_LIVE, &queue->flags);
|
||||
} else {
|
||||
if (test_bit(NVME_TCP_Q_ALLOCATED, &ctrl->queues[idx].flags))
|
||||
__nvme_tcp_stop_queue(&ctrl->queues[idx]);
|
||||
if (test_bit(NVME_TCP_Q_ALLOCATED, &queue->flags))
|
||||
__nvme_tcp_stop_queue(queue);
|
||||
dev_err(nctrl->device,
|
||||
"failed to connect queue: %d ret=%d\n", idx, ret);
|
||||
}
|
||||
|
@ -146,6 +146,7 @@ static void hibvt_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
|
||||
value = readl(base + PWM_CTRL_ADDR(pwm->hwpwm));
|
||||
state->enabled = (PWM_ENABLE_MASK & value);
|
||||
state->polarity = (PWM_POLARITY_MASK & value) ? PWM_POLARITY_INVERSED : PWM_POLARITY_NORMAL;
|
||||
}
|
||||
|
||||
static int hibvt_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
|
@ -132,6 +132,7 @@ static void iqs620_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
mutex_unlock(&iqs620_pwm->lock);
|
||||
|
||||
state->period = IQS620_PWM_PERIOD_NS;
|
||||
state->polarity = PWM_POLARITY_NORMAL;
|
||||
}
|
||||
|
||||
static int iqs620_pwm_notifier(struct notifier_block *notifier,
|
||||
|
@ -168,6 +168,12 @@ static int meson_pwm_calc(struct meson_pwm *meson, struct pwm_device *pwm,
|
||||
duty = state->duty_cycle;
|
||||
period = state->period;
|
||||
|
||||
/*
|
||||
* Note this is wrong. The result is an output wave that isn't really
|
||||
* inverted and so is wrongly identified by .get_state as normal.
|
||||
* Fixing this needs some care however as some machines might rely on
|
||||
* this.
|
||||
*/
|
||||
if (state->polarity == PWM_POLARITY_INVERSED)
|
||||
duty = period - duty;
|
||||
|
||||
@ -366,6 +372,7 @@ static void meson_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
state->period = 0;
|
||||
state->duty_cycle = 0;
|
||||
}
|
||||
state->polarity = PWM_POLARITY_NORMAL;
|
||||
}
|
||||
|
||||
static const struct pwm_ops meson_pwm_ops = {
|
||||
|
@ -8,18 +8,19 @@
|
||||
// Copyright (c) 2012 Marvell Technology Ltd.
|
||||
// Yunfan Zhang <yfzhang@marvell.com>
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/param.h>
|
||||
#include <linux/bits.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/param.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/regulator/driver.h>
|
||||
#include <linux/regulator/fan53555.h>
|
||||
#include <linux/regulator/machine.h>
|
||||
#include <linux/regulator/of_regulator.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/regulator/fan53555.h>
|
||||
|
||||
/* Voltage setting */
|
||||
#define FAN53555_VSEL0 0x00
|
||||
|
@ -3248,7 +3248,7 @@ fw_crash_buffer_show(struct device *cdev,
|
||||
|
||||
spin_lock_irqsave(&instance->crashdump_lock, flags);
|
||||
buff_offset = instance->fw_crash_buffer_offset;
|
||||
if (!instance->crash_dump_buf &&
|
||||
if (!instance->crash_dump_buf ||
|
||||
!((instance->fw_crash_state == AVAILABLE) ||
|
||||
(instance->fw_crash_state == COPYING))) {
|
||||
dev_err(&instance->pdev->dev,
|
||||
|
@ -317,11 +317,18 @@ static int scsi_vpd_inquiry(struct scsi_device *sdev, unsigned char *buffer,
|
||||
if (result)
|
||||
return -EIO;
|
||||
|
||||
/* Sanity check that we got the page back that we asked for */
|
||||
/*
|
||||
* Sanity check that we got the page back that we asked for and that
|
||||
* the page size is not 0.
|
||||
*/
|
||||
if (buffer[1] != page)
|
||||
return -EIO;
|
||||
|
||||
return get_unaligned_be16(&buffer[2]) + 4;
|
||||
result = get_unaligned_be16(&buffer[2]);
|
||||
if (!result)
|
||||
return -EIO;
|
||||
|
||||
return result + 4;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -205,7 +205,7 @@ static int fuse_dentry_revalidate(struct dentry *entry, unsigned int flags)
|
||||
if (inode && fuse_is_bad(inode))
|
||||
goto invalid;
|
||||
else if (time_before64(fuse_dentry_time(entry), get_jiffies_64()) ||
|
||||
(flags & (LOOKUP_EXCL | LOOKUP_REVAL))) {
|
||||
(flags & (LOOKUP_EXCL | LOOKUP_REVAL | LOOKUP_RENAME_TARGET))) {
|
||||
struct fuse_entry_out outarg;
|
||||
FUSE_ARGS(args);
|
||||
struct fuse_forget_link *forget;
|
||||
@ -578,6 +578,7 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry,
|
||||
struct fuse_entry_out outentry;
|
||||
struct fuse_inode *fi;
|
||||
struct fuse_file *ff;
|
||||
bool trunc = flags & O_TRUNC;
|
||||
|
||||
/* Userspace expects S_IFREG in create mode */
|
||||
BUG_ON((mode & S_IFMT) != S_IFREG);
|
||||
@ -646,6 +647,10 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry,
|
||||
} else {
|
||||
file->private_data = ff;
|
||||
fuse_finish_open(inode, file);
|
||||
if (fm->fc->atomic_o_trunc && trunc)
|
||||
truncate_pagecache(inode, 0);
|
||||
else if (!(ff->open_flags & FOPEN_KEEP_CACHE))
|
||||
invalidate_inode_pages2(inode->i_mapping);
|
||||
}
|
||||
return err;
|
||||
|
||||
|
@ -206,14 +206,10 @@ void fuse_finish_open(struct inode *inode, struct file *file)
|
||||
fi->attr_version = atomic64_inc_return(&fc->attr_version);
|
||||
i_size_write(inode, 0);
|
||||
spin_unlock(&fi->lock);
|
||||
truncate_pagecache(inode, 0);
|
||||
fuse_invalidate_attr(inode);
|
||||
if (fc->writeback_cache)
|
||||
file_update_time(file);
|
||||
} else if (!(ff->open_flags & FOPEN_KEEP_CACHE)) {
|
||||
invalidate_inode_pages2(inode->i_mapping);
|
||||
}
|
||||
|
||||
if ((file->f_mode & FMODE_WRITE) && fc->writeback_cache)
|
||||
fuse_link_write_file(file);
|
||||
}
|
||||
@ -236,30 +232,39 @@ int fuse_open_common(struct inode *inode, struct file *file, bool isdir)
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (is_wb_truncate || dax_truncate) {
|
||||
if (is_wb_truncate || dax_truncate)
|
||||
inode_lock(inode);
|
||||
fuse_set_nowrite(inode);
|
||||
}
|
||||
|
||||
if (dax_truncate) {
|
||||
down_write(&get_fuse_inode(inode)->i_mmap_sem);
|
||||
err = fuse_dax_break_layouts(inode, 0, 0);
|
||||
if (err)
|
||||
goto out;
|
||||
goto out_inode_unlock;
|
||||
}
|
||||
|
||||
if (is_wb_truncate || dax_truncate)
|
||||
fuse_set_nowrite(inode);
|
||||
|
||||
err = fuse_do_open(fm, get_node_id(inode), file, isdir);
|
||||
if (!err)
|
||||
fuse_finish_open(inode, file);
|
||||
|
||||
out:
|
||||
if (is_wb_truncate || dax_truncate)
|
||||
fuse_release_nowrite(inode);
|
||||
if (!err) {
|
||||
struct fuse_file *ff = file->private_data;
|
||||
|
||||
if (fc->atomic_o_trunc && (file->f_flags & O_TRUNC))
|
||||
truncate_pagecache(inode, 0);
|
||||
else if (!(ff->open_flags & FOPEN_KEEP_CACHE))
|
||||
invalidate_inode_pages2(inode->i_mapping);
|
||||
}
|
||||
if (dax_truncate)
|
||||
up_write(&get_fuse_inode(inode)->i_mmap_sem);
|
||||
|
||||
if (is_wb_truncate | dax_truncate) {
|
||||
fuse_release_nowrite(inode);
|
||||
out_inode_unlock:
|
||||
if (is_wb_truncate || dax_truncate)
|
||||
inode_unlock(inode);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
@ -784,7 +789,7 @@ static void fuse_read_update_size(struct inode *inode, loff_t size,
|
||||
struct fuse_inode *fi = get_fuse_inode(inode);
|
||||
|
||||
spin_lock(&fi->lock);
|
||||
if (attr_ver == fi->attr_version && size < inode->i_size &&
|
||||
if (attr_ver >= fi->attr_version && size < inode->i_size &&
|
||||
!test_bit(FUSE_I_SIZE_UNSTABLE, &fi->state)) {
|
||||
fi->attr_version = atomic64_inc_return(&fc->attr_version);
|
||||
i_size_write(inode, size);
|
||||
|
@ -571,6 +571,9 @@ struct fuse_conn {
|
||||
/** Maxmum number of pages that can be used in a single request */
|
||||
unsigned int max_pages;
|
||||
|
||||
/** Constrain ->max_pages to this value during feature negotiation */
|
||||
unsigned int max_pages_limit;
|
||||
|
||||
/** Input queue */
|
||||
struct fuse_iqueue iq;
|
||||
|
||||
|
@ -713,6 +713,7 @@ void fuse_conn_init(struct fuse_conn *fc, struct fuse_mount *fm,
|
||||
fc->pid_ns = get_pid_ns(task_active_pid_ns(current));
|
||||
fc->user_ns = get_user_ns(user_ns);
|
||||
fc->max_pages = FUSE_DEFAULT_MAX_PAGES_PER_REQ;
|
||||
fc->max_pages_limit = FUSE_MAX_MAX_PAGES;
|
||||
|
||||
INIT_LIST_HEAD(&fc->mounts);
|
||||
list_add(&fm->fc_entry, &fc->mounts);
|
||||
@ -1059,7 +1060,7 @@ static void process_init_reply(struct fuse_mount *fm, struct fuse_args *args,
|
||||
fc->abort_err = 1;
|
||||
if (arg->flags & FUSE_MAX_PAGES) {
|
||||
fc->max_pages =
|
||||
min_t(unsigned int, FUSE_MAX_MAX_PAGES,
|
||||
min_t(unsigned int, fc->max_pages_limit,
|
||||
max_t(unsigned int, arg->max_pages, 1));
|
||||
}
|
||||
if (IS_ENABLED(CONFIG_FUSE_DAX) &&
|
||||
@ -1617,7 +1618,7 @@ static void fuse_kill_sb_blk(struct super_block *sb)
|
||||
struct fuse_mount *fm = get_fuse_mount_super(sb);
|
||||
bool last;
|
||||
|
||||
if (fm) {
|
||||
if (sb->s_root) {
|
||||
last = fuse_mount_remove(fm);
|
||||
if (last)
|
||||
fuse_conn_destroy(fm);
|
||||
|
@ -18,6 +18,12 @@
|
||||
#include <linux/uio.h>
|
||||
#include "fuse_i.h"
|
||||
|
||||
/* Used to help calculate the FUSE connection's max_pages limit for a request's
|
||||
* size. Parts of the struct fuse_req are sliced into scattergather lists in
|
||||
* addition to the pages used, so this can help account for that overhead.
|
||||
*/
|
||||
#define FUSE_HEADER_OVERHEAD 4
|
||||
|
||||
/* List of virtio-fs device instances and a lock for the list. Also provides
|
||||
* mutual exclusion in device removal and mounting path
|
||||
*/
|
||||
@ -1395,7 +1401,7 @@ static void virtio_kill_sb(struct super_block *sb)
|
||||
bool last;
|
||||
|
||||
/* If mount failed, we can still be called without any fc */
|
||||
if (fm) {
|
||||
if (sb->s_root) {
|
||||
last = fuse_mount_remove(fm);
|
||||
if (last)
|
||||
virtio_fs_conn_destroy(fm);
|
||||
@ -1428,9 +1434,10 @@ static int virtio_fs_get_tree(struct fs_context *fsc)
|
||||
{
|
||||
struct virtio_fs *fs;
|
||||
struct super_block *sb;
|
||||
struct fuse_conn *fc;
|
||||
struct fuse_conn *fc = NULL;
|
||||
struct fuse_mount *fm;
|
||||
int err;
|
||||
unsigned int virtqueue_size;
|
||||
int err = -EIO;
|
||||
|
||||
/* This gets a reference on virtio_fs object. This ptr gets installed
|
||||
* in fc->iq->priv. Once fuse_conn is going away, it calls ->put()
|
||||
@ -1442,28 +1449,28 @@ static int virtio_fs_get_tree(struct fs_context *fsc)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
virtqueue_size = virtqueue_get_vring_size(fs->vqs[VQ_REQUEST].vq);
|
||||
if (WARN_ON(virtqueue_size <= FUSE_HEADER_OVERHEAD))
|
||||
goto out_err;
|
||||
|
||||
err = -ENOMEM;
|
||||
fc = kzalloc(sizeof(struct fuse_conn), GFP_KERNEL);
|
||||
if (!fc) {
|
||||
mutex_lock(&virtio_fs_mutex);
|
||||
virtio_fs_put(fs);
|
||||
mutex_unlock(&virtio_fs_mutex);
|
||||
return -ENOMEM;
|
||||
}
|
||||
if (!fc)
|
||||
goto out_err;
|
||||
|
||||
fm = kzalloc(sizeof(struct fuse_mount), GFP_KERNEL);
|
||||
if (!fm) {
|
||||
mutex_lock(&virtio_fs_mutex);
|
||||
virtio_fs_put(fs);
|
||||
mutex_unlock(&virtio_fs_mutex);
|
||||
kfree(fc);
|
||||
return -ENOMEM;
|
||||
}
|
||||
if (!fm)
|
||||
goto out_err;
|
||||
|
||||
fuse_conn_init(fc, fm, fsc->user_ns, &virtio_fs_fiq_ops, fs);
|
||||
fc->release = fuse_free_conn;
|
||||
fc->delete_stale = true;
|
||||
fc->auto_submounts = true;
|
||||
|
||||
/* Tell FUSE to split requests that exceed the virtqueue's size */
|
||||
fc->max_pages_limit = min_t(unsigned int, fc->max_pages_limit,
|
||||
virtqueue_size - FUSE_HEADER_OVERHEAD);
|
||||
|
||||
fsc->s_fs_info = fm;
|
||||
sb = sget_fc(fsc, virtio_fs_test_super, virtio_fs_set_super);
|
||||
fuse_mount_put(fm);
|
||||
@ -1485,6 +1492,13 @@ static int virtio_fs_get_tree(struct fs_context *fsc)
|
||||
WARN_ON(fsc->root);
|
||||
fsc->root = dget(sb->s_root);
|
||||
return 0;
|
||||
|
||||
out_err:
|
||||
kfree(fc);
|
||||
mutex_lock(&virtio_fs_mutex);
|
||||
virtio_fs_put(fs);
|
||||
mutex_unlock(&virtio_fs_mutex);
|
||||
return err;
|
||||
}
|
||||
|
||||
static const struct fs_context_operations virtio_fs_context_ops = {
|
||||
|
@ -435,6 +435,23 @@ static int nilfs_segctor_reset_segment_buffer(struct nilfs_sc_info *sci)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* nilfs_segctor_zeropad_segsum - zero pad the rest of the segment summary area
|
||||
* @sci: segment constructor object
|
||||
*
|
||||
* nilfs_segctor_zeropad_segsum() zero-fills unallocated space at the end of
|
||||
* the current segment summary block.
|
||||
*/
|
||||
static void nilfs_segctor_zeropad_segsum(struct nilfs_sc_info *sci)
|
||||
{
|
||||
struct nilfs_segsum_pointer *ssp;
|
||||
|
||||
ssp = sci->sc_blk_cnt > 0 ? &sci->sc_binfo_ptr : &sci->sc_finfo_ptr;
|
||||
if (ssp->offset < ssp->bh->b_size)
|
||||
memset(ssp->bh->b_data + ssp->offset, 0,
|
||||
ssp->bh->b_size - ssp->offset);
|
||||
}
|
||||
|
||||
static int nilfs_segctor_feed_segment(struct nilfs_sc_info *sci)
|
||||
{
|
||||
sci->sc_nblk_this_inc += sci->sc_curseg->sb_sum.nblocks;
|
||||
@ -443,6 +460,7 @@ static int nilfs_segctor_feed_segment(struct nilfs_sc_info *sci)
|
||||
* The current segment is filled up
|
||||
* (internal code)
|
||||
*/
|
||||
nilfs_segctor_zeropad_segsum(sci);
|
||||
sci->sc_curseg = NILFS_NEXT_SEGBUF(sci->sc_curseg);
|
||||
return nilfs_segctor_reset_segment_buffer(sci);
|
||||
}
|
||||
@ -547,6 +565,7 @@ static int nilfs_segctor_add_file_block(struct nilfs_sc_info *sci,
|
||||
goto retry;
|
||||
}
|
||||
if (unlikely(required)) {
|
||||
nilfs_segctor_zeropad_segsum(sci);
|
||||
err = nilfs_segbuf_extend_segsum(segbuf);
|
||||
if (unlikely(err))
|
||||
goto failed;
|
||||
@ -1536,6 +1555,7 @@ static int nilfs_segctor_collect(struct nilfs_sc_info *sci,
|
||||
nadd = min_t(int, nadd << 1, SC_MAX_SEGDELTA);
|
||||
sci->sc_stage = prev_stage;
|
||||
}
|
||||
nilfs_segctor_zeropad_segsum(sci);
|
||||
nilfs_segctor_truncate_segments(sci, sci->sc_curseg, nilfs->ns_sufile);
|
||||
return 0;
|
||||
|
||||
|
@ -39,33 +39,6 @@ static inline bool xfs_ioend_is_append(struct iomap_ioend *ioend)
|
||||
XFS_I(ioend->io_inode)->i_d.di_size;
|
||||
}
|
||||
|
||||
STATIC int
|
||||
xfs_setfilesize_trans_alloc(
|
||||
struct iomap_ioend *ioend)
|
||||
{
|
||||
struct xfs_mount *mp = XFS_I(ioend->io_inode)->i_mount;
|
||||
struct xfs_trans *tp;
|
||||
int error;
|
||||
|
||||
error = xfs_trans_alloc(mp, &M_RES(mp)->tr_fsyncts, 0, 0, 0, &tp);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
ioend->io_private = tp;
|
||||
|
||||
/*
|
||||
* We may pass freeze protection with a transaction. So tell lockdep
|
||||
* we released it.
|
||||
*/
|
||||
__sb_writers_release(ioend->io_inode->i_sb, SB_FREEZE_FS);
|
||||
/*
|
||||
* We hand off the transaction to the completion thread now, so
|
||||
* clear the flag here.
|
||||
*/
|
||||
xfs_trans_clear_context(tp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Update on-disk file size now that data has been written to disk.
|
||||
*/
|
||||
@ -191,12 +164,10 @@ xfs_end_ioend(
|
||||
error = xfs_reflink_end_cow(ip, offset, size);
|
||||
else if (ioend->io_type == IOMAP_UNWRITTEN)
|
||||
error = xfs_iomap_write_unwritten(ip, offset, size, false);
|
||||
else
|
||||
ASSERT(!xfs_ioend_is_append(ioend) || ioend->io_private);
|
||||
|
||||
if (!error && xfs_ioend_is_append(ioend))
|
||||
error = xfs_setfilesize(ip, ioend->io_offset, ioend->io_size);
|
||||
done:
|
||||
if (ioend->io_private)
|
||||
error = xfs_setfilesize_ioend(ioend, error);
|
||||
iomap_finish_ioends(ioend, error);
|
||||
memalloc_nofs_restore(nofs_flag);
|
||||
}
|
||||
@ -246,7 +217,7 @@ xfs_end_io(
|
||||
|
||||
static inline bool xfs_ioend_needs_workqueue(struct iomap_ioend *ioend)
|
||||
{
|
||||
return ioend->io_private ||
|
||||
return xfs_ioend_is_append(ioend) ||
|
||||
ioend->io_type == IOMAP_UNWRITTEN ||
|
||||
(ioend->io_flags & IOMAP_F_SHARED);
|
||||
}
|
||||
@ -259,8 +230,6 @@ xfs_end_bio(
|
||||
struct xfs_inode *ip = XFS_I(ioend->io_inode);
|
||||
unsigned long flags;
|
||||
|
||||
ASSERT(xfs_ioend_needs_workqueue(ioend));
|
||||
|
||||
spin_lock_irqsave(&ip->i_ioend_lock, flags);
|
||||
if (list_empty(&ip->i_ioend_list))
|
||||
WARN_ON_ONCE(!queue_work(ip->i_mount->m_unwritten_workqueue,
|
||||
@ -510,14 +479,6 @@ xfs_prepare_ioend(
|
||||
ioend->io_offset, ioend->io_size);
|
||||
}
|
||||
|
||||
/* Reserve log space if we might write beyond the on-disk inode size. */
|
||||
if (!status &&
|
||||
((ioend->io_flags & IOMAP_F_SHARED) ||
|
||||
ioend->io_type != IOMAP_UNWRITTEN) &&
|
||||
xfs_ioend_is_append(ioend) &&
|
||||
!ioend->io_private)
|
||||
status = xfs_setfilesize_trans_alloc(ioend);
|
||||
|
||||
memalloc_nofs_restore(nofs_flag);
|
||||
|
||||
if (xfs_ioend_needs_workqueue(ioend))
|
||||
|
@ -260,6 +260,7 @@ struct nf_bridge_info {
|
||||
u8 pkt_otherhost:1;
|
||||
u8 in_prerouting:1;
|
||||
u8 bridged_dnat:1;
|
||||
u8 sabotage_in_done:1;
|
||||
__u16 frag_max_size;
|
||||
struct net_device *physindev;
|
||||
|
||||
@ -4322,7 +4323,7 @@ static inline void nf_reset_ct(struct sk_buff *skb)
|
||||
|
||||
static inline void nf_reset_trace(struct sk_buff *skb)
|
||||
{
|
||||
#if IS_ENABLED(CONFIG_NETFILTER_XT_TARGET_TRACE) || defined(CONFIG_NF_TABLES)
|
||||
#if IS_ENABLED(CONFIG_NETFILTER_XT_TARGET_TRACE) || IS_ENABLED(CONFIG_NF_TABLES)
|
||||
skb->nf_trace = 0;
|
||||
#endif
|
||||
}
|
||||
@ -4342,7 +4343,7 @@ static inline void __nf_copy(struct sk_buff *dst, const struct sk_buff *src,
|
||||
dst->_nfct = src->_nfct;
|
||||
nf_conntrack_get(skb_nfct(src));
|
||||
#endif
|
||||
#if IS_ENABLED(CONFIG_NETFILTER_XT_TARGET_TRACE) || defined(CONFIG_NF_TABLES)
|
||||
#if IS_ENABLED(CONFIG_NETFILTER_XT_TARGET_TRACE) || IS_ENABLED(CONFIG_NF_TABLES)
|
||||
if (copy)
|
||||
dst->nf_trace = src->nf_trace;
|
||||
#endif
|
||||
|
@ -1106,6 +1106,8 @@ void ipv6_icmp_error(struct sock *sk, struct sk_buff *skb, int err, __be16 port,
|
||||
void ipv6_local_error(struct sock *sk, int err, struct flowi6 *fl6, u32 info);
|
||||
void ipv6_local_rxpmtu(struct sock *sk, struct flowi6 *fl6, u32 mtu);
|
||||
|
||||
void inet6_cleanup_sock(struct sock *sk);
|
||||
void inet6_sock_destruct(struct sock *sk);
|
||||
int inet6_release(struct socket *sock);
|
||||
int inet6_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len);
|
||||
int inet6_getname(struct socket *sock, struct sockaddr *uaddr,
|
||||
|
@ -268,7 +268,7 @@ static inline bool udp_sk_bound_dev_eq(struct net *net, int bound_dev_if,
|
||||
}
|
||||
|
||||
/* net/ipv4/udp.c */
|
||||
void udp_destruct_sock(struct sock *sk);
|
||||
void udp_destruct_common(struct sock *sk);
|
||||
void skb_consume_udp(struct sock *sk, struct sk_buff *skb, int len);
|
||||
int __udp_enqueue_schedule_skb(struct sock *sk, struct sk_buff *skb);
|
||||
void udp_skb_destructor(struct sock *sk, struct sk_buff *skb);
|
||||
|
@ -24,14 +24,6 @@ static __inline__ int udplite_getfrag(void *from, char *to, int offset,
|
||||
return copy_from_iter_full(to, len, &msg->msg_iter) ? 0 : -EFAULT;
|
||||
}
|
||||
|
||||
/* Designate sk as UDP-Lite socket */
|
||||
static inline int udplite_sk_init(struct sock *sk)
|
||||
{
|
||||
udp_init_sock(sk);
|
||||
udp_sk(sk)->pcflag = UDPLITE_BIT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Checksumming routines
|
||||
*/
|
||||
|
@ -520,7 +520,7 @@ TRACE_EVENT(f2fs_truncate_partial_nodes,
|
||||
TP_STRUCT__entry(
|
||||
__field(dev_t, dev)
|
||||
__field(ino_t, ino)
|
||||
__field(nid_t, nid[3])
|
||||
__array(nid_t, nid, 3)
|
||||
__field(int, depth)
|
||||
__field(int, err)
|
||||
),
|
||||
|
@ -1931,6 +1931,21 @@ static int backtrack_insn(struct bpf_verifier_env *env, int idx,
|
||||
}
|
||||
} else if (opcode == BPF_EXIT) {
|
||||
return -ENOTSUPP;
|
||||
} else if (BPF_SRC(insn->code) == BPF_X) {
|
||||
if (!(*reg_mask & (dreg | sreg)))
|
||||
return 0;
|
||||
/* dreg <cond> sreg
|
||||
* Both dreg and sreg need precision before
|
||||
* this insn. If only sreg was marked precise
|
||||
* before it would be equally necessary to
|
||||
* propagate it to dreg.
|
||||
*/
|
||||
*reg_mask |= (sreg | dreg);
|
||||
/* else dreg <cond> K
|
||||
* Only dreg still needs precision before
|
||||
* this insn, so for the K-based conditional
|
||||
* there is nothing new to be marked.
|
||||
*/
|
||||
}
|
||||
} else if (class == BPF_LD) {
|
||||
if (!(*reg_mask & dreg))
|
||||
|
@ -1018,7 +1018,7 @@ static inline void uclamp_idle_reset(struct rq *rq, enum uclamp_id clamp_id,
|
||||
if (!(rq->uclamp_flags & UCLAMP_FLAG_IDLE))
|
||||
return;
|
||||
|
||||
WRITE_ONCE(rq->uclamp[clamp_id].value, clamp_value);
|
||||
uclamp_rq_set(rq, clamp_id, clamp_value);
|
||||
}
|
||||
|
||||
static inline
|
||||
@ -1203,8 +1203,8 @@ static inline void uclamp_rq_inc_id(struct rq *rq, struct task_struct *p,
|
||||
if (bucket->tasks == 1 || uc_se->value > bucket->value)
|
||||
bucket->value = uc_se->value;
|
||||
|
||||
if (uc_se->value > READ_ONCE(uc_rq->value))
|
||||
WRITE_ONCE(uc_rq->value, uc_se->value);
|
||||
if (uc_se->value > uclamp_rq_get(rq, clamp_id))
|
||||
uclamp_rq_set(rq, clamp_id, uc_se->value);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1270,7 +1270,7 @@ static inline void uclamp_rq_dec_id(struct rq *rq, struct task_struct *p,
|
||||
if (likely(bucket->tasks))
|
||||
return;
|
||||
|
||||
rq_clamp = READ_ONCE(uc_rq->value);
|
||||
rq_clamp = uclamp_rq_get(rq, clamp_id);
|
||||
/*
|
||||
* Defensive programming: this should never happen. If it happens,
|
||||
* e.g. due to future modification, warn and fixup the expected value.
|
||||
@ -1278,7 +1278,7 @@ static inline void uclamp_rq_dec_id(struct rq *rq, struct task_struct *p,
|
||||
SCHED_WARN_ON(bucket->value > rq_clamp);
|
||||
if (bucket->value >= rq_clamp) {
|
||||
bkt_clamp = uclamp_rq_max_value(rq, clamp_id, uc_se->value);
|
||||
WRITE_ONCE(uc_rq->value, bkt_clamp);
|
||||
uclamp_rq_set(rq, clamp_id, bkt_clamp);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3938,14 +3938,16 @@ static inline unsigned long task_util_est(struct task_struct *p)
|
||||
}
|
||||
|
||||
#ifdef CONFIG_UCLAMP_TASK
|
||||
static inline unsigned long uclamp_task_util(struct task_struct *p)
|
||||
static inline unsigned long uclamp_task_util(struct task_struct *p,
|
||||
unsigned long uclamp_min,
|
||||
unsigned long uclamp_max)
|
||||
{
|
||||
return clamp(task_util_est(p),
|
||||
uclamp_eff_value(p, UCLAMP_MIN),
|
||||
uclamp_eff_value(p, UCLAMP_MAX));
|
||||
return clamp(task_util_est(p), uclamp_min, uclamp_max);
|
||||
}
|
||||
#else
|
||||
static inline unsigned long uclamp_task_util(struct task_struct *p)
|
||||
static inline unsigned long uclamp_task_util(struct task_struct *p,
|
||||
unsigned long uclamp_min,
|
||||
unsigned long uclamp_max)
|
||||
{
|
||||
return task_util_est(p);
|
||||
}
|
||||
@ -4126,12 +4128,16 @@ static inline int util_fits_cpu(unsigned long util,
|
||||
* For uclamp_max, we can tolerate a drop in performance level as the
|
||||
* goal is to cap the task. So it's okay if it's getting less.
|
||||
*
|
||||
* In case of capacity inversion, which is not handled yet, we should
|
||||
* honour the inverted capacity for both uclamp_min and uclamp_max all
|
||||
* the time.
|
||||
* In case of capacity inversion we should honour the inverted capacity
|
||||
* for both uclamp_min and uclamp_max all the time.
|
||||
*/
|
||||
capacity_orig = capacity_orig_of(cpu);
|
||||
capacity_orig_thermal = capacity_orig - arch_scale_thermal_pressure(cpu);
|
||||
capacity_orig = cpu_in_capacity_inversion(cpu);
|
||||
if (capacity_orig) {
|
||||
capacity_orig_thermal = capacity_orig;
|
||||
} else {
|
||||
capacity_orig = capacity_orig_of(cpu);
|
||||
capacity_orig_thermal = capacity_orig - arch_scale_thermal_pressure(cpu);
|
||||
}
|
||||
|
||||
/*
|
||||
* We want to force a task to fit a cpu as implied by uclamp_max.
|
||||
@ -4212,10 +4218,12 @@ static inline int util_fits_cpu(unsigned long util,
|
||||
return fits;
|
||||
}
|
||||
|
||||
static inline int task_fits_capacity(struct task_struct *p,
|
||||
unsigned long capacity)
|
||||
static inline int task_fits_cpu(struct task_struct *p, int cpu)
|
||||
{
|
||||
return fits_capacity(uclamp_task_util(p), capacity);
|
||||
unsigned long uclamp_min = uclamp_eff_value(p, UCLAMP_MIN);
|
||||
unsigned long uclamp_max = uclamp_eff_value(p, UCLAMP_MAX);
|
||||
unsigned long util = task_util_est(p);
|
||||
return util_fits_cpu(util, uclamp_min, uclamp_max, cpu);
|
||||
}
|
||||
|
||||
static inline void update_misfit_status(struct task_struct *p, struct rq *rq)
|
||||
@ -4231,7 +4239,7 @@ static inline void update_misfit_status(struct task_struct *p, struct rq *rq)
|
||||
return;
|
||||
}
|
||||
|
||||
if (task_fits_capacity(p, capacity_of(cpu_of(rq)))) {
|
||||
if (task_fits_cpu(p, cpu_of(rq))) {
|
||||
rq->misfit_task_load = 0;
|
||||
return;
|
||||
}
|
||||
@ -5685,13 +5693,15 @@ static inline unsigned long cpu_util(int cpu);
|
||||
|
||||
static inline bool cpu_overutilized(int cpu)
|
||||
{
|
||||
unsigned long rq_util_min = uclamp_rq_get(cpu_rq(cpu), UCLAMP_MIN);
|
||||
unsigned long rq_util_max = uclamp_rq_get(cpu_rq(cpu), UCLAMP_MAX);
|
||||
int overutilized = -1;
|
||||
|
||||
trace_android_rvh_cpu_overutilized(cpu, &overutilized);
|
||||
if (overutilized != -1)
|
||||
return overutilized;
|
||||
|
||||
return !fits_capacity(cpu_util(cpu), capacity_of(cpu));
|
||||
return !util_fits_cpu(cpu_util(cpu), rq_util_min, rq_util_max, cpu);
|
||||
}
|
||||
|
||||
static inline void update_overutilized_status(struct rq *rq)
|
||||
@ -6433,21 +6443,23 @@ static int select_idle_cpu(struct task_struct *p, struct sched_domain *sd, int t
|
||||
static int
|
||||
select_idle_capacity(struct task_struct *p, struct sched_domain *sd, int target)
|
||||
{
|
||||
unsigned long task_util, best_cap = 0;
|
||||
unsigned long task_util, util_min, util_max, best_cap = 0;
|
||||
int cpu, best_cpu = -1;
|
||||
struct cpumask *cpus;
|
||||
|
||||
cpus = this_cpu_cpumask_var_ptr(select_idle_mask);
|
||||
cpumask_and(cpus, sched_domain_span(sd), p->cpus_ptr);
|
||||
|
||||
task_util = uclamp_task_util(p);
|
||||
task_util = task_util_est(p);
|
||||
util_min = uclamp_eff_value(p, UCLAMP_MIN);
|
||||
util_max = uclamp_eff_value(p, UCLAMP_MAX);
|
||||
|
||||
for_each_cpu_wrap(cpu, cpus, target) {
|
||||
unsigned long cpu_cap = capacity_of(cpu);
|
||||
|
||||
if (!available_idle_cpu(cpu) && !sched_idle_cpu(cpu))
|
||||
continue;
|
||||
if (fits_capacity(task_util, cpu_cap))
|
||||
if (util_fits_cpu(task_util, util_min, util_max, cpu))
|
||||
return cpu;
|
||||
|
||||
if (cpu_cap > best_cap) {
|
||||
@ -6459,10 +6471,13 @@ select_idle_capacity(struct task_struct *p, struct sched_domain *sd, int target)
|
||||
return best_cpu;
|
||||
}
|
||||
|
||||
static inline bool asym_fits_capacity(unsigned long task_util, int cpu)
|
||||
static inline bool asym_fits_cpu(unsigned long util,
|
||||
unsigned long util_min,
|
||||
unsigned long util_max,
|
||||
int cpu)
|
||||
{
|
||||
if (static_branch_unlikely(&sched_asym_cpucapacity))
|
||||
return fits_capacity(task_util, capacity_of(cpu));
|
||||
return util_fits_cpu(util, util_min, util_max, cpu);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -6473,7 +6488,7 @@ static inline bool asym_fits_capacity(unsigned long task_util, int cpu)
|
||||
static int select_idle_sibling(struct task_struct *p, int prev, int target)
|
||||
{
|
||||
struct sched_domain *sd;
|
||||
unsigned long task_util;
|
||||
unsigned long task_util, util_min, util_max;
|
||||
int i, recent_used_cpu;
|
||||
|
||||
/*
|
||||
@ -6482,11 +6497,13 @@ static int select_idle_sibling(struct task_struct *p, int prev, int target)
|
||||
*/
|
||||
if (static_branch_unlikely(&sched_asym_cpucapacity)) {
|
||||
sync_entity_load_avg(&p->se);
|
||||
task_util = uclamp_task_util(p);
|
||||
task_util = task_util_est(p);
|
||||
util_min = uclamp_eff_value(p, UCLAMP_MIN);
|
||||
util_max = uclamp_eff_value(p, UCLAMP_MAX);
|
||||
}
|
||||
|
||||
if ((available_idle_cpu(target) || sched_idle_cpu(target)) &&
|
||||
asym_fits_capacity(task_util, target))
|
||||
asym_fits_cpu(task_util, util_min, util_max, target))
|
||||
return target;
|
||||
|
||||
/*
|
||||
@ -6494,7 +6511,7 @@ static int select_idle_sibling(struct task_struct *p, int prev, int target)
|
||||
*/
|
||||
if (prev != target && cpus_share_cache(prev, target) &&
|
||||
(available_idle_cpu(prev) || sched_idle_cpu(prev)) &&
|
||||
asym_fits_capacity(task_util, prev))
|
||||
asym_fits_cpu(task_util, util_min, util_max, prev))
|
||||
return prev;
|
||||
|
||||
/*
|
||||
@ -6509,7 +6526,7 @@ static int select_idle_sibling(struct task_struct *p, int prev, int target)
|
||||
in_task() &&
|
||||
prev == smp_processor_id() &&
|
||||
this_rq()->nr_running <= 1 &&
|
||||
asym_fits_capacity(task_util, prev)) {
|
||||
asym_fits_cpu(task_util, util_min, util_max, prev)) {
|
||||
return prev;
|
||||
}
|
||||
|
||||
@ -6520,7 +6537,7 @@ static int select_idle_sibling(struct task_struct *p, int prev, int target)
|
||||
cpus_share_cache(recent_used_cpu, target) &&
|
||||
(available_idle_cpu(recent_used_cpu) || sched_idle_cpu(recent_used_cpu)) &&
|
||||
cpumask_test_cpu(p->recent_used_cpu, p->cpus_ptr) &&
|
||||
asym_fits_capacity(task_util, recent_used_cpu)) {
|
||||
asym_fits_cpu(task_util, util_min, util_max, recent_used_cpu)) {
|
||||
/*
|
||||
* Replace recent_used_cpu with prev as it is a potential
|
||||
* candidate for the next wake:
|
||||
@ -6846,6 +6863,8 @@ compute_energy(struct task_struct *p, int dst_cpu, struct perf_domain *pd)
|
||||
static int find_energy_efficient_cpu(struct task_struct *p, int prev_cpu, int sync)
|
||||
{
|
||||
unsigned long prev_delta = ULONG_MAX, best_delta = ULONG_MAX;
|
||||
unsigned long p_util_min = uclamp_is_used() ? uclamp_eff_value(p, UCLAMP_MIN) : 0;
|
||||
unsigned long p_util_max = uclamp_is_used() ? uclamp_eff_value(p, UCLAMP_MAX) : 1024;
|
||||
struct root_domain *rd = cpu_rq(smp_processor_id())->rd;
|
||||
int max_spare_cap_cpu_ls = prev_cpu, best_idle_cpu = -1;
|
||||
unsigned long max_spare_cap_ls = 0, target_cap;
|
||||
@ -6871,7 +6890,7 @@ static int find_energy_efficient_cpu(struct task_struct *p, int prev_cpu, int sy
|
||||
cpu = smp_processor_id();
|
||||
if (sync && cpu_rq(cpu)->nr_running == 1 &&
|
||||
cpumask_test_cpu(cpu, p->cpus_ptr) &&
|
||||
task_fits_capacity(p, capacity_of(cpu))) {
|
||||
task_fits_cpu(p, cpu)) {
|
||||
rcu_read_unlock();
|
||||
return cpu;
|
||||
}
|
||||
@ -6886,7 +6905,7 @@ static int find_energy_efficient_cpu(struct task_struct *p, int prev_cpu, int sy
|
||||
if (!sd)
|
||||
goto fail;
|
||||
|
||||
if (!task_util_est(p))
|
||||
if (!uclamp_task_util(p, p_util_min, p_util_max))
|
||||
goto unlock;
|
||||
|
||||
latency_sensitive = uclamp_latency_sensitive(p);
|
||||
@ -6894,7 +6913,9 @@ static int find_energy_efficient_cpu(struct task_struct *p, int prev_cpu, int sy
|
||||
target_cap = boosted ? 0 : ULONG_MAX;
|
||||
|
||||
for (; pd; pd = pd->next) {
|
||||
unsigned long util_min = p_util_min, util_max = p_util_max;
|
||||
unsigned long cur_delta, spare_cap, max_spare_cap = 0;
|
||||
unsigned long rq_util_min, rq_util_max;
|
||||
unsigned long base_energy_pd;
|
||||
int max_spare_cap_cpu = -1;
|
||||
|
||||
@ -6903,6 +6924,8 @@ static int find_energy_efficient_cpu(struct task_struct *p, int prev_cpu, int sy
|
||||
base_energy += base_energy_pd;
|
||||
|
||||
for_each_cpu_and(cpu, perf_domain_span(pd), sched_domain_span(sd)) {
|
||||
struct rq *rq = cpu_rq(cpu);
|
||||
|
||||
if (!cpumask_test_cpu(cpu, p->cpus_ptr))
|
||||
continue;
|
||||
|
||||
@ -6918,8 +6941,21 @@ static int find_energy_efficient_cpu(struct task_struct *p, int prev_cpu, int sy
|
||||
* much capacity we can get out of the CPU; this is
|
||||
* aligned with schedutil_cpu_util().
|
||||
*/
|
||||
util = uclamp_rq_util_with(cpu_rq(cpu), util, p);
|
||||
if (!fits_capacity(util, cpu_cap))
|
||||
if (uclamp_is_used() && !uclamp_rq_is_idle(rq)) {
|
||||
/*
|
||||
* Open code uclamp_rq_util_with() except for
|
||||
* the clamp() part. Ie: apply max aggregation
|
||||
* only. util_fits_cpu() logic requires to
|
||||
* operate on non clamped util but must use the
|
||||
* max-aggregated uclamp_{min, max}.
|
||||
*/
|
||||
rq_util_min = uclamp_rq_get(rq, UCLAMP_MIN);
|
||||
rq_util_max = uclamp_rq_get(rq, UCLAMP_MAX);
|
||||
|
||||
util_min = max(rq_util_min, p_util_min);
|
||||
util_max = max(rq_util_max, p_util_max);
|
||||
}
|
||||
if (!util_fits_cpu(util, util_min, util_max, cpu))
|
||||
continue;
|
||||
|
||||
/* Always use prev_cpu as a candidate. */
|
||||
@ -8080,7 +8116,7 @@ static int detach_tasks(struct lb_env *env)
|
||||
|
||||
case migrate_misfit:
|
||||
/* This is not a misfit task */
|
||||
if (task_fits_capacity(p, capacity_of(env->src_cpu)))
|
||||
if (task_fits_cpu(p, env->src_cpu))
|
||||
goto next;
|
||||
|
||||
env->imbalance = 0;
|
||||
@ -8478,17 +8514,83 @@ static unsigned long scale_rt_capacity(int cpu)
|
||||
|
||||
static void update_cpu_capacity(struct sched_domain *sd, int cpu)
|
||||
{
|
||||
unsigned long capacity_orig = arch_scale_cpu_capacity(cpu);
|
||||
unsigned long capacity = scale_rt_capacity(cpu);
|
||||
struct sched_group *sdg = sd->groups;
|
||||
struct rq *rq = cpu_rq(cpu);
|
||||
|
||||
cpu_rq(cpu)->cpu_capacity_orig = arch_scale_cpu_capacity(cpu);
|
||||
rq->cpu_capacity_orig = capacity_orig;
|
||||
|
||||
if (!capacity)
|
||||
capacity = 1;
|
||||
|
||||
trace_android_rvh_update_cpu_capacity(cpu, &capacity);
|
||||
cpu_rq(cpu)->cpu_capacity = capacity;
|
||||
trace_sched_cpu_capacity_tp(cpu_rq(cpu));
|
||||
rq->cpu_capacity = capacity;
|
||||
|
||||
/*
|
||||
* Detect if the performance domain is in capacity inversion state.
|
||||
*
|
||||
* Capacity inversion happens when another perf domain with equal or
|
||||
* lower capacity_orig_of() ends up having higher capacity than this
|
||||
* domain after subtracting thermal pressure.
|
||||
*
|
||||
* We only take into account thermal pressure in this detection as it's
|
||||
* the only metric that actually results in *real* reduction of
|
||||
* capacity due to performance points (OPPs) being dropped/become
|
||||
* unreachable due to thermal throttling.
|
||||
*
|
||||
* We assume:
|
||||
* * That all cpus in a perf domain have the same capacity_orig
|
||||
* (same uArch).
|
||||
* * Thermal pressure will impact all cpus in this perf domain
|
||||
* equally.
|
||||
*/
|
||||
if (sched_energy_enabled()) {
|
||||
unsigned long inv_cap = capacity_orig - thermal_load_avg(rq);
|
||||
struct perf_domain *pd;
|
||||
|
||||
rcu_read_lock();
|
||||
|
||||
pd = rcu_dereference(rq->rd->pd);
|
||||
rq->cpu_capacity_inverted = 0;
|
||||
|
||||
for (; pd; pd = pd->next) {
|
||||
struct cpumask *pd_span = perf_domain_span(pd);
|
||||
unsigned long pd_cap_orig, pd_cap;
|
||||
|
||||
/* We can't be inverted against our own pd */
|
||||
if (cpumask_test_cpu(cpu_of(rq), pd_span))
|
||||
continue;
|
||||
|
||||
cpu = cpumask_any(pd_span);
|
||||
pd_cap_orig = arch_scale_cpu_capacity(cpu);
|
||||
|
||||
if (capacity_orig < pd_cap_orig)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* handle the case of multiple perf domains have the
|
||||
* same capacity_orig but one of them is under higher
|
||||
* thermal pressure. We record it as capacity
|
||||
* inversion.
|
||||
*/
|
||||
if (capacity_orig == pd_cap_orig) {
|
||||
pd_cap = pd_cap_orig - thermal_load_avg(cpu_rq(cpu));
|
||||
|
||||
if (pd_cap > inv_cap) {
|
||||
rq->cpu_capacity_inverted = inv_cap;
|
||||
break;
|
||||
}
|
||||
} else if (pd_cap_orig > inv_cap) {
|
||||
rq->cpu_capacity_inverted = inv_cap;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
trace_sched_cpu_capacity_tp(rq);
|
||||
|
||||
sdg->sgc->capacity = capacity;
|
||||
sdg->sgc->min_capacity = capacity;
|
||||
@ -9023,6 +9125,10 @@ static inline void update_sg_wakeup_stats(struct sched_domain *sd,
|
||||
|
||||
memset(sgs, 0, sizeof(*sgs));
|
||||
|
||||
/* Assume that task can't fit any CPU of the group */
|
||||
if (sd->flags & SD_ASYM_CPUCAPACITY)
|
||||
sgs->group_misfit_task_load = 1;
|
||||
|
||||
for_each_cpu(i, sched_group_span(group)) {
|
||||
struct rq *rq = cpu_rq(i);
|
||||
unsigned int local;
|
||||
@ -9042,12 +9148,12 @@ static inline void update_sg_wakeup_stats(struct sched_domain *sd,
|
||||
if (!nr_running && idle_cpu_without(i, p))
|
||||
sgs->idle_cpus++;
|
||||
|
||||
}
|
||||
/* Check if task fits in the CPU */
|
||||
if (sd->flags & SD_ASYM_CPUCAPACITY &&
|
||||
sgs->group_misfit_task_load &&
|
||||
task_fits_cpu(p, i))
|
||||
sgs->group_misfit_task_load = 0;
|
||||
|
||||
/* Check if task fits in the group */
|
||||
if (sd->flags & SD_ASYM_CPUCAPACITY &&
|
||||
!task_fits_capacity(p, group->sgc->max_capacity)) {
|
||||
sgs->group_misfit_task_load = 1;
|
||||
}
|
||||
|
||||
sgs->group_capacity = group->sgc->capacity;
|
||||
|
@ -993,6 +993,7 @@ struct rq {
|
||||
|
||||
unsigned long cpu_capacity;
|
||||
unsigned long cpu_capacity_orig;
|
||||
unsigned long cpu_capacity_inverted;
|
||||
|
||||
struct callback_head *balance_callback;
|
||||
|
||||
@ -2458,6 +2459,23 @@ static inline void cpufreq_update_util(struct rq *rq, unsigned int flags) {}
|
||||
#ifdef CONFIG_UCLAMP_TASK
|
||||
unsigned long uclamp_eff_value(struct task_struct *p, enum uclamp_id clamp_id);
|
||||
|
||||
static inline unsigned long uclamp_rq_get(struct rq *rq,
|
||||
enum uclamp_id clamp_id)
|
||||
{
|
||||
return READ_ONCE(rq->uclamp[clamp_id].value);
|
||||
}
|
||||
|
||||
static inline void uclamp_rq_set(struct rq *rq, enum uclamp_id clamp_id,
|
||||
unsigned int value)
|
||||
{
|
||||
WRITE_ONCE(rq->uclamp[clamp_id].value, value);
|
||||
}
|
||||
|
||||
static inline bool uclamp_rq_is_idle(struct rq *rq)
|
||||
{
|
||||
return rq->uclamp_flags & UCLAMP_FLAG_IDLE;
|
||||
}
|
||||
|
||||
/**
|
||||
* uclamp_rq_util_with - clamp @util with @rq and @p effective uclamp values.
|
||||
* @rq: The rq to clamp against. Must not be NULL.
|
||||
@ -2493,12 +2511,12 @@ unsigned long uclamp_rq_util_with(struct rq *rq, unsigned long util,
|
||||
* Ignore last runnable task's max clamp, as this task will
|
||||
* reset it. Similarly, no need to read the rq's min clamp.
|
||||
*/
|
||||
if (rq->uclamp_flags & UCLAMP_FLAG_IDLE)
|
||||
if (uclamp_rq_is_idle(rq))
|
||||
goto out;
|
||||
}
|
||||
|
||||
min_util = max_t(unsigned long, min_util, READ_ONCE(rq->uclamp[UCLAMP_MIN].value));
|
||||
max_util = max_t(unsigned long, max_util, READ_ONCE(rq->uclamp[UCLAMP_MAX].value));
|
||||
min_util = max_t(unsigned long, min_util, uclamp_rq_get(rq, UCLAMP_MIN));
|
||||
max_util = max_t(unsigned long, max_util, uclamp_rq_get(rq, UCLAMP_MAX));
|
||||
out:
|
||||
/*
|
||||
* Since CPU's {min,max}_util clamps are MAX aggregated considering
|
||||
@ -2529,6 +2547,15 @@ static inline bool uclamp_is_used(void)
|
||||
return static_branch_likely(&sched_uclamp_used);
|
||||
}
|
||||
#else /* CONFIG_UCLAMP_TASK */
|
||||
static inline unsigned long uclamp_eff_value(struct task_struct *p,
|
||||
enum uclamp_id clamp_id)
|
||||
{
|
||||
if (clamp_id == UCLAMP_MIN)
|
||||
return 0;
|
||||
|
||||
return SCHED_CAPACITY_SCALE;
|
||||
}
|
||||
|
||||
static inline
|
||||
unsigned long uclamp_rq_util_with(struct rq *rq, unsigned long util,
|
||||
struct task_struct *p)
|
||||
@ -2545,6 +2572,25 @@ static inline bool uclamp_is_used(void)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline unsigned long uclamp_rq_get(struct rq *rq,
|
||||
enum uclamp_id clamp_id)
|
||||
{
|
||||
if (clamp_id == UCLAMP_MIN)
|
||||
return 0;
|
||||
|
||||
return SCHED_CAPACITY_SCALE;
|
||||
}
|
||||
|
||||
static inline void uclamp_rq_set(struct rq *rq, enum uclamp_id clamp_id,
|
||||
unsigned int value)
|
||||
{
|
||||
}
|
||||
|
||||
static inline bool uclamp_rq_is_idle(struct rq *rq)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif /* CONFIG_UCLAMP_TASK */
|
||||
|
||||
#ifdef CONFIG_UCLAMP_TASK_GROUP
|
||||
@ -2579,6 +2625,24 @@ static inline unsigned long capacity_orig_of(int cpu)
|
||||
{
|
||||
return cpu_rq(cpu)->cpu_capacity_orig;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns inverted capacity if the CPU is in capacity inversion state.
|
||||
* 0 otherwise.
|
||||
*
|
||||
* Capacity inversion detection only considers thermal impact where actual
|
||||
* performance points (OPPs) gets dropped.
|
||||
*
|
||||
* Capacity inversion state happens when another performance domain that has
|
||||
* equal or lower capacity_orig_of() becomes effectively larger than the perf
|
||||
* domain this CPU belongs to due to thermal pressure throttling it hard.
|
||||
*
|
||||
* See comment in update_cpu_capacity().
|
||||
*/
|
||||
static inline unsigned long cpu_in_capacity_inversion(int cpu)
|
||||
{
|
||||
return cpu_rq(cpu)->cpu_capacity_inverted;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
69
kernel/sys.c
69
kernel/sys.c
@ -644,6 +644,7 @@ long __sys_setresuid(uid_t ruid, uid_t euid, uid_t suid)
|
||||
struct cred *new;
|
||||
int retval;
|
||||
kuid_t kruid, keuid, ksuid;
|
||||
bool ruid_new, euid_new, suid_new;
|
||||
|
||||
kruid = make_kuid(ns, ruid);
|
||||
keuid = make_kuid(ns, euid);
|
||||
@ -658,25 +659,29 @@ long __sys_setresuid(uid_t ruid, uid_t euid, uid_t suid)
|
||||
if ((suid != (uid_t) -1) && !uid_valid(ksuid))
|
||||
return -EINVAL;
|
||||
|
||||
old = current_cred();
|
||||
|
||||
/* check for no-op */
|
||||
if ((ruid == (uid_t) -1 || uid_eq(kruid, old->uid)) &&
|
||||
(euid == (uid_t) -1 || (uid_eq(keuid, old->euid) &&
|
||||
uid_eq(keuid, old->fsuid))) &&
|
||||
(suid == (uid_t) -1 || uid_eq(ksuid, old->suid)))
|
||||
return 0;
|
||||
|
||||
ruid_new = ruid != (uid_t) -1 && !uid_eq(kruid, old->uid) &&
|
||||
!uid_eq(kruid, old->euid) && !uid_eq(kruid, old->suid);
|
||||
euid_new = euid != (uid_t) -1 && !uid_eq(keuid, old->uid) &&
|
||||
!uid_eq(keuid, old->euid) && !uid_eq(keuid, old->suid);
|
||||
suid_new = suid != (uid_t) -1 && !uid_eq(ksuid, old->uid) &&
|
||||
!uid_eq(ksuid, old->euid) && !uid_eq(ksuid, old->suid);
|
||||
if ((ruid_new || euid_new || suid_new) &&
|
||||
!ns_capable_setid(old->user_ns, CAP_SETUID))
|
||||
return -EPERM;
|
||||
|
||||
new = prepare_creds();
|
||||
if (!new)
|
||||
return -ENOMEM;
|
||||
|
||||
old = current_cred();
|
||||
|
||||
retval = -EPERM;
|
||||
if (!ns_capable_setid(old->user_ns, CAP_SETUID)) {
|
||||
if (ruid != (uid_t) -1 && !uid_eq(kruid, old->uid) &&
|
||||
!uid_eq(kruid, old->euid) && !uid_eq(kruid, old->suid))
|
||||
goto error;
|
||||
if (euid != (uid_t) -1 && !uid_eq(keuid, old->uid) &&
|
||||
!uid_eq(keuid, old->euid) && !uid_eq(keuid, old->suid))
|
||||
goto error;
|
||||
if (suid != (uid_t) -1 && !uid_eq(ksuid, old->uid) &&
|
||||
!uid_eq(ksuid, old->euid) && !uid_eq(ksuid, old->suid))
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (ruid != (uid_t) -1) {
|
||||
new->uid = kruid;
|
||||
if (!uid_eq(kruid, old->uid)) {
|
||||
@ -736,6 +741,7 @@ long __sys_setresgid(gid_t rgid, gid_t egid, gid_t sgid)
|
||||
struct cred *new;
|
||||
int retval;
|
||||
kgid_t krgid, kegid, ksgid;
|
||||
bool rgid_new, egid_new, sgid_new;
|
||||
|
||||
krgid = make_kgid(ns, rgid);
|
||||
kegid = make_kgid(ns, egid);
|
||||
@ -748,23 +754,28 @@ long __sys_setresgid(gid_t rgid, gid_t egid, gid_t sgid)
|
||||
if ((sgid != (gid_t) -1) && !gid_valid(ksgid))
|
||||
return -EINVAL;
|
||||
|
||||
old = current_cred();
|
||||
|
||||
/* check for no-op */
|
||||
if ((rgid == (gid_t) -1 || gid_eq(krgid, old->gid)) &&
|
||||
(egid == (gid_t) -1 || (gid_eq(kegid, old->egid) &&
|
||||
gid_eq(kegid, old->fsgid))) &&
|
||||
(sgid == (gid_t) -1 || gid_eq(ksgid, old->sgid)))
|
||||
return 0;
|
||||
|
||||
rgid_new = rgid != (gid_t) -1 && !gid_eq(krgid, old->gid) &&
|
||||
!gid_eq(krgid, old->egid) && !gid_eq(krgid, old->sgid);
|
||||
egid_new = egid != (gid_t) -1 && !gid_eq(kegid, old->gid) &&
|
||||
!gid_eq(kegid, old->egid) && !gid_eq(kegid, old->sgid);
|
||||
sgid_new = sgid != (gid_t) -1 && !gid_eq(ksgid, old->gid) &&
|
||||
!gid_eq(ksgid, old->egid) && !gid_eq(ksgid, old->sgid);
|
||||
if ((rgid_new || egid_new || sgid_new) &&
|
||||
!ns_capable_setid(old->user_ns, CAP_SETGID))
|
||||
return -EPERM;
|
||||
|
||||
new = prepare_creds();
|
||||
if (!new)
|
||||
return -ENOMEM;
|
||||
old = current_cred();
|
||||
|
||||
retval = -EPERM;
|
||||
if (!ns_capable_setid(old->user_ns, CAP_SETGID)) {
|
||||
if (rgid != (gid_t) -1 && !gid_eq(krgid, old->gid) &&
|
||||
!gid_eq(krgid, old->egid) && !gid_eq(krgid, old->sgid))
|
||||
goto error;
|
||||
if (egid != (gid_t) -1 && !gid_eq(kegid, old->gid) &&
|
||||
!gid_eq(kegid, old->egid) && !gid_eq(kegid, old->sgid))
|
||||
goto error;
|
||||
if (sgid != (gid_t) -1 && !gid_eq(ksgid, old->gid) &&
|
||||
!gid_eq(ksgid, old->egid) && !gid_eq(ksgid, old->sgid))
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (rgid != (gid_t) -1)
|
||||
new->gid = krgid;
|
||||
|
@ -623,6 +623,10 @@ static int __collapse_huge_page_isolate(struct vm_area_struct *vma,
|
||||
result = SCAN_PTE_NON_PRESENT;
|
||||
goto out;
|
||||
}
|
||||
if (pte_uffd_wp(pteval)) {
|
||||
result = SCAN_PTE_UFFD_WP;
|
||||
goto out;
|
||||
}
|
||||
page = vm_normal_page(vma, address, pteval);
|
||||
if (unlikely(!page)) {
|
||||
result = SCAN_PAGE_NULL;
|
||||
|
@ -868,12 +868,17 @@ static unsigned int ip_sabotage_in(void *priv,
|
||||
{
|
||||
struct nf_bridge_info *nf_bridge = nf_bridge_info_get(skb);
|
||||
|
||||
if (nf_bridge && !nf_bridge->in_prerouting &&
|
||||
!netif_is_l3_master(skb->dev) &&
|
||||
!netif_is_l3_slave(skb->dev)) {
|
||||
nf_bridge_info_free(skb);
|
||||
state->okfn(state->net, state->sk, skb);
|
||||
return NF_STOLEN;
|
||||
if (nf_bridge) {
|
||||
if (nf_bridge->sabotage_in_done)
|
||||
return NF_ACCEPT;
|
||||
|
||||
if (!nf_bridge->in_prerouting &&
|
||||
!netif_is_l3_master(skb->dev) &&
|
||||
!netif_is_l3_slave(skb->dev)) {
|
||||
nf_bridge->sabotage_in_done = 1;
|
||||
state->okfn(state->net, state->sk, skb);
|
||||
return NF_STOLEN;
|
||||
}
|
||||
}
|
||||
|
||||
return NF_ACCEPT;
|
||||
|
@ -283,6 +283,7 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
|
||||
int dccp_rcv_established(struct sock *sk, struct sk_buff *skb,
|
||||
const struct dccp_hdr *dh, const unsigned int len);
|
||||
|
||||
void dccp_destruct_common(struct sock *sk);
|
||||
int dccp_init_sock(struct sock *sk, const __u8 ctl_sock_initialized);
|
||||
void dccp_destroy_sock(struct sock *sk);
|
||||
|
||||
|
@ -992,6 +992,12 @@ static const struct inet_connection_sock_af_ops dccp_ipv6_mapped = {
|
||||
.sockaddr_len = sizeof(struct sockaddr_in6),
|
||||
};
|
||||
|
||||
static void dccp_v6_sk_destruct(struct sock *sk)
|
||||
{
|
||||
dccp_destruct_common(sk);
|
||||
inet6_sock_destruct(sk);
|
||||
}
|
||||
|
||||
/* NOTE: A lot of things set to zero explicitly by call to
|
||||
* sk_alloc() so need not be done here.
|
||||
*/
|
||||
@ -1004,17 +1010,12 @@ static int dccp_v6_init_sock(struct sock *sk)
|
||||
if (unlikely(!dccp_v6_ctl_sock_initialized))
|
||||
dccp_v6_ctl_sock_initialized = 1;
|
||||
inet_csk(sk)->icsk_af_ops = &dccp_ipv6_af_ops;
|
||||
sk->sk_destruct = dccp_v6_sk_destruct;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static void dccp_v6_destroy_sock(struct sock *sk)
|
||||
{
|
||||
dccp_destroy_sock(sk);
|
||||
inet6_destroy_sock(sk);
|
||||
}
|
||||
|
||||
static struct timewait_sock_ops dccp6_timewait_sock_ops = {
|
||||
.twsk_obj_size = sizeof(struct dccp6_timewait_sock),
|
||||
};
|
||||
@ -1037,7 +1038,7 @@ static struct proto dccp_v6_prot = {
|
||||
.accept = inet_csk_accept,
|
||||
.get_port = inet_csk_get_port,
|
||||
.shutdown = dccp_shutdown,
|
||||
.destroy = dccp_v6_destroy_sock,
|
||||
.destroy = dccp_destroy_sock,
|
||||
.orphan_count = &dccp_orphan_count,
|
||||
.max_header = MAX_DCCP_HEADER,
|
||||
.obj_size = sizeof(struct dccp6_sock),
|
||||
|
@ -171,12 +171,18 @@ const char *dccp_packet_name(const int type)
|
||||
|
||||
EXPORT_SYMBOL_GPL(dccp_packet_name);
|
||||
|
||||
static void dccp_sk_destruct(struct sock *sk)
|
||||
void dccp_destruct_common(struct sock *sk)
|
||||
{
|
||||
struct dccp_sock *dp = dccp_sk(sk);
|
||||
|
||||
ccid_hc_tx_delete(dp->dccps_hc_tx_ccid, sk);
|
||||
dp->dccps_hc_tx_ccid = NULL;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(dccp_destruct_common);
|
||||
|
||||
static void dccp_sk_destruct(struct sock *sk)
|
||||
{
|
||||
dccp_destruct_common(sk);
|
||||
inet_sock_destruct(sk);
|
||||
}
|
||||
|
||||
|
@ -1584,7 +1584,7 @@ int __udp_enqueue_schedule_skb(struct sock *sk, struct sk_buff *skb)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(__udp_enqueue_schedule_skb);
|
||||
|
||||
void udp_destruct_sock(struct sock *sk)
|
||||
void udp_destruct_common(struct sock *sk)
|
||||
{
|
||||
/* reclaim completely the forward allocated memory */
|
||||
struct udp_sock *up = udp_sk(sk);
|
||||
@ -1597,10 +1597,14 @@ void udp_destruct_sock(struct sock *sk)
|
||||
kfree_skb(skb);
|
||||
}
|
||||
udp_rmem_release(sk, total, 0, true);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(udp_destruct_common);
|
||||
|
||||
static void udp_destruct_sock(struct sock *sk)
|
||||
{
|
||||
udp_destruct_common(sk);
|
||||
inet_sock_destruct(sk);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(udp_destruct_sock);
|
||||
|
||||
int udp_init_sock(struct sock *sk)
|
||||
{
|
||||
@ -1608,7 +1612,6 @@ int udp_init_sock(struct sock *sk)
|
||||
sk->sk_destruct = udp_destruct_sock;
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(udp_init_sock);
|
||||
|
||||
void skb_consume_udp(struct sock *sk, struct sk_buff *skb, int len)
|
||||
{
|
||||
|
@ -17,6 +17,14 @@
|
||||
struct udp_table udplite_table __read_mostly;
|
||||
EXPORT_SYMBOL(udplite_table);
|
||||
|
||||
/* Designate sk as UDP-Lite socket */
|
||||
static int udplite_sk_init(struct sock *sk)
|
||||
{
|
||||
udp_init_sock(sk);
|
||||
udp_sk(sk)->pcflag = UDPLITE_BIT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int udplite_rcv(struct sk_buff *skb)
|
||||
{
|
||||
return __udp4_lib_rcv(skb, &udplite_table, IPPROTO_UDPLITE);
|
||||
|
@ -107,6 +107,13 @@ static __inline__ struct ipv6_pinfo *inet6_sk_generic(struct sock *sk)
|
||||
return (struct ipv6_pinfo *)(((u8 *)sk) + offset);
|
||||
}
|
||||
|
||||
void inet6_sock_destruct(struct sock *sk)
|
||||
{
|
||||
inet6_cleanup_sock(sk);
|
||||
inet_sock_destruct(sk);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(inet6_sock_destruct);
|
||||
|
||||
static int inet6_create(struct net *net, struct socket *sock, int protocol,
|
||||
int kern)
|
||||
{
|
||||
@ -199,7 +206,7 @@ static int inet6_create(struct net *net, struct socket *sock, int protocol,
|
||||
inet->hdrincl = 1;
|
||||
}
|
||||
|
||||
sk->sk_destruct = inet_sock_destruct;
|
||||
sk->sk_destruct = inet6_sock_destruct;
|
||||
sk->sk_family = PF_INET6;
|
||||
sk->sk_protocol = protocol;
|
||||
|
||||
@ -505,6 +512,12 @@ void inet6_destroy_sock(struct sock *sk)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(inet6_destroy_sock);
|
||||
|
||||
void inet6_cleanup_sock(struct sock *sk)
|
||||
{
|
||||
inet6_destroy_sock(sk);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(inet6_cleanup_sock);
|
||||
|
||||
/*
|
||||
* This does both peername and sockname.
|
||||
*/
|
||||
|
@ -429,9 +429,6 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
|
||||
if (optlen < sizeof(int))
|
||||
goto e_inval;
|
||||
if (val == PF_INET) {
|
||||
struct ipv6_txoptions *opt;
|
||||
struct sk_buff *pktopt;
|
||||
|
||||
if (sk->sk_type == SOCK_RAW)
|
||||
break;
|
||||
|
||||
@ -462,7 +459,6 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
|
||||
break;
|
||||
}
|
||||
|
||||
fl6_free_socklist(sk);
|
||||
__ipv6_sock_mc_close(sk);
|
||||
__ipv6_sock_ac_close(sk);
|
||||
|
||||
@ -497,14 +493,14 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
|
||||
sk->sk_socket->ops = &inet_dgram_ops;
|
||||
sk->sk_family = PF_INET;
|
||||
}
|
||||
opt = xchg((__force struct ipv6_txoptions **)&np->opt,
|
||||
NULL);
|
||||
if (opt) {
|
||||
atomic_sub(opt->tot_len, &sk->sk_omem_alloc);
|
||||
txopt_put(opt);
|
||||
}
|
||||
pktopt = xchg(&np->pktoptions, NULL);
|
||||
kfree_skb(pktopt);
|
||||
|
||||
/* Disable all options not to allocate memory anymore,
|
||||
* but there is still a race. See the lockless path
|
||||
* in udpv6_sendmsg() and ipv6_local_rxpmtu().
|
||||
*/
|
||||
np->rxopt.all = 0;
|
||||
|
||||
inet6_cleanup_sock(sk);
|
||||
|
||||
/*
|
||||
* ... and add it to the refcnt debug socks count
|
||||
|
@ -22,11 +22,6 @@
|
||||
#include <linux/proc_fs.h>
|
||||
#include <net/ping.h>
|
||||
|
||||
static void ping_v6_destroy(struct sock *sk)
|
||||
{
|
||||
inet6_destroy_sock(sk);
|
||||
}
|
||||
|
||||
/* Compatibility glue so we can support IPv6 when it's compiled as a module */
|
||||
static int dummy_ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len,
|
||||
int *addr_len)
|
||||
@ -171,7 +166,6 @@ struct proto pingv6_prot = {
|
||||
.owner = THIS_MODULE,
|
||||
.init = ping_init_sock,
|
||||
.close = ping_close,
|
||||
.destroy = ping_v6_destroy,
|
||||
.connect = ip6_datagram_connect_v6_only,
|
||||
.disconnect = __udp_disconnect,
|
||||
.setsockopt = ipv6_setsockopt,
|
||||
|
@ -1211,8 +1211,6 @@ static void raw6_destroy(struct sock *sk)
|
||||
lock_sock(sk);
|
||||
ip6_flush_pending_frames(sk);
|
||||
release_sock(sk);
|
||||
|
||||
inet6_destroy_sock(sk);
|
||||
}
|
||||
|
||||
static int rawv6_init_sk(struct sock *sk)
|
||||
|
@ -32,7 +32,8 @@ static void *ipv6_rpl_segdata_pos(const struct ipv6_rpl_sr_hdr *hdr, int i)
|
||||
size_t ipv6_rpl_srh_size(unsigned char n, unsigned char cmpri,
|
||||
unsigned char cmpre)
|
||||
{
|
||||
return (n * IPV6_PFXTAIL_LEN(cmpri)) + IPV6_PFXTAIL_LEN(cmpre);
|
||||
return sizeof(struct ipv6_rpl_sr_hdr) + (n * IPV6_PFXTAIL_LEN(cmpri)) +
|
||||
IPV6_PFXTAIL_LEN(cmpre);
|
||||
}
|
||||
|
||||
void ipv6_rpl_srh_decompress(struct ipv6_rpl_sr_hdr *outhdr,
|
||||
|
@ -1936,12 +1936,6 @@ static int tcp_v6_init_sock(struct sock *sk)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void tcp_v6_destroy_sock(struct sock *sk)
|
||||
{
|
||||
tcp_v4_destroy_sock(sk);
|
||||
inet6_destroy_sock(sk);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PROC_FS
|
||||
/* Proc filesystem TCPv6 sock list dumping. */
|
||||
static void get_openreq6(struct seq_file *seq,
|
||||
@ -2134,7 +2128,7 @@ struct proto tcpv6_prot = {
|
||||
.accept = inet_csk_accept,
|
||||
.ioctl = tcp_ioctl,
|
||||
.init = tcp_v6_init_sock,
|
||||
.destroy = tcp_v6_destroy_sock,
|
||||
.destroy = tcp_v4_destroy_sock,
|
||||
.shutdown = tcp_shutdown,
|
||||
.setsockopt = tcp_setsockopt,
|
||||
.getsockopt = tcp_getsockopt,
|
||||
|
@ -54,6 +54,19 @@
|
||||
#include <trace/events/skb.h>
|
||||
#include "udp_impl.h"
|
||||
|
||||
static void udpv6_destruct_sock(struct sock *sk)
|
||||
{
|
||||
udp_destruct_common(sk);
|
||||
inet6_sock_destruct(sk);
|
||||
}
|
||||
|
||||
int udpv6_init_sock(struct sock *sk)
|
||||
{
|
||||
skb_queue_head_init(&udp_sk(sk)->reader_queue);
|
||||
sk->sk_destruct = udpv6_destruct_sock;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u32 udp6_ehashfn(const struct net *net,
|
||||
const struct in6_addr *laddr,
|
||||
const u16 lport,
|
||||
@ -1617,8 +1630,6 @@ void udpv6_destroy_sock(struct sock *sk)
|
||||
udp_encap_disable();
|
||||
}
|
||||
}
|
||||
|
||||
inet6_destroy_sock(sk);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1702,7 +1713,7 @@ struct proto udpv6_prot = {
|
||||
.connect = ip6_datagram_connect,
|
||||
.disconnect = udp_disconnect,
|
||||
.ioctl = udp_ioctl,
|
||||
.init = udp_init_sock,
|
||||
.init = udpv6_init_sock,
|
||||
.destroy = udpv6_destroy_sock,
|
||||
.setsockopt = udpv6_setsockopt,
|
||||
.getsockopt = udpv6_getsockopt,
|
||||
|
@ -12,6 +12,7 @@ int __udp6_lib_rcv(struct sk_buff *, struct udp_table *, int);
|
||||
int __udp6_lib_err(struct sk_buff *, struct inet6_skb_parm *, u8, u8, int,
|
||||
__be32, struct udp_table *);
|
||||
|
||||
int udpv6_init_sock(struct sock *sk);
|
||||
int udp_v6_get_port(struct sock *sk, unsigned short snum);
|
||||
void udp_v6_rehash(struct sock *sk);
|
||||
|
||||
|
@ -12,6 +12,13 @@
|
||||
#include <linux/proc_fs.h>
|
||||
#include "udp_impl.h"
|
||||
|
||||
static int udplitev6_sk_init(struct sock *sk)
|
||||
{
|
||||
udpv6_init_sock(sk);
|
||||
udp_sk(sk)->pcflag = UDPLITE_BIT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int udplitev6_rcv(struct sk_buff *skb)
|
||||
{
|
||||
return __udp6_lib_rcv(skb, &udplite_table, IPPROTO_UDPLITE);
|
||||
@ -38,7 +45,7 @@ struct proto udplitev6_prot = {
|
||||
.connect = ip6_datagram_connect,
|
||||
.disconnect = udp_disconnect,
|
||||
.ioctl = udp_ioctl,
|
||||
.init = udplite_sk_init,
|
||||
.init = udplitev6_sk_init,
|
||||
.destroy = udpv6_destroy_sock,
|
||||
.setsockopt = udpv6_setsockopt,
|
||||
.getsockopt = udpv6_getsockopt,
|
||||
|
@ -255,8 +255,6 @@ static void l2tp_ip6_destroy_sock(struct sock *sk)
|
||||
|
||||
if (tunnel)
|
||||
l2tp_tunnel_delete(tunnel);
|
||||
|
||||
inet6_destroy_sock(sk);
|
||||
}
|
||||
|
||||
static int l2tp_ip6_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len)
|
||||
|
@ -2863,12 +2863,6 @@ static const struct proto_ops mptcp_v6_stream_ops = {
|
||||
|
||||
static struct proto mptcp_v6_prot;
|
||||
|
||||
static void mptcp_v6_destroy(struct sock *sk)
|
||||
{
|
||||
mptcp_destroy(sk);
|
||||
inet6_destroy_sock(sk);
|
||||
}
|
||||
|
||||
static struct inet_protosw mptcp_v6_protosw = {
|
||||
.type = SOCK_STREAM,
|
||||
.protocol = IPPROTO_MPTCP,
|
||||
@ -2884,7 +2878,6 @@ int __init mptcp_proto_v6_init(void)
|
||||
mptcp_v6_prot = mptcp_prot;
|
||||
strcpy(mptcp_v6_prot.name, "MPTCPv6");
|
||||
mptcp_v6_prot.slab = NULL;
|
||||
mptcp_v6_prot.destroy = mptcp_v6_destroy;
|
||||
mptcp_v6_prot.obj_size = sizeof(struct mptcp6_sock);
|
||||
|
||||
err = proto_register(&mptcp_v6_prot, 1);
|
||||
|
@ -421,15 +421,16 @@ static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
|
||||
} else
|
||||
weight = 1;
|
||||
|
||||
if (tb[TCA_QFQ_LMAX]) {
|
||||
if (tb[TCA_QFQ_LMAX])
|
||||
lmax = nla_get_u32(tb[TCA_QFQ_LMAX]);
|
||||
if (lmax < QFQ_MIN_LMAX || lmax > (1UL << QFQ_MTU_SHIFT)) {
|
||||
pr_notice("qfq: invalid max length %u\n", lmax);
|
||||
return -EINVAL;
|
||||
}
|
||||
} else
|
||||
else
|
||||
lmax = psched_mtu(qdisc_dev(sch));
|
||||
|
||||
if (lmax < QFQ_MIN_LMAX || lmax > (1UL << QFQ_MTU_SHIFT)) {
|
||||
pr_notice("qfq: invalid max length %u\n", lmax);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
inv_w = ONE_FP / weight;
|
||||
weight = ONE_FP / inv_w;
|
||||
|
||||
|
@ -5000,13 +5000,17 @@ static void sctp_destroy_sock(struct sock *sk)
|
||||
}
|
||||
|
||||
/* Triggered when there are no references on the socket anymore */
|
||||
static void sctp_destruct_sock(struct sock *sk)
|
||||
static void sctp_destruct_common(struct sock *sk)
|
||||
{
|
||||
struct sctp_sock *sp = sctp_sk(sk);
|
||||
|
||||
/* Free up the HMAC transform. */
|
||||
crypto_free_shash(sp->hmac);
|
||||
}
|
||||
|
||||
static void sctp_destruct_sock(struct sock *sk)
|
||||
{
|
||||
sctp_destruct_common(sk);
|
||||
inet_sock_destruct(sk);
|
||||
}
|
||||
|
||||
@ -9200,7 +9204,7 @@ void sctp_copy_sock(struct sock *newsk, struct sock *sk,
|
||||
sctp_sk(newsk)->reuse = sp->reuse;
|
||||
|
||||
newsk->sk_shutdown = sk->sk_shutdown;
|
||||
newsk->sk_destruct = sctp_destruct_sock;
|
||||
newsk->sk_destruct = sk->sk_destruct;
|
||||
newsk->sk_family = sk->sk_family;
|
||||
newsk->sk_protocol = IPPROTO_SCTP;
|
||||
newsk->sk_backlog_rcv = sk->sk_prot->backlog_rcv;
|
||||
@ -9432,11 +9436,20 @@ struct proto sctp_prot = {
|
||||
|
||||
#if IS_ENABLED(CONFIG_IPV6)
|
||||
|
||||
#include <net/transp_v6.h>
|
||||
static void sctp_v6_destroy_sock(struct sock *sk)
|
||||
static void sctp_v6_destruct_sock(struct sock *sk)
|
||||
{
|
||||
sctp_destroy_sock(sk);
|
||||
inet6_destroy_sock(sk);
|
||||
sctp_destruct_common(sk);
|
||||
inet6_sock_destruct(sk);
|
||||
}
|
||||
|
||||
static int sctp_v6_init_sock(struct sock *sk)
|
||||
{
|
||||
int ret = sctp_init_sock(sk);
|
||||
|
||||
if (!ret)
|
||||
sk->sk_destruct = sctp_v6_destruct_sock;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct proto sctpv6_prot = {
|
||||
@ -9446,8 +9459,8 @@ struct proto sctpv6_prot = {
|
||||
.disconnect = sctp_disconnect,
|
||||
.accept = sctp_accept,
|
||||
.ioctl = sctp_ioctl,
|
||||
.init = sctp_init_sock,
|
||||
.destroy = sctp_v6_destroy_sock,
|
||||
.init = sctp_v6_init_sock,
|
||||
.destroy = sctp_destroy_sock,
|
||||
.shutdown = sctp_shutdown,
|
||||
.setsockopt = sctp_setsockopt,
|
||||
.getsockopt = sctp_getsockopt,
|
||||
|
@ -625,7 +625,7 @@ int main(int argc, char **argv)
|
||||
p = strrchr(argv[1], '/');
|
||||
p = p ? p + 1 : argv[1];
|
||||
grammar_name = strdup(p);
|
||||
if (!p) {
|
||||
if (!grammar_name) {
|
||||
perror(NULL);
|
||||
exit(1);
|
||||
}
|
||||
|
@ -207,14 +207,19 @@ static int fsl_asrc_dma_hw_params(struct snd_soc_component *component,
|
||||
be_chan = soc_component_to_pcm(component_be)->chan[substream->stream];
|
||||
tmp_chan = be_chan;
|
||||
}
|
||||
if (!tmp_chan)
|
||||
tmp_chan = dma_request_slave_channel(dev_be, tx ? "tx" : "rx");
|
||||
if (!tmp_chan) {
|
||||
tmp_chan = dma_request_chan(dev_be, tx ? "tx" : "rx");
|
||||
if (IS_ERR(tmp_chan)) {
|
||||
dev_err(dev, "failed to request DMA channel for Back-End\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* An EDMA DEV_TO_DEV channel is fixed and bound with DMA event of each
|
||||
* peripheral, unlike SDMA channel that is allocated dynamically. So no
|
||||
* need to configure dma_request and dma_request2, but get dma_chan of
|
||||
* Back-End device directly via dma_request_slave_channel.
|
||||
* Back-End device directly via dma_request_chan.
|
||||
*/
|
||||
if (!asrc->use_edma) {
|
||||
/* Get DMA request of Back-End */
|
||||
|
23
tools/testing/selftests/sigaltstack/current_stack_pointer.h
Normal file
23
tools/testing/selftests/sigaltstack/current_stack_pointer.h
Normal file
@ -0,0 +1,23 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
|
||||
#if __alpha__
|
||||
register unsigned long sp asm("$30");
|
||||
#elif __arm__ || __aarch64__ || __csky__ || __m68k__ || __mips__ || __riscv
|
||||
register unsigned long sp asm("sp");
|
||||
#elif __i386__
|
||||
register unsigned long sp asm("esp");
|
||||
#elif __loongarch64
|
||||
register unsigned long sp asm("$sp");
|
||||
#elif __ppc__
|
||||
register unsigned long sp asm("r1");
|
||||
#elif __s390x__
|
||||
register unsigned long sp asm("%15");
|
||||
#elif __sh__
|
||||
register unsigned long sp asm("r15");
|
||||
#elif __x86_64__
|
||||
register unsigned long sp asm("rsp");
|
||||
#elif __XTENSA__
|
||||
register unsigned long sp asm("a1");
|
||||
#else
|
||||
#error "implement current_stack_pointer equivalent"
|
||||
#endif
|
@ -19,6 +19,7 @@
|
||||
#include <errno.h>
|
||||
|
||||
#include "../kselftest.h"
|
||||
#include "current_stack_pointer.h"
|
||||
|
||||
#ifndef SS_AUTODISARM
|
||||
#define SS_AUTODISARM (1U << 31)
|
||||
@ -40,12 +41,6 @@ void my_usr1(int sig, siginfo_t *si, void *u)
|
||||
stack_t stk;
|
||||
struct stk_data *p;
|
||||
|
||||
#if __s390x__
|
||||
register unsigned long sp asm("%15");
|
||||
#else
|
||||
register unsigned long sp asm("sp");
|
||||
#endif
|
||||
|
||||
if (sp < (unsigned long)sstack ||
|
||||
sp >= (unsigned long)sstack + SIGSTKSZ) {
|
||||
ksft_exit_fail_msg("SP is not on sigaltstack\n");
|
||||
|
Loading…
Reference in New Issue
Block a user