This is the 5.4.254 stable release
-----BEGIN PGP SIGNATURE-----
iQIzBAABCAAdFiEEZH8oZUiU471FcZm+ONu9yGCSaT4FAmTc9xQACgkQONu9yGCS
aT4VrQ//aeDhl35R4kgB8ZYcv2EHa9DgE+cDkFYIUruQ029jPET1NkMuXMiWys2K
trzC5VCAawfac8jHR4kAetP2W6ydHgSQprtUxjgjIwKlPgiFQOla5/DXNqMGTv9Y
fFKcIfgpef9OkvPr46LHf1S4i3H8vaVu3pN40gEnIAPu4Rgz3wvbmi6BoSTszThI
MrbOu70iRxVxF8+3HR8G3Ja6bly4dTl2Y36P6G+JPAQc8+X9RT1Yv39kiAg7TSzP
i/SIn2G5pNu2+BMcxUn0SO13YXPYIGQTZ6xLX13QIDEuoqQRjDB9vZPaKoSm7170
Nh1JjvUXy72/zvDJYJWzbrL/o4AfS2tHBNTUq5loXO4LPvbmg18g3Xysuk6vRBmG
NjOpbG9PK3MCwWEQIdEAgtFF6hw74MF/UM7b1Tty3FAaWf4Ca75vY5acqSy4Fhbx
KuBnNGZTaRJRCUFeEBtAz8sIeFCclfuSpBhrQzj8zCkDT59PuiWJ7wyW1yAizMtE
VNvDJFxdQXtU06AHWJxp9msWiXYBZbFfk75MVTxnZLS3SDJuJ40fDjjGCM4WciMg
gBLS+v4tO67KEuhj8t50WJW4Kk7P1Q0j3QkItHOMMRpsJQZF3z8rqEqthAacEaAH
hVvB2OxpXicqpHwrFW3DZuxzgfJd6sofaKq85/2I7FullRyXVjg=
=6G08
-----END PGP SIGNATURE-----
Merge 5.4.254 into android11-5.4-lts
Changes in 5.4.254
mmc: moxart: read scr register without changing byte order
ipv6: adjust ndisc_is_useropt() to also return true for PIO
dmaengine: pl330: Return DMA_PAUSED when transaction is paused
drm/nouveau/gr: enable memory loads on helper invocation on all channels
radix tree test suite: fix incorrect allocation size for pthreads
x86/pkeys: Revert a5eff72597
("x86/pkeys: Add PKRU value to init_fpstate")
nilfs2: fix use-after-free of nilfs_root in dirtying inodes via iput
iio: cros_ec: Fix the allocation size for cros_ec_command
binder: fix memory leak in binder_init()
usb-storage: alauda: Fix uninit-value in alauda_check_media()
usb: dwc3: Properly handle processing of pending events
usb: common: usb-conn-gpio: Prevent bailing out if initial role is none
x86/cpu/amd: Enable Zenbleed fix for AMD Custom APU 0405
x86/mm: Fix VDSO and VVAR placement on 5-level paging machines
x86: Move gds_ucode_mitigated() declaration to header
drm/nouveau/disp: Revert a NULL check inside nouveau_connector_get_modes
selftests/rseq: Fix build with undefined __weak
mISDN: Update parameter type of dsp_cmx_send()
net/packet: annotate data-races around tp->status
bonding: Fix incorrect deletion of ETH_P_8021AD protocol vid from slaves
dccp: fix data-race around dp->dccps_mss_cache
drivers: net: prevent tun_build_skb() to exceed the packet size limit
IB/hfi1: Fix possible panic during hotplug remove
wifi: cfg80211: fix sband iftype data lookup for AP_VLAN
dmaengine: mcf-edma: Fix a potential un-allocated memory access
net/mlx5: Allow 0 for total host VFs
ibmvnic: Handle DMA unmapping of login buffs in release functions
btrfs: don't stop integrity writeback too early
btrfs: set cache_block_group_error if we find an error
nvme-tcp: fix potential unbalanced freeze & unfreeze
nvme-rdma: fix potential unbalanced freeze & unfreeze
netfilter: nf_tables: report use refcount overflow
scsi: core: Fix legacy /proc parsing buffer overflow
scsi: storvsc: Fix handling of virtual Fibre Channel timeouts
scsi: 53c700: Check that command slot is not NULL
scsi: snic: Fix possible memory leak if device_add() fails
scsi: core: Fix possible memory leak if device_add() fails
alpha: remove __init annotation from exported page_is_ram()
sch_netem: fix issues in netem_change() vs get_dist_table()
Linux 5.4.254
Change-Id: I187a81acd36ef0ec486a959c626f1f06373170cc
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
commit
38b412a16c
2
Makefile
2
Makefile
@ -1,7 +1,7 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
VERSION = 5
|
||||
PATCHLEVEL = 4
|
||||
SUBLEVEL = 253
|
||||
SUBLEVEL = 254
|
||||
EXTRAVERSION =
|
||||
NAME = Kleptomaniac Octopus
|
||||
|
||||
|
@ -394,8 +394,7 @@ setup_memory(void *kernel_end)
|
||||
extern void setup_memory(void *);
|
||||
#endif /* !CONFIG_DISCONTIGMEM */
|
||||
|
||||
int __init
|
||||
page_is_ram(unsigned long pfn)
|
||||
int page_is_ram(unsigned long pfn)
|
||||
{
|
||||
struct memclust_struct * cluster;
|
||||
struct memdesc_struct * memdesc;
|
||||
|
@ -222,8 +222,8 @@ static unsigned long vdso_addr(unsigned long start, unsigned len)
|
||||
|
||||
/* Round the lowest possible end address up to a PMD boundary. */
|
||||
end = (start + len + PMD_SIZE - 1) & PMD_MASK;
|
||||
if (end >= TASK_SIZE_MAX)
|
||||
end = TASK_SIZE_MAX;
|
||||
if (end >= DEFAULT_MAP_WINDOW)
|
||||
end = DEFAULT_MAP_WINDOW;
|
||||
end -= len;
|
||||
|
||||
if (end > start) {
|
||||
|
@ -976,4 +976,6 @@ enum taa_mitigations {
|
||||
TAA_MITIGATION_TSX_DISABLED,
|
||||
};
|
||||
|
||||
extern bool gds_ucode_mitigated(void);
|
||||
|
||||
#endif /* _ASM_X86_PROCESSOR_H */
|
||||
|
@ -72,6 +72,7 @@ static const int amd_erratum_1054[] =
|
||||
static const int amd_zenbleed[] =
|
||||
AMD_LEGACY_ERRATUM(AMD_MODEL_RANGE(0x17, 0x30, 0x0, 0x4f, 0xf),
|
||||
AMD_MODEL_RANGE(0x17, 0x60, 0x0, 0x7f, 0xf),
|
||||
AMD_MODEL_RANGE(0x17, 0x90, 0x0, 0x91, 0xf),
|
||||
AMD_MODEL_RANGE(0x17, 0xa0, 0x0, 0xaf, 0xf));
|
||||
|
||||
static bool cpu_has_amd_erratum(struct cpuinfo_x86 *cpu, const int *erratum)
|
||||
|
@ -450,8 +450,6 @@ static bool pku_disabled;
|
||||
|
||||
static __always_inline void setup_pku(struct cpuinfo_x86 *c)
|
||||
{
|
||||
struct pkru_state *pk;
|
||||
|
||||
/* check the boot processor, plus compile options for PKU: */
|
||||
if (!cpu_feature_enabled(X86_FEATURE_PKU))
|
||||
return;
|
||||
@ -462,9 +460,6 @@ static __always_inline void setup_pku(struct cpuinfo_x86 *c)
|
||||
return;
|
||||
|
||||
cr4_set_bits(X86_CR4_PKE);
|
||||
pk = get_xsave_addr(&init_fpstate.xsave, XFEATURE_PKRU);
|
||||
if (pk)
|
||||
pk->pkru = init_pkru_value;
|
||||
/*
|
||||
* Seting X86_CR4_PKE will cause the X86_FEATURE_OSPKE
|
||||
* cpuid bit to be set. We need to ensure that we
|
||||
|
@ -226,8 +226,6 @@ struct kvm_stats_debugfs_item debugfs_entries[] = {
|
||||
|
||||
u64 __read_mostly host_xcr0;
|
||||
|
||||
extern bool gds_ucode_mitigated(void);
|
||||
|
||||
struct kmem_cache *x86_fpu_cache;
|
||||
EXPORT_SYMBOL_GPL(x86_fpu_cache);
|
||||
|
||||
|
@ -10,7 +10,6 @@
|
||||
|
||||
#include <asm/cpufeature.h> /* boot_cpu_has, ... */
|
||||
#include <asm/mmu_context.h> /* vma_pkey() */
|
||||
#include <asm/fpu/internal.h> /* init_fpstate */
|
||||
|
||||
int __execute_only_pkey(struct mm_struct *mm)
|
||||
{
|
||||
@ -154,7 +153,6 @@ static ssize_t init_pkru_read_file(struct file *file, char __user *user_buf,
|
||||
static ssize_t init_pkru_write_file(struct file *file,
|
||||
const char __user *user_buf, size_t count, loff_t *ppos)
|
||||
{
|
||||
struct pkru_state *pk;
|
||||
char buf[32];
|
||||
ssize_t len;
|
||||
u32 new_init_pkru;
|
||||
@ -177,10 +175,6 @@ static ssize_t init_pkru_write_file(struct file *file,
|
||||
return -EINVAL;
|
||||
|
||||
WRITE_ONCE(init_pkru_value, new_init_pkru);
|
||||
pk = get_xsave_addr(&init_fpstate.xsave, XFEATURE_PKRU);
|
||||
if (!pk)
|
||||
return -EINVAL;
|
||||
pk->pkru = new_init_pkru;
|
||||
return count;
|
||||
}
|
||||
|
||||
|
@ -6545,6 +6545,7 @@ static int __init binder_init(void)
|
||||
|
||||
err_alloc_device_names_failed:
|
||||
debugfs_remove_recursive(binder_debugfs_dir_entry_root);
|
||||
binder_alloc_shrinker_exit();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -1086,6 +1086,12 @@ int binder_alloc_shrinker_init(void)
|
||||
return ret;
|
||||
}
|
||||
|
||||
void binder_alloc_shrinker_exit(void)
|
||||
{
|
||||
unregister_shrinker(&binder_shrinker);
|
||||
list_lru_destroy(&binder_alloc_lru);
|
||||
}
|
||||
|
||||
/**
|
||||
* check_buffer() - verify that buffer/offset is safe to access
|
||||
* @alloc: binder_alloc for this proc
|
||||
|
@ -125,6 +125,7 @@ extern struct binder_buffer *binder_alloc_new_buf(struct binder_alloc *alloc,
|
||||
int pid);
|
||||
extern void binder_alloc_init(struct binder_alloc *alloc);
|
||||
extern int binder_alloc_shrinker_init(void);
|
||||
extern void binder_alloc_shrinker_exit(void);
|
||||
extern void binder_alloc_vma_close(struct binder_alloc *alloc);
|
||||
extern struct binder_buffer *
|
||||
binder_alloc_prepare_to_free(struct binder_alloc *alloc,
|
||||
|
@ -191,7 +191,13 @@ static int mcf_edma_probe(struct platform_device *pdev)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
chans = pdata->dma_channels;
|
||||
if (!pdata->dma_channels) {
|
||||
dev_info(&pdev->dev, "setting default channel number to 64");
|
||||
chans = 64;
|
||||
} else {
|
||||
chans = pdata->dma_channels;
|
||||
}
|
||||
|
||||
len = sizeof(*mcf_edma) + sizeof(*mcf_chan) * chans;
|
||||
mcf_edma = devm_kzalloc(&pdev->dev, len, GFP_KERNEL);
|
||||
if (!mcf_edma)
|
||||
@ -203,11 +209,6 @@ static int mcf_edma_probe(struct platform_device *pdev)
|
||||
mcf_edma->drvdata = &mcf_data;
|
||||
mcf_edma->big_endian = 1;
|
||||
|
||||
if (!mcf_edma->n_chans) {
|
||||
dev_info(&pdev->dev, "setting default channel number to 64");
|
||||
mcf_edma->n_chans = 64;
|
||||
}
|
||||
|
||||
mutex_init(&mcf_edma->fsl_edma_mutex);
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
|
@ -402,6 +402,12 @@ enum desc_status {
|
||||
* of a channel can be BUSY at any time.
|
||||
*/
|
||||
BUSY,
|
||||
/*
|
||||
* Pause was called while descriptor was BUSY. Due to hardware
|
||||
* limitations, only termination is possible for descriptors
|
||||
* that have been paused.
|
||||
*/
|
||||
PAUSED,
|
||||
/*
|
||||
* Sitting on the channel work_list but xfer done
|
||||
* by PL330 core
|
||||
@ -2035,7 +2041,7 @@ static inline void fill_queue(struct dma_pl330_chan *pch)
|
||||
list_for_each_entry(desc, &pch->work_list, node) {
|
||||
|
||||
/* If already submitted */
|
||||
if (desc->status == BUSY)
|
||||
if (desc->status == BUSY || desc->status == PAUSED)
|
||||
continue;
|
||||
|
||||
ret = pl330_submit_req(pch->thread, desc);
|
||||
@ -2322,6 +2328,7 @@ static int pl330_pause(struct dma_chan *chan)
|
||||
{
|
||||
struct dma_pl330_chan *pch = to_pchan(chan);
|
||||
struct pl330_dmac *pl330 = pch->dmac;
|
||||
struct dma_pl330_desc *desc;
|
||||
unsigned long flags;
|
||||
|
||||
pm_runtime_get_sync(pl330->ddma.dev);
|
||||
@ -2331,6 +2338,10 @@ static int pl330_pause(struct dma_chan *chan)
|
||||
_stop(pch->thread);
|
||||
spin_unlock(&pl330->lock);
|
||||
|
||||
list_for_each_entry(desc, &pch->work_list, node) {
|
||||
if (desc->status == BUSY)
|
||||
desc->status = PAUSED;
|
||||
}
|
||||
spin_unlock_irqrestore(&pch->lock, flags);
|
||||
pm_runtime_mark_last_busy(pl330->ddma.dev);
|
||||
pm_runtime_put_autosuspend(pl330->ddma.dev);
|
||||
@ -2421,7 +2432,7 @@ pl330_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
|
||||
else if (running && desc == running)
|
||||
transferred =
|
||||
pl330_get_current_xferred_count(pch, desc);
|
||||
else if (desc->status == BUSY)
|
||||
else if (desc->status == BUSY || desc->status == PAUSED)
|
||||
/*
|
||||
* Busy but not running means either just enqueued,
|
||||
* or finished and not yet marked done
|
||||
@ -2438,6 +2449,9 @@ pl330_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
|
||||
case DONE:
|
||||
ret = DMA_COMPLETE;
|
||||
break;
|
||||
case PAUSED:
|
||||
ret = DMA_PAUSED;
|
||||
break;
|
||||
case PREP:
|
||||
case BUSY:
|
||||
ret = DMA_IN_PROGRESS;
|
||||
|
@ -955,7 +955,7 @@ nouveau_connector_get_modes(struct drm_connector *connector)
|
||||
/* Determine display colour depth for everything except LVDS now,
|
||||
* DP requires this before mode_valid() is called.
|
||||
*/
|
||||
if (connector->connector_type != DRM_MODE_CONNECTOR_LVDS && nv_connector->native_mode)
|
||||
if (connector->connector_type != DRM_MODE_CONNECTOR_LVDS)
|
||||
nouveau_connector_detect_depth(connector);
|
||||
|
||||
/* Find the native mode if this is a digital panel, if we didn't
|
||||
|
@ -121,6 +121,7 @@ void gk104_grctx_generate_r418800(struct gf100_gr *);
|
||||
|
||||
extern const struct gf100_grctx_func gk110_grctx;
|
||||
void gk110_grctx_generate_r419eb0(struct gf100_gr *);
|
||||
void gk110_grctx_generate_r419f78(struct gf100_gr *);
|
||||
|
||||
extern const struct gf100_grctx_func gk110b_grctx;
|
||||
extern const struct gf100_grctx_func gk208_grctx;
|
||||
|
@ -916,7 +916,9 @@ static void
|
||||
gk104_grctx_generate_r419f78(struct gf100_gr *gr)
|
||||
{
|
||||
struct nvkm_device *device = gr->base.engine.subdev.device;
|
||||
nvkm_mask(device, 0x419f78, 0x00000001, 0x00000000);
|
||||
|
||||
/* bit 3 set disables loads in fp helper invocations, we need it enabled */
|
||||
nvkm_mask(device, 0x419f78, 0x00000009, 0x00000000);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -820,6 +820,15 @@ gk110_grctx_generate_r419eb0(struct gf100_gr *gr)
|
||||
nvkm_mask(device, 0x419eb0, 0x00001000, 0x00001000);
|
||||
}
|
||||
|
||||
void
|
||||
gk110_grctx_generate_r419f78(struct gf100_gr *gr)
|
||||
{
|
||||
struct nvkm_device *device = gr->base.engine.subdev.device;
|
||||
|
||||
/* bit 3 set disables loads in fp helper invocations, we need it enabled */
|
||||
nvkm_mask(device, 0x419f78, 0x00000008, 0x00000000);
|
||||
}
|
||||
|
||||
const struct gf100_grctx_func
|
||||
gk110_grctx = {
|
||||
.main = gf100_grctx_generate_main,
|
||||
@ -852,4 +861,5 @@ gk110_grctx = {
|
||||
.gpc_tpc_nr = gk104_grctx_generate_gpc_tpc_nr,
|
||||
.r418800 = gk104_grctx_generate_r418800,
|
||||
.r419eb0 = gk110_grctx_generate_r419eb0,
|
||||
.r419f78 = gk110_grctx_generate_r419f78,
|
||||
};
|
||||
|
@ -101,4 +101,5 @@ gk110b_grctx = {
|
||||
.gpc_tpc_nr = gk104_grctx_generate_gpc_tpc_nr,
|
||||
.r418800 = gk104_grctx_generate_r418800,
|
||||
.r419eb0 = gk110_grctx_generate_r419eb0,
|
||||
.r419f78 = gk110_grctx_generate_r419f78,
|
||||
};
|
||||
|
@ -566,4 +566,5 @@ gk208_grctx = {
|
||||
.dist_skip_table = gf117_grctx_generate_dist_skip_table,
|
||||
.gpc_tpc_nr = gk104_grctx_generate_gpc_tpc_nr,
|
||||
.r418800 = gk104_grctx_generate_r418800,
|
||||
.r419f78 = gk110_grctx_generate_r419f78,
|
||||
};
|
||||
|
@ -991,4 +991,5 @@ gm107_grctx = {
|
||||
.r406500 = gm107_grctx_generate_r406500,
|
||||
.gpc_tpc_nr = gk104_grctx_generate_gpc_tpc_nr,
|
||||
.r419e00 = gm107_grctx_generate_r419e00,
|
||||
.r419f78 = gk110_grctx_generate_r419f78,
|
||||
};
|
||||
|
@ -99,7 +99,7 @@ int cros_ec_sensors_core_init(struct platform_device *pdev,
|
||||
platform_set_drvdata(pdev, indio_dev);
|
||||
|
||||
state->ec = ec->ec_dev;
|
||||
state->msg = devm_kzalloc(&pdev->dev,
|
||||
state->msg = devm_kzalloc(&pdev->dev, sizeof(*state->msg) +
|
||||
max((u16)sizeof(struct ec_params_motion_sense),
|
||||
state->ec->max_response), GFP_KERNEL);
|
||||
if (!state->msg)
|
||||
|
@ -12191,6 +12191,7 @@ static void free_cntrs(struct hfi1_devdata *dd)
|
||||
|
||||
if (dd->synth_stats_timer.function)
|
||||
del_timer_sync(&dd->synth_stats_timer);
|
||||
cancel_work_sync(&dd->update_cntr_work);
|
||||
ppd = (struct hfi1_pportdata *)(dd + 1);
|
||||
for (i = 0; i < dd->num_pports; i++, ppd++) {
|
||||
kfree(ppd->cntrs);
|
||||
|
@ -247,7 +247,7 @@ extern void dsp_cmx_hardware(struct dsp_conf *conf, struct dsp *dsp);
|
||||
extern int dsp_cmx_conf(struct dsp *dsp, u32 conf_id);
|
||||
extern void dsp_cmx_receive(struct dsp *dsp, struct sk_buff *skb);
|
||||
extern void dsp_cmx_hdlc(struct dsp *dsp, struct sk_buff *skb);
|
||||
extern void dsp_cmx_send(void *arg);
|
||||
extern void dsp_cmx_send(struct timer_list *arg);
|
||||
extern void dsp_cmx_transmit(struct dsp *dsp, struct sk_buff *skb);
|
||||
extern int dsp_cmx_del_conf_member(struct dsp *dsp);
|
||||
extern int dsp_cmx_del_conf(struct dsp_conf *conf);
|
||||
|
@ -1625,7 +1625,7 @@ static u16 dsp_count; /* last sample count */
|
||||
static int dsp_count_valid; /* if we have last sample count */
|
||||
|
||||
void
|
||||
dsp_cmx_send(void *arg)
|
||||
dsp_cmx_send(struct timer_list *arg)
|
||||
{
|
||||
struct dsp_conf *conf;
|
||||
struct dsp_conf_member *member;
|
||||
|
@ -1200,7 +1200,7 @@ static int __init dsp_init(void)
|
||||
}
|
||||
|
||||
/* set sample timer */
|
||||
timer_setup(&dsp_spl_tl, (void *)dsp_cmx_send, 0);
|
||||
timer_setup(&dsp_spl_tl, dsp_cmx_send, 0);
|
||||
dsp_spl_tl.expires = jiffies + dsp_tics;
|
||||
dsp_spl_jiffies = dsp_spl_tl.expires;
|
||||
add_timer(&dsp_spl_tl);
|
||||
|
@ -339,13 +339,7 @@ static void moxart_transfer_pio(struct moxart_host *host)
|
||||
return;
|
||||
}
|
||||
for (len = 0; len < remain && len < host->fifo_width;) {
|
||||
/* SCR data must be read in big endian. */
|
||||
if (data->mrq->cmd->opcode == SD_APP_SEND_SCR)
|
||||
*sgp = ioread32be(host->base +
|
||||
REG_DATA_WINDOW);
|
||||
else
|
||||
*sgp = ioread32(host->base +
|
||||
REG_DATA_WINDOW);
|
||||
*sgp = ioread32(host->base + REG_DATA_WINDOW);
|
||||
sgp++;
|
||||
len += 4;
|
||||
}
|
||||
|
@ -4451,7 +4451,9 @@ void bond_setup(struct net_device *bond_dev)
|
||||
|
||||
bond_dev->hw_features = BOND_VLAN_FEATURES |
|
||||
NETIF_F_HW_VLAN_CTAG_RX |
|
||||
NETIF_F_HW_VLAN_CTAG_FILTER;
|
||||
NETIF_F_HW_VLAN_CTAG_FILTER |
|
||||
NETIF_F_HW_VLAN_STAG_RX |
|
||||
NETIF_F_HW_VLAN_STAG_FILTER;
|
||||
|
||||
bond_dev->hw_features |= NETIF_F_GSO_ENCAP_ALL | NETIF_F_GSO_UDP_L4;
|
||||
bond_dev->features |= bond_dev->hw_features;
|
||||
|
@ -873,12 +873,22 @@ static int ibmvnic_login(struct net_device *netdev)
|
||||
|
||||
static void release_login_buffer(struct ibmvnic_adapter *adapter)
|
||||
{
|
||||
if (!adapter->login_buf)
|
||||
return;
|
||||
|
||||
dma_unmap_single(&adapter->vdev->dev, adapter->login_buf_token,
|
||||
adapter->login_buf_sz, DMA_TO_DEVICE);
|
||||
kfree(adapter->login_buf);
|
||||
adapter->login_buf = NULL;
|
||||
}
|
||||
|
||||
static void release_login_rsp_buffer(struct ibmvnic_adapter *adapter)
|
||||
{
|
||||
if (!adapter->login_rsp_buf)
|
||||
return;
|
||||
|
||||
dma_unmap_single(&adapter->vdev->dev, adapter->login_rsp_buf_token,
|
||||
adapter->login_rsp_buf_sz, DMA_FROM_DEVICE);
|
||||
kfree(adapter->login_rsp_buf);
|
||||
adapter->login_rsp_buf = NULL;
|
||||
}
|
||||
@ -4298,11 +4308,6 @@ static int handle_login_rsp(union ibmvnic_crq *login_rsp_crq,
|
||||
struct ibmvnic_login_buffer *login = adapter->login_buf;
|
||||
int i;
|
||||
|
||||
dma_unmap_single(dev, adapter->login_buf_token, adapter->login_buf_sz,
|
||||
DMA_TO_DEVICE);
|
||||
dma_unmap_single(dev, adapter->login_rsp_buf_token,
|
||||
adapter->login_rsp_buf_sz, DMA_FROM_DEVICE);
|
||||
|
||||
/* If the number of queues requested can't be allocated by the
|
||||
* server, the login response will return with code 1. We will need
|
||||
* to resend the login buffer with fewer queues requested.
|
||||
|
@ -211,8 +211,7 @@ static u16 mlx5_get_max_vfs(struct mlx5_core_dev *dev)
|
||||
host_total_vfs = MLX5_GET(query_esw_functions_out, out,
|
||||
host_params_context.host_total_vfs);
|
||||
kvfree(out);
|
||||
if (host_total_vfs)
|
||||
return host_total_vfs;
|
||||
return host_total_vfs;
|
||||
}
|
||||
|
||||
done:
|
||||
|
@ -1672,7 +1672,7 @@ static bool tun_can_build_skb(struct tun_struct *tun, struct tun_file *tfile,
|
||||
if (zerocopy)
|
||||
return false;
|
||||
|
||||
if (SKB_DATA_ALIGN(len + TUN_RX_PAD) +
|
||||
if (SKB_DATA_ALIGN(len + TUN_RX_PAD + XDP_PACKET_HEADROOM) +
|
||||
SKB_DATA_ALIGN(sizeof(struct skb_shared_info)) > PAGE_SIZE)
|
||||
return false;
|
||||
|
||||
|
@ -905,6 +905,7 @@ static int nvme_rdma_configure_io_queues(struct nvme_rdma_ctrl *ctrl, bool new)
|
||||
goto out_cleanup_connect_q;
|
||||
|
||||
if (!new) {
|
||||
nvme_start_freeze(&ctrl->ctrl);
|
||||
nvme_start_queues(&ctrl->ctrl);
|
||||
if (!nvme_wait_freeze_timeout(&ctrl->ctrl, NVME_IO_TIMEOUT)) {
|
||||
/*
|
||||
@ -913,6 +914,7 @@ static int nvme_rdma_configure_io_queues(struct nvme_rdma_ctrl *ctrl, bool new)
|
||||
* to be safe.
|
||||
*/
|
||||
ret = -ENODEV;
|
||||
nvme_unfreeze(&ctrl->ctrl);
|
||||
goto out_wait_freeze_timed_out;
|
||||
}
|
||||
blk_mq_update_nr_hw_queues(ctrl->ctrl.tagset,
|
||||
@ -958,7 +960,6 @@ static void nvme_rdma_teardown_io_queues(struct nvme_rdma_ctrl *ctrl,
|
||||
bool remove)
|
||||
{
|
||||
if (ctrl->ctrl.queue_count > 1) {
|
||||
nvme_start_freeze(&ctrl->ctrl);
|
||||
nvme_stop_queues(&ctrl->ctrl);
|
||||
nvme_sync_io_queues(&ctrl->ctrl);
|
||||
nvme_rdma_stop_io_queues(ctrl);
|
||||
|
@ -1707,6 +1707,7 @@ static int nvme_tcp_configure_io_queues(struct nvme_ctrl *ctrl, bool new)
|
||||
goto out_cleanup_connect_q;
|
||||
|
||||
if (!new) {
|
||||
nvme_start_freeze(ctrl);
|
||||
nvme_start_queues(ctrl);
|
||||
if (!nvme_wait_freeze_timeout(ctrl, NVME_IO_TIMEOUT)) {
|
||||
/*
|
||||
@ -1715,6 +1716,7 @@ static int nvme_tcp_configure_io_queues(struct nvme_ctrl *ctrl, bool new)
|
||||
* to be safe.
|
||||
*/
|
||||
ret = -ENODEV;
|
||||
nvme_unfreeze(ctrl);
|
||||
goto out_wait_freeze_timed_out;
|
||||
}
|
||||
blk_mq_update_nr_hw_queues(ctrl->tagset,
|
||||
@ -1837,7 +1839,6 @@ static void nvme_tcp_teardown_io_queues(struct nvme_ctrl *ctrl,
|
||||
if (ctrl->queue_count <= 1)
|
||||
return;
|
||||
blk_mq_quiesce_queue(ctrl->admin_q);
|
||||
nvme_start_freeze(ctrl);
|
||||
nvme_stop_queues(ctrl);
|
||||
nvme_sync_io_queues(ctrl);
|
||||
nvme_tcp_stop_io_queues(ctrl);
|
||||
|
@ -1581,7 +1581,7 @@ NCR_700_intr(int irq, void *dev_id)
|
||||
printk("scsi%d (%d:%d) PHASE MISMATCH IN SEND MESSAGE %d remain, return %p[%04x], phase %s\n", host->host_no, pun, lun, count, (void *)temp, temp - hostdata->pScript, sbcl_to_string(NCR_700_readb(host, SBCL_REG)));
|
||||
#endif
|
||||
resume_offset = hostdata->pScript + Ent_SendMessagePhaseMismatch;
|
||||
} else if(dsp >= to32bit(&slot->pSG[0].ins) &&
|
||||
} else if (slot && dsp >= to32bit(&slot->pSG[0].ins) &&
|
||||
dsp <= to32bit(&slot->pSG[NCR_700_SG_SEGMENTS].ins)) {
|
||||
int data_transfer = NCR_700_readl(host, DBC_REG) & 0xffffff;
|
||||
int SGcount = (dsp - to32bit(&slot->pSG[0].ins))/sizeof(struct NCR_700_SG_List);
|
||||
|
@ -248,6 +248,7 @@ int raid_component_add(struct raid_template *r,struct device *raid_dev,
|
||||
return 0;
|
||||
|
||||
err_out:
|
||||
put_device(&rc->dev);
|
||||
list_del(&rc->node);
|
||||
rd->component_count--;
|
||||
put_device(component_dev);
|
||||
|
@ -311,7 +311,7 @@ static ssize_t proc_scsi_write(struct file *file, const char __user *buf,
|
||||
size_t length, loff_t *ppos)
|
||||
{
|
||||
int host, channel, id, lun;
|
||||
char *buffer, *p;
|
||||
char *buffer, *end, *p;
|
||||
int err;
|
||||
|
||||
if (!buf || length > PAGE_SIZE)
|
||||
@ -326,10 +326,14 @@ static ssize_t proc_scsi_write(struct file *file, const char __user *buf,
|
||||
goto out;
|
||||
|
||||
err = -EINVAL;
|
||||
if (length < PAGE_SIZE)
|
||||
buffer[length] = '\0';
|
||||
else if (buffer[PAGE_SIZE-1])
|
||||
goto out;
|
||||
if (length < PAGE_SIZE) {
|
||||
end = buffer + length;
|
||||
*end = '\0';
|
||||
} else {
|
||||
end = buffer + PAGE_SIZE - 1;
|
||||
if (*end)
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* Usage: echo "scsi add-single-device 0 1 2 3" >/proc/scsi/scsi
|
||||
@ -338,10 +342,10 @@ static ssize_t proc_scsi_write(struct file *file, const char __user *buf,
|
||||
if (!strncmp("scsi add-single-device", buffer, 22)) {
|
||||
p = buffer + 23;
|
||||
|
||||
host = simple_strtoul(p, &p, 0);
|
||||
channel = simple_strtoul(p + 1, &p, 0);
|
||||
id = simple_strtoul(p + 1, &p, 0);
|
||||
lun = simple_strtoul(p + 1, &p, 0);
|
||||
host = (p < end) ? simple_strtoul(p, &p, 0) : 0;
|
||||
channel = (p + 1 < end) ? simple_strtoul(p + 1, &p, 0) : 0;
|
||||
id = (p + 1 < end) ? simple_strtoul(p + 1, &p, 0) : 0;
|
||||
lun = (p + 1 < end) ? simple_strtoul(p + 1, &p, 0) : 0;
|
||||
|
||||
err = scsi_add_single_device(host, channel, id, lun);
|
||||
|
||||
@ -352,10 +356,10 @@ static ssize_t proc_scsi_write(struct file *file, const char __user *buf,
|
||||
} else if (!strncmp("scsi remove-single-device", buffer, 25)) {
|
||||
p = buffer + 26;
|
||||
|
||||
host = simple_strtoul(p, &p, 0);
|
||||
channel = simple_strtoul(p + 1, &p, 0);
|
||||
id = simple_strtoul(p + 1, &p, 0);
|
||||
lun = simple_strtoul(p + 1, &p, 0);
|
||||
host = (p < end) ? simple_strtoul(p, &p, 0) : 0;
|
||||
channel = (p + 1 < end) ? simple_strtoul(p + 1, &p, 0) : 0;
|
||||
id = (p + 1 < end) ? simple_strtoul(p + 1, &p, 0) : 0;
|
||||
lun = (p + 1 < end) ? simple_strtoul(p + 1, &p, 0) : 0;
|
||||
|
||||
err = scsi_remove_single_device(host, channel, id, lun);
|
||||
}
|
||||
|
@ -317,6 +317,7 @@ snic_tgt_create(struct snic *snic, struct snic_tgt_id *tgtid)
|
||||
"Snic Tgt: device_add, with err = %d\n",
|
||||
ret);
|
||||
|
||||
put_device(&tgt->dev);
|
||||
put_device(&snic->shost->shost_gendev);
|
||||
spin_lock_irqsave(snic->shost->host_lock, flags);
|
||||
list_del(&tgt->list);
|
||||
|
@ -1526,10 +1526,6 @@ static int storvsc_host_reset_handler(struct scsi_cmnd *scmnd)
|
||||
*/
|
||||
static enum blk_eh_timer_return storvsc_eh_timed_out(struct scsi_cmnd *scmnd)
|
||||
{
|
||||
#if IS_ENABLED(CONFIG_SCSI_FC_ATTRS)
|
||||
if (scmnd->device->host->transportt == fc_transport_template)
|
||||
return fc_eh_timed_out(scmnd);
|
||||
#endif
|
||||
return BLK_EH_RESET_TIMER;
|
||||
}
|
||||
|
||||
|
@ -38,6 +38,7 @@ struct usb_conn_info {
|
||||
struct gpio_desc *vbus_gpiod;
|
||||
int id_irq;
|
||||
int vbus_irq;
|
||||
bool initial_detection;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -82,11 +83,13 @@ static void usb_conn_detect_cable(struct work_struct *work)
|
||||
dev_dbg(info->dev, "role %d/%d, gpios: id %d, vbus %d\n",
|
||||
info->last_role, role, id, vbus);
|
||||
|
||||
if (info->last_role == role) {
|
||||
if (!info->initial_detection && info->last_role == role) {
|
||||
dev_warn(info->dev, "repeated role: %d\n", role);
|
||||
return;
|
||||
}
|
||||
|
||||
info->initial_detection = false;
|
||||
|
||||
if (info->last_role == USB_ROLE_HOST)
|
||||
regulator_disable(info->vbus);
|
||||
|
||||
@ -206,6 +209,7 @@ static int usb_conn_probe(struct platform_device *pdev)
|
||||
platform_set_drvdata(pdev, info);
|
||||
|
||||
/* Perform initial detection */
|
||||
info->initial_detection = true;
|
||||
usb_conn_queue_dwork(info, 0);
|
||||
|
||||
return 0;
|
||||
|
@ -3589,9 +3589,14 @@ static irqreturn_t dwc3_check_event_buf(struct dwc3_event_buffer *evt)
|
||||
u32 reg;
|
||||
|
||||
if (pm_runtime_suspended(dwc->dev)) {
|
||||
dwc->pending_events = true;
|
||||
/*
|
||||
* Trigger runtime resume. The get() function will be balanced
|
||||
* after processing the pending events in dwc3_process_pending
|
||||
* events().
|
||||
*/
|
||||
pm_runtime_get(dwc->dev);
|
||||
disable_irq_nosync(dwc->irq_gadget);
|
||||
dwc->pending_events = true;
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
@ -3827,6 +3832,8 @@ void dwc3_gadget_process_pending_events(struct dwc3 *dwc)
|
||||
{
|
||||
if (dwc->pending_events) {
|
||||
dwc3_interrupt(dwc->irq_gadget, dwc->ev_buf);
|
||||
dwc3_thread_interrupt(dwc->irq_gadget, dwc->ev_buf);
|
||||
pm_runtime_put(dwc->dev);
|
||||
dwc->pending_events = false;
|
||||
enable_irq(dwc->irq_gadget);
|
||||
}
|
||||
|
@ -318,7 +318,8 @@ static int alauda_get_media_status(struct us_data *us, unsigned char *data)
|
||||
rc = usb_stor_ctrl_transfer(us, us->recv_ctrl_pipe,
|
||||
command, 0xc0, 0, 1, data, 2);
|
||||
|
||||
usb_stor_dbg(us, "Media status %02X %02X\n", data[0], data[1]);
|
||||
if (rc == USB_STOR_XFER_GOOD)
|
||||
usb_stor_dbg(us, "Media status %02X %02X\n", data[0], data[1]);
|
||||
|
||||
return rc;
|
||||
}
|
||||
@ -454,10 +455,14 @@ static int alauda_init_media(struct us_data *us)
|
||||
static int alauda_check_media(struct us_data *us)
|
||||
{
|
||||
struct alauda_info *info = (struct alauda_info *) us->extra;
|
||||
unsigned char status[2];
|
||||
unsigned char *status = us->iobuf;
|
||||
int rc;
|
||||
|
||||
rc = alauda_get_media_status(us, status);
|
||||
if (rc != USB_STOR_XFER_GOOD) {
|
||||
status[0] = 0xF0; /* Pretend there's no media */
|
||||
status[1] = 0;
|
||||
}
|
||||
|
||||
/* Check for no media or door open */
|
||||
if ((status[0] & 0x80) || ((status[0] & 0x1F) == 0x10)
|
||||
|
@ -3989,8 +3989,11 @@ static noinline int find_free_extent(struct btrfs_root *root,
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
if (unlikely(block_group->cached == BTRFS_CACHE_ERROR))
|
||||
if (unlikely(block_group->cached == BTRFS_CACHE_ERROR)) {
|
||||
if (!cache_block_group_error)
|
||||
cache_block_group_error = -EIO;
|
||||
goto loop;
|
||||
}
|
||||
|
||||
/*
|
||||
* Ok we want to try and use the cluster allocator, so
|
||||
|
@ -4024,11 +4024,12 @@ int btree_write_cache_pages(struct address_space *mapping,
|
||||
free_extent_buffer(eb);
|
||||
|
||||
/*
|
||||
* the filesystem may choose to bump up nr_to_write.
|
||||
* The filesystem may choose to bump up nr_to_write.
|
||||
* We have to make sure to honor the new nr_to_write
|
||||
* at any time
|
||||
* at any time.
|
||||
*/
|
||||
nr_to_write_done = wbc->nr_to_write <= 0;
|
||||
nr_to_write_done = (wbc->sync_mode == WB_SYNC_NONE &&
|
||||
wbc->nr_to_write <= 0);
|
||||
}
|
||||
pagevec_release(&pvec);
|
||||
cond_resched();
|
||||
|
@ -1112,9 +1112,17 @@ int nilfs_set_file_dirty(struct inode *inode, unsigned int nr_dirty)
|
||||
|
||||
int __nilfs_mark_inode_dirty(struct inode *inode, int flags)
|
||||
{
|
||||
struct the_nilfs *nilfs = inode->i_sb->s_fs_info;
|
||||
struct buffer_head *ibh;
|
||||
int err;
|
||||
|
||||
/*
|
||||
* Do not dirty inodes after the log writer has been detached
|
||||
* and its nilfs_root struct has been freed.
|
||||
*/
|
||||
if (unlikely(nilfs_purging(nilfs)))
|
||||
return 0;
|
||||
|
||||
err = nilfs_load_inode_block(inode, &ibh);
|
||||
if (unlikely(err)) {
|
||||
nilfs_msg(inode->i_sb, KERN_WARNING,
|
||||
|
@ -2845,6 +2845,7 @@ void nilfs_detach_log_writer(struct super_block *sb)
|
||||
nilfs_segctor_destroy(nilfs->ns_writer);
|
||||
nilfs->ns_writer = NULL;
|
||||
}
|
||||
set_nilfs_purging(nilfs);
|
||||
|
||||
/* Force to free the list of dirty files */
|
||||
spin_lock(&nilfs->ns_inode_lock);
|
||||
@ -2857,4 +2858,5 @@ void nilfs_detach_log_writer(struct super_block *sb)
|
||||
up_write(&nilfs->ns_segctor_sem);
|
||||
|
||||
nilfs_dispose_list(nilfs, &garbage_list, 1);
|
||||
clear_nilfs_purging(nilfs);
|
||||
}
|
||||
|
@ -29,6 +29,7 @@ enum {
|
||||
THE_NILFS_DISCONTINUED, /* 'next' pointer chain has broken */
|
||||
THE_NILFS_GC_RUNNING, /* gc process is running */
|
||||
THE_NILFS_SB_DIRTY, /* super block is dirty */
|
||||
THE_NILFS_PURGING, /* disposing dirty files for cleanup */
|
||||
};
|
||||
|
||||
/**
|
||||
@ -208,6 +209,7 @@ THE_NILFS_FNS(INIT, init)
|
||||
THE_NILFS_FNS(DISCONTINUED, discontinued)
|
||||
THE_NILFS_FNS(GC_RUNNING, gc_running)
|
||||
THE_NILFS_FNS(SB_DIRTY, sb_dirty)
|
||||
THE_NILFS_FNS(PURGING, purging)
|
||||
|
||||
/*
|
||||
* Mount option operations
|
||||
|
@ -454,6 +454,9 @@ ieee80211_get_sband_iftype_data(const struct ieee80211_supported_band *sband,
|
||||
if (WARN_ON(iftype >= NL80211_IFTYPE_MAX))
|
||||
return NULL;
|
||||
|
||||
if (iftype == NL80211_IFTYPE_AP_VLAN)
|
||||
iftype = NL80211_IFTYPE_AP;
|
||||
|
||||
for (i = 0; i < sband->n_iftype_data; i++) {
|
||||
const struct ieee80211_sband_iftype_data *data =
|
||||
&sband->iftype_data[i];
|
||||
|
@ -1013,6 +1013,29 @@ int __nft_release_basechain(struct nft_ctx *ctx);
|
||||
|
||||
unsigned int nft_do_chain(struct nft_pktinfo *pkt, void *priv);
|
||||
|
||||
static inline bool nft_use_inc(u32 *use)
|
||||
{
|
||||
if (*use == UINT_MAX)
|
||||
return false;
|
||||
|
||||
(*use)++;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline void nft_use_dec(u32 *use)
|
||||
{
|
||||
WARN_ON_ONCE((*use)-- == 0);
|
||||
}
|
||||
|
||||
/* For error and abort path: restore use counter to previous state. */
|
||||
static inline void nft_use_inc_restore(u32 *use)
|
||||
{
|
||||
WARN_ON_ONCE(!nft_use_inc(use));
|
||||
}
|
||||
|
||||
#define nft_use_dec_restore nft_use_dec
|
||||
|
||||
/**
|
||||
* struct nft_table - nf_tables table
|
||||
*
|
||||
@ -1082,8 +1105,8 @@ struct nft_object {
|
||||
struct list_head list;
|
||||
struct rhlist_head rhlhead;
|
||||
struct nft_object_hash_key key;
|
||||
u32 genmask:2,
|
||||
use:30;
|
||||
u32 genmask:2;
|
||||
u32 use;
|
||||
u64 handle;
|
||||
/* runtime data below here */
|
||||
const struct nft_object_ops *ops ____cacheline_aligned;
|
||||
@ -1185,8 +1208,8 @@ struct nft_flowtable {
|
||||
int hooknum;
|
||||
int priority;
|
||||
int ops_len;
|
||||
u32 genmask:2,
|
||||
use:30;
|
||||
u32 genmask:2;
|
||||
u32 use;
|
||||
u64 handle;
|
||||
/* runtime data below here */
|
||||
struct nf_hook_ops *ops ____cacheline_aligned;
|
||||
|
@ -185,7 +185,7 @@ unsigned int dccp_sync_mss(struct sock *sk, u32 pmtu)
|
||||
|
||||
/* And store cached results */
|
||||
icsk->icsk_pmtu_cookie = pmtu;
|
||||
dp->dccps_mss_cache = cur_mps;
|
||||
WRITE_ONCE(dp->dccps_mss_cache, cur_mps);
|
||||
|
||||
return cur_mps;
|
||||
}
|
||||
|
@ -644,7 +644,7 @@ static int do_dccp_getsockopt(struct sock *sk, int level, int optname,
|
||||
return dccp_getsockopt_service(sk, len,
|
||||
(__be32 __user *)optval, optlen);
|
||||
case DCCP_SOCKOPT_GET_CUR_MPS:
|
||||
val = dp->dccps_mss_cache;
|
||||
val = READ_ONCE(dp->dccps_mss_cache);
|
||||
break;
|
||||
case DCCP_SOCKOPT_AVAILABLE_CCIDS:
|
||||
return ccid_getsockopt_builtin_ccids(sk, len, optval, optlen);
|
||||
@ -766,7 +766,7 @@ int dccp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
|
||||
|
||||
trace_dccp_probe(sk, len);
|
||||
|
||||
if (len > dp->dccps_mss_cache)
|
||||
if (len > READ_ONCE(dp->dccps_mss_cache))
|
||||
return -EMSGSIZE;
|
||||
|
||||
lock_sock(sk);
|
||||
@ -799,6 +799,12 @@ int dccp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
|
||||
goto out_discard;
|
||||
}
|
||||
|
||||
/* We need to check dccps_mss_cache after socket is locked. */
|
||||
if (len > dp->dccps_mss_cache) {
|
||||
rc = -EMSGSIZE;
|
||||
goto out_discard;
|
||||
}
|
||||
|
||||
skb_reserve(skb, sk->sk_prot->max_header);
|
||||
rc = memcpy_from_msg(skb_put(skb, len), msg, len);
|
||||
if (rc != 0)
|
||||
|
@ -194,7 +194,8 @@ static struct nd_opt_hdr *ndisc_next_option(struct nd_opt_hdr *cur,
|
||||
static inline int ndisc_is_useropt(const struct net_device *dev,
|
||||
struct nd_opt_hdr *opt)
|
||||
{
|
||||
return opt->nd_opt_type == ND_OPT_RDNSS ||
|
||||
return opt->nd_opt_type == ND_OPT_PREFIX_INFO ||
|
||||
opt->nd_opt_type == ND_OPT_RDNSS ||
|
||||
opt->nd_opt_type == ND_OPT_DNSSL ||
|
||||
opt->nd_opt_type == ND_OPT_CAPTIVE_PORTAL ||
|
||||
opt->nd_opt_type == ND_OPT_PREF64 ||
|
||||
|
@ -282,7 +282,7 @@ static int nft_delchain(struct nft_ctx *ctx)
|
||||
if (IS_ERR(trans))
|
||||
return PTR_ERR(trans);
|
||||
|
||||
ctx->table->use--;
|
||||
nft_use_dec(&ctx->table->use);
|
||||
nft_deactivate_next(ctx->net, ctx->chain);
|
||||
|
||||
return 0;
|
||||
@ -323,7 +323,7 @@ nf_tables_delrule_deactivate(struct nft_ctx *ctx, struct nft_rule *rule)
|
||||
/* You cannot delete the same rule twice */
|
||||
if (nft_is_active_next(ctx->net, rule)) {
|
||||
nft_deactivate_next(ctx->net, rule);
|
||||
ctx->chain->use--;
|
||||
nft_use_dec(&ctx->chain->use);
|
||||
return 0;
|
||||
}
|
||||
return -ENOENT;
|
||||
@ -412,7 +412,7 @@ static int nft_delset(const struct nft_ctx *ctx, struct nft_set *set)
|
||||
return err;
|
||||
|
||||
nft_deactivate_next(ctx->net, set);
|
||||
ctx->table->use--;
|
||||
nft_use_dec(&ctx->table->use);
|
||||
|
||||
return err;
|
||||
}
|
||||
@ -444,7 +444,7 @@ static int nft_delobj(struct nft_ctx *ctx, struct nft_object *obj)
|
||||
return err;
|
||||
|
||||
nft_deactivate_next(ctx->net, obj);
|
||||
ctx->table->use--;
|
||||
nft_use_dec(&ctx->table->use);
|
||||
|
||||
return err;
|
||||
}
|
||||
@ -478,7 +478,7 @@ static int nft_delflowtable(struct nft_ctx *ctx,
|
||||
return err;
|
||||
|
||||
nft_deactivate_next(ctx->net, flowtable);
|
||||
ctx->table->use--;
|
||||
nft_use_dec(&ctx->table->use);
|
||||
|
||||
return err;
|
||||
}
|
||||
@ -1715,9 +1715,6 @@ static int nf_tables_addchain(struct nft_ctx *ctx, u8 family, u8 genmask,
|
||||
struct nft_rule **rules;
|
||||
int err;
|
||||
|
||||
if (table->use == UINT_MAX)
|
||||
return -EOVERFLOW;
|
||||
|
||||
if (nla[NFTA_CHAIN_HOOK]) {
|
||||
struct nft_chain_hook hook;
|
||||
struct nf_hook_ops *ops;
|
||||
@ -1794,6 +1791,11 @@ static int nf_tables_addchain(struct nft_ctx *ctx, u8 family, u8 genmask,
|
||||
if (err < 0)
|
||||
goto err1;
|
||||
|
||||
if (!nft_use_inc(&table->use)) {
|
||||
err = -EMFILE;
|
||||
goto err_use;
|
||||
}
|
||||
|
||||
err = rhltable_insert_key(&table->chains_ht, chain->name,
|
||||
&chain->rhlhead, nft_chain_ht_params);
|
||||
if (err)
|
||||
@ -1811,11 +1813,12 @@ static int nf_tables_addchain(struct nft_ctx *ctx, u8 family, u8 genmask,
|
||||
if (nft_is_base_chain(chain))
|
||||
nft_trans_chain_policy(trans) = policy;
|
||||
|
||||
table->use++;
|
||||
list_add_tail_rcu(&chain->list, &table->chains);
|
||||
|
||||
return 0;
|
||||
err2:
|
||||
nft_use_dec_restore(&table->use);
|
||||
err_use:
|
||||
nf_tables_unregister_hook(net, table, chain);
|
||||
err1:
|
||||
nf_tables_chain_destroy(ctx);
|
||||
@ -2831,9 +2834,6 @@ static int nf_tables_newrule(struct net *net, struct sock *nlsk,
|
||||
return -EINVAL;
|
||||
handle = nf_tables_alloc_handle(table);
|
||||
|
||||
if (chain->use == UINT_MAX)
|
||||
return -EOVERFLOW;
|
||||
|
||||
if (nla[NFTA_RULE_POSITION]) {
|
||||
pos_handle = be64_to_cpu(nla_get_be64(nla[NFTA_RULE_POSITION]));
|
||||
old_rule = __nft_rule_lookup(chain, pos_handle);
|
||||
@ -2915,16 +2915,21 @@ static int nf_tables_newrule(struct net *net, struct sock *nlsk,
|
||||
expr = nft_expr_next(expr);
|
||||
}
|
||||
|
||||
if (!nft_use_inc(&chain->use)) {
|
||||
err = -EMFILE;
|
||||
goto err2;
|
||||
}
|
||||
|
||||
if (nlh->nlmsg_flags & NLM_F_REPLACE) {
|
||||
trans = nft_trans_rule_add(&ctx, NFT_MSG_NEWRULE, rule);
|
||||
if (trans == NULL) {
|
||||
err = -ENOMEM;
|
||||
goto err2;
|
||||
goto err_destroy_flow_rule;
|
||||
}
|
||||
err = nft_delrule(&ctx, old_rule);
|
||||
if (err < 0) {
|
||||
nft_trans_destroy(trans);
|
||||
goto err2;
|
||||
goto err_destroy_flow_rule;
|
||||
}
|
||||
|
||||
list_add_tail_rcu(&rule->list, &old_rule->list);
|
||||
@ -2932,7 +2937,7 @@ static int nf_tables_newrule(struct net *net, struct sock *nlsk,
|
||||
trans = nft_trans_rule_add(&ctx, NFT_MSG_NEWRULE, rule);
|
||||
if (!trans) {
|
||||
err = -ENOMEM;
|
||||
goto err2;
|
||||
goto err_destroy_flow_rule;
|
||||
}
|
||||
|
||||
if (nlh->nlmsg_flags & NLM_F_APPEND) {
|
||||
@ -2948,7 +2953,6 @@ static int nf_tables_newrule(struct net *net, struct sock *nlsk,
|
||||
}
|
||||
}
|
||||
kvfree(info);
|
||||
chain->use++;
|
||||
|
||||
if (nft_net->validate_state == NFT_VALIDATE_DO)
|
||||
return nft_table_validate(net, table);
|
||||
@ -2962,6 +2966,9 @@ static int nf_tables_newrule(struct net *net, struct sock *nlsk,
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_destroy_flow_rule:
|
||||
nft_use_dec_restore(&chain->use);
|
||||
err2:
|
||||
nft_rule_expr_deactivate(&ctx, rule, NFT_TRANS_PREPARE_ERROR);
|
||||
nf_tables_rule_destroy(&ctx, rule);
|
||||
@ -3775,10 +3782,15 @@ static int nf_tables_newset(struct net *net, struct sock *nlsk,
|
||||
if (ops->privsize != NULL)
|
||||
size = ops->privsize(nla, &desc);
|
||||
|
||||
if (!nft_use_inc(&table->use)) {
|
||||
err = -EMFILE;
|
||||
goto err1;
|
||||
}
|
||||
|
||||
set = kvzalloc(sizeof(*set) + size + udlen, GFP_KERNEL);
|
||||
if (!set) {
|
||||
err = -ENOMEM;
|
||||
goto err1;
|
||||
goto err_alloc;
|
||||
}
|
||||
|
||||
name = nla_strdup(nla[NFTA_SET_NAME], GFP_KERNEL);
|
||||
@ -3825,7 +3837,7 @@ static int nf_tables_newset(struct net *net, struct sock *nlsk,
|
||||
goto err4;
|
||||
|
||||
list_add_tail_rcu(&set->list, &table->sets);
|
||||
table->use++;
|
||||
|
||||
return 0;
|
||||
|
||||
err4:
|
||||
@ -3834,6 +3846,8 @@ static int nf_tables_newset(struct net *net, struct sock *nlsk,
|
||||
kfree(set->name);
|
||||
err2:
|
||||
kvfree(set);
|
||||
err_alloc:
|
||||
nft_use_dec_restore(&table->use);
|
||||
err1:
|
||||
module_put(to_set_type(ops)->owner);
|
||||
return err;
|
||||
@ -3920,9 +3934,6 @@ int nf_tables_bind_set(const struct nft_ctx *ctx, struct nft_set *set,
|
||||
struct nft_set_binding *i;
|
||||
struct nft_set_iter iter;
|
||||
|
||||
if (set->use == UINT_MAX)
|
||||
return -EOVERFLOW;
|
||||
|
||||
if (!list_empty(&set->bindings) && nft_set_is_anonymous(set))
|
||||
return -EBUSY;
|
||||
|
||||
@ -3947,10 +3958,12 @@ int nf_tables_bind_set(const struct nft_ctx *ctx, struct nft_set *set,
|
||||
return iter.err;
|
||||
}
|
||||
bind:
|
||||
if (!nft_use_inc(&set->use))
|
||||
return -EMFILE;
|
||||
|
||||
binding->chain = ctx->chain;
|
||||
list_add_tail_rcu(&binding->list, &set->bindings);
|
||||
nft_set_trans_bind(ctx, set);
|
||||
set->use++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -3974,7 +3987,7 @@ void nf_tables_activate_set(const struct nft_ctx *ctx, struct nft_set *set)
|
||||
if (nft_set_is_anonymous(set))
|
||||
nft_clear(ctx->net, set);
|
||||
|
||||
set->use++;
|
||||
nft_use_inc_restore(&set->use);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nf_tables_activate_set);
|
||||
|
||||
@ -3990,17 +4003,17 @@ void nf_tables_deactivate_set(const struct nft_ctx *ctx, struct nft_set *set,
|
||||
else
|
||||
list_del_rcu(&binding->list);
|
||||
|
||||
set->use--;
|
||||
nft_use_dec(&set->use);
|
||||
break;
|
||||
case NFT_TRANS_PREPARE:
|
||||
if (nft_set_is_anonymous(set))
|
||||
nft_deactivate_next(ctx->net, set);
|
||||
|
||||
set->use--;
|
||||
nft_use_dec(&set->use);
|
||||
return;
|
||||
case NFT_TRANS_ABORT:
|
||||
case NFT_TRANS_RELEASE:
|
||||
set->use--;
|
||||
nft_use_dec(&set->use);
|
||||
/* fall through */
|
||||
default:
|
||||
nf_tables_unbind_set(ctx, set, binding,
|
||||
@ -4585,7 +4598,7 @@ void nft_set_elem_destroy(const struct nft_set *set, void *elem,
|
||||
}
|
||||
}
|
||||
if (nft_set_ext_exists(ext, NFT_SET_EXT_OBJREF))
|
||||
(*nft_set_ext_obj(ext))->use--;
|
||||
nft_use_dec(&(*nft_set_ext_obj(ext))->use);
|
||||
kfree(elem);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nft_set_elem_destroy);
|
||||
@ -4706,8 +4719,16 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
|
||||
set->objtype, genmask);
|
||||
if (IS_ERR(obj)) {
|
||||
err = PTR_ERR(obj);
|
||||
obj = NULL;
|
||||
goto err2;
|
||||
}
|
||||
|
||||
if (!nft_use_inc(&obj->use)) {
|
||||
err = -EMFILE;
|
||||
obj = NULL;
|
||||
goto err2;
|
||||
}
|
||||
|
||||
nft_set_ext_add(&tmpl, NFT_SET_EXT_OBJREF);
|
||||
}
|
||||
|
||||
@ -4772,10 +4793,8 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
|
||||
udata->len = ulen - 1;
|
||||
nla_memcpy(&udata->data, nla[NFTA_SET_ELEM_USERDATA], ulen);
|
||||
}
|
||||
if (obj) {
|
||||
if (obj)
|
||||
*nft_set_ext_obj(ext) = obj;
|
||||
obj->use++;
|
||||
}
|
||||
|
||||
trans = nft_trans_elem_alloc(ctx, NFT_MSG_NEWSETELEM, set);
|
||||
if (trans == NULL)
|
||||
@ -4821,13 +4840,14 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
|
||||
err5:
|
||||
kfree(trans);
|
||||
err4:
|
||||
if (obj)
|
||||
obj->use--;
|
||||
kfree(elem.priv);
|
||||
err3:
|
||||
if (nla[NFTA_SET_ELEM_DATA] != NULL)
|
||||
nft_data_release(&elem.data.val, desc.type);
|
||||
err2:
|
||||
if (obj)
|
||||
nft_use_dec_restore(&obj->use);
|
||||
|
||||
nft_data_release(&elem.key.val, NFT_DATA_VALUE);
|
||||
err1:
|
||||
return err;
|
||||
@ -4887,11 +4907,14 @@ static int nf_tables_newsetelem(struct net *net, struct sock *nlsk,
|
||||
*/
|
||||
void nft_data_hold(const struct nft_data *data, enum nft_data_types type)
|
||||
{
|
||||
struct nft_chain *chain;
|
||||
|
||||
if (type == NFT_DATA_VERDICT) {
|
||||
switch (data->verdict.code) {
|
||||
case NFT_JUMP:
|
||||
case NFT_GOTO:
|
||||
data->verdict.chain->use++;
|
||||
chain = data->verdict.chain;
|
||||
nft_use_inc_restore(&chain->use);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -4906,7 +4929,7 @@ static void nft_set_elem_activate(const struct net *net,
|
||||
if (nft_set_ext_exists(ext, NFT_SET_EXT_DATA))
|
||||
nft_data_hold(nft_set_ext_data(ext), set->dtype);
|
||||
if (nft_set_ext_exists(ext, NFT_SET_EXT_OBJREF))
|
||||
(*nft_set_ext_obj(ext))->use++;
|
||||
nft_use_inc_restore(&(*nft_set_ext_obj(ext))->use);
|
||||
}
|
||||
|
||||
static void nft_set_elem_deactivate(const struct net *net,
|
||||
@ -4918,7 +4941,7 @@ static void nft_set_elem_deactivate(const struct net *net,
|
||||
if (nft_set_ext_exists(ext, NFT_SET_EXT_DATA))
|
||||
nft_data_release(nft_set_ext_data(ext), set->dtype);
|
||||
if (nft_set_ext_exists(ext, NFT_SET_EXT_OBJREF))
|
||||
(*nft_set_ext_obj(ext))->use--;
|
||||
nft_use_dec(&(*nft_set_ext_obj(ext))->use);
|
||||
}
|
||||
|
||||
static int nft_del_setelem(struct nft_ctx *ctx, struct nft_set *set,
|
||||
@ -5375,9 +5398,14 @@ static int nf_tables_newobj(struct net *net, struct sock *nlsk,
|
||||
|
||||
nft_ctx_init(&ctx, net, skb, nlh, family, table, NULL, nla);
|
||||
|
||||
if (!nft_use_inc(&table->use))
|
||||
return -EMFILE;
|
||||
|
||||
type = nft_obj_type_get(net, objtype);
|
||||
if (IS_ERR(type))
|
||||
return PTR_ERR(type);
|
||||
if (IS_ERR(type)) {
|
||||
err = PTR_ERR(type);
|
||||
goto err_type;
|
||||
}
|
||||
|
||||
obj = nft_obj_init(&ctx, type, nla[NFTA_OBJ_DATA]);
|
||||
if (IS_ERR(obj)) {
|
||||
@ -5403,7 +5431,7 @@ static int nf_tables_newobj(struct net *net, struct sock *nlsk,
|
||||
goto err4;
|
||||
|
||||
list_add_tail_rcu(&obj->list, &table->objects);
|
||||
table->use++;
|
||||
|
||||
return 0;
|
||||
err4:
|
||||
/* queued in transaction log */
|
||||
@ -5417,6 +5445,9 @@ static int nf_tables_newobj(struct net *net, struct sock *nlsk,
|
||||
kfree(obj);
|
||||
err1:
|
||||
module_put(type->owner);
|
||||
err_type:
|
||||
nft_use_dec_restore(&table->use);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
@ -5761,7 +5792,7 @@ void nf_tables_deactivate_flowtable(const struct nft_ctx *ctx,
|
||||
case NFT_TRANS_PREPARE:
|
||||
case NFT_TRANS_ABORT:
|
||||
case NFT_TRANS_RELEASE:
|
||||
flowtable->use--;
|
||||
nft_use_dec(&flowtable->use);
|
||||
/* fall through */
|
||||
default:
|
||||
return;
|
||||
@ -5967,9 +5998,14 @@ static int nf_tables_newflowtable(struct net *net, struct sock *nlsk,
|
||||
|
||||
nft_ctx_init(&ctx, net, skb, nlh, family, table, NULL, nla);
|
||||
|
||||
if (!nft_use_inc(&table->use))
|
||||
return -EMFILE;
|
||||
|
||||
flowtable = kzalloc(sizeof(*flowtable), GFP_KERNEL);
|
||||
if (!flowtable)
|
||||
return -ENOMEM;
|
||||
if (!flowtable) {
|
||||
err = -ENOMEM;
|
||||
goto flowtable_alloc;
|
||||
}
|
||||
|
||||
flowtable->table = table;
|
||||
flowtable->handle = nf_tables_alloc_handle(table);
|
||||
@ -6023,7 +6059,6 @@ static int nf_tables_newflowtable(struct net *net, struct sock *nlsk,
|
||||
goto err6;
|
||||
|
||||
list_add_tail_rcu(&flowtable->list, &table->flowtables);
|
||||
table->use++;
|
||||
|
||||
return 0;
|
||||
err6:
|
||||
@ -6041,6 +6076,9 @@ static int nf_tables_newflowtable(struct net *net, struct sock *nlsk,
|
||||
kfree(flowtable->name);
|
||||
err1:
|
||||
kfree(flowtable);
|
||||
flowtable_alloc:
|
||||
nft_use_dec_restore(&table->use);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
@ -7033,7 +7071,7 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb)
|
||||
*/
|
||||
if (nft_set_is_anonymous(nft_trans_set(trans)) &&
|
||||
!list_empty(&nft_trans_set(trans)->bindings))
|
||||
trans->ctx.table->use--;
|
||||
nft_use_dec(&trans->ctx.table->use);
|
||||
|
||||
nf_tables_set_notify(&trans->ctx, nft_trans_set(trans),
|
||||
NFT_MSG_NEWSET, GFP_KERNEL);
|
||||
@ -7186,7 +7224,7 @@ static int __nf_tables_abort(struct net *net, enum nfnl_abort_action action)
|
||||
kfree(nft_trans_chain_name(trans));
|
||||
nft_trans_destroy(trans);
|
||||
} else {
|
||||
trans->ctx.table->use--;
|
||||
nft_use_dec_restore(&trans->ctx.table->use);
|
||||
nft_chain_del(trans->ctx.chain);
|
||||
nf_tables_unregister_hook(trans->ctx.net,
|
||||
trans->ctx.table,
|
||||
@ -7194,25 +7232,25 @@ static int __nf_tables_abort(struct net *net, enum nfnl_abort_action action)
|
||||
}
|
||||
break;
|
||||
case NFT_MSG_DELCHAIN:
|
||||
trans->ctx.table->use++;
|
||||
nft_use_inc_restore(&trans->ctx.table->use);
|
||||
nft_clear(trans->ctx.net, trans->ctx.chain);
|
||||
nft_trans_destroy(trans);
|
||||
break;
|
||||
case NFT_MSG_NEWRULE:
|
||||
trans->ctx.chain->use--;
|
||||
nft_use_dec_restore(&trans->ctx.chain->use);
|
||||
list_del_rcu(&nft_trans_rule(trans)->list);
|
||||
nft_rule_expr_deactivate(&trans->ctx,
|
||||
nft_trans_rule(trans),
|
||||
NFT_TRANS_ABORT);
|
||||
break;
|
||||
case NFT_MSG_DELRULE:
|
||||
trans->ctx.chain->use++;
|
||||
nft_use_inc_restore(&trans->ctx.chain->use);
|
||||
nft_clear(trans->ctx.net, nft_trans_rule(trans));
|
||||
nft_rule_expr_activate(&trans->ctx, nft_trans_rule(trans));
|
||||
nft_trans_destroy(trans);
|
||||
break;
|
||||
case NFT_MSG_NEWSET:
|
||||
trans->ctx.table->use--;
|
||||
nft_use_dec_restore(&trans->ctx.table->use);
|
||||
if (nft_trans_set_bound(trans)) {
|
||||
nft_trans_destroy(trans);
|
||||
break;
|
||||
@ -7220,7 +7258,7 @@ static int __nf_tables_abort(struct net *net, enum nfnl_abort_action action)
|
||||
list_del_rcu(&nft_trans_set(trans)->list);
|
||||
break;
|
||||
case NFT_MSG_DELSET:
|
||||
trans->ctx.table->use++;
|
||||
nft_use_inc_restore(&trans->ctx.table->use);
|
||||
nft_clear(trans->ctx.net, nft_trans_set(trans));
|
||||
nft_trans_destroy(trans);
|
||||
break;
|
||||
@ -7247,23 +7285,23 @@ static int __nf_tables_abort(struct net *net, enum nfnl_abort_action action)
|
||||
nft_obj_destroy(&trans->ctx, nft_trans_obj_newobj(trans));
|
||||
nft_trans_destroy(trans);
|
||||
} else {
|
||||
trans->ctx.table->use--;
|
||||
nft_use_dec_restore(&trans->ctx.table->use);
|
||||
nft_obj_del(nft_trans_obj(trans));
|
||||
}
|
||||
break;
|
||||
case NFT_MSG_DELOBJ:
|
||||
trans->ctx.table->use++;
|
||||
nft_use_inc_restore(&trans->ctx.table->use);
|
||||
nft_clear(trans->ctx.net, nft_trans_obj(trans));
|
||||
nft_trans_destroy(trans);
|
||||
break;
|
||||
case NFT_MSG_NEWFLOWTABLE:
|
||||
trans->ctx.table->use--;
|
||||
nft_use_dec_restore(&trans->ctx.table->use);
|
||||
list_del_rcu(&nft_trans_flowtable(trans)->list);
|
||||
nft_unregister_flowtable_net_hooks(net,
|
||||
nft_trans_flowtable(trans));
|
||||
break;
|
||||
case NFT_MSG_DELFLOWTABLE:
|
||||
trans->ctx.table->use++;
|
||||
nft_use_inc_restore(&trans->ctx.table->use);
|
||||
nft_clear(trans->ctx.net, nft_trans_flowtable(trans));
|
||||
nft_trans_destroy(trans);
|
||||
break;
|
||||
@ -7689,8 +7727,9 @@ static int nft_verdict_init(const struct nft_ctx *ctx, struct nft_data *data,
|
||||
return PTR_ERR(chain);
|
||||
if (nft_is_base_chain(chain))
|
||||
return -EOPNOTSUPP;
|
||||
if (!nft_use_inc(&chain->use))
|
||||
return -EMFILE;
|
||||
|
||||
chain->use++;
|
||||
data->verdict.chain = chain;
|
||||
break;
|
||||
}
|
||||
@ -7702,10 +7741,13 @@ static int nft_verdict_init(const struct nft_ctx *ctx, struct nft_data *data,
|
||||
|
||||
static void nft_verdict_uninit(const struct nft_data *data)
|
||||
{
|
||||
struct nft_chain *chain;
|
||||
|
||||
switch (data->verdict.code) {
|
||||
case NFT_JUMP:
|
||||
case NFT_GOTO:
|
||||
data->verdict.chain->use--;
|
||||
chain = data->verdict.chain;
|
||||
nft_use_dec(&chain->use);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -7859,11 +7901,11 @@ int __nft_release_basechain(struct nft_ctx *ctx)
|
||||
nf_tables_unregister_hook(ctx->net, ctx->chain->table, ctx->chain);
|
||||
list_for_each_entry_safe(rule, nr, &ctx->chain->rules, list) {
|
||||
list_del(&rule->list);
|
||||
ctx->chain->use--;
|
||||
nft_use_dec(&ctx->chain->use);
|
||||
nf_tables_rule_release(ctx, rule);
|
||||
}
|
||||
nft_chain_del(ctx->chain);
|
||||
ctx->table->use--;
|
||||
nft_use_dec(&ctx->table->use);
|
||||
nf_tables_chain_destroy(ctx);
|
||||
|
||||
return 0;
|
||||
@ -7900,29 +7942,29 @@ static void __nft_release_table(struct net *net, struct nft_table *table)
|
||||
ctx.chain = chain;
|
||||
list_for_each_entry_safe(rule, nr, &chain->rules, list) {
|
||||
list_del(&rule->list);
|
||||
chain->use--;
|
||||
nft_use_dec(&chain->use);
|
||||
nf_tables_rule_release(&ctx, rule);
|
||||
}
|
||||
}
|
||||
list_for_each_entry_safe(flowtable, nf, &table->flowtables, list) {
|
||||
list_del(&flowtable->list);
|
||||
table->use--;
|
||||
nft_use_dec(&table->use);
|
||||
nf_tables_flowtable_destroy(flowtable);
|
||||
}
|
||||
list_for_each_entry_safe(set, ns, &table->sets, list) {
|
||||
list_del(&set->list);
|
||||
table->use--;
|
||||
nft_use_dec(&table->use);
|
||||
nft_set_destroy(set);
|
||||
}
|
||||
list_for_each_entry_safe(obj, ne, &table->objects, list) {
|
||||
nft_obj_del(obj);
|
||||
table->use--;
|
||||
nft_use_dec(&table->use);
|
||||
nft_obj_destroy(&ctx, obj);
|
||||
}
|
||||
list_for_each_entry_safe(chain, nc, &table->chains, list) {
|
||||
ctx.chain = chain;
|
||||
nft_chain_del(chain);
|
||||
table->use--;
|
||||
nft_use_dec(&table->use);
|
||||
nf_tables_chain_destroy(&ctx);
|
||||
}
|
||||
list_del(&table->list);
|
||||
|
@ -171,8 +171,10 @@ static int nft_flow_offload_init(const struct nft_ctx *ctx,
|
||||
if (IS_ERR(flowtable))
|
||||
return PTR_ERR(flowtable);
|
||||
|
||||
if (!nft_use_inc(&flowtable->use))
|
||||
return -EMFILE;
|
||||
|
||||
priv->flowtable = flowtable;
|
||||
flowtable->use++;
|
||||
|
||||
return nf_ct_netns_get(ctx->net, ctx->family);
|
||||
}
|
||||
@ -191,7 +193,7 @@ static void nft_flow_offload_activate(const struct nft_ctx *ctx,
|
||||
{
|
||||
struct nft_flow_offload *priv = nft_expr_priv(expr);
|
||||
|
||||
priv->flowtable->use++;
|
||||
nft_use_inc_restore(&priv->flowtable->use);
|
||||
}
|
||||
|
||||
static void nft_flow_offload_destroy(const struct nft_ctx *ctx,
|
||||
|
@ -41,8 +41,10 @@ static int nft_objref_init(const struct nft_ctx *ctx,
|
||||
if (IS_ERR(obj))
|
||||
return -ENOENT;
|
||||
|
||||
if (!nft_use_inc(&obj->use))
|
||||
return -EMFILE;
|
||||
|
||||
nft_objref_priv(expr) = obj;
|
||||
obj->use++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -71,7 +73,7 @@ static void nft_objref_deactivate(const struct nft_ctx *ctx,
|
||||
if (phase == NFT_TRANS_COMMIT)
|
||||
return;
|
||||
|
||||
obj->use--;
|
||||
nft_use_dec(&obj->use);
|
||||
}
|
||||
|
||||
static void nft_objref_activate(const struct nft_ctx *ctx,
|
||||
@ -79,7 +81,7 @@ static void nft_objref_activate(const struct nft_ctx *ctx,
|
||||
{
|
||||
struct nft_object *obj = nft_objref_priv(expr);
|
||||
|
||||
obj->use++;
|
||||
nft_use_inc_restore(&obj->use);
|
||||
}
|
||||
|
||||
static struct nft_expr_type nft_objref_type;
|
||||
|
@ -363,18 +363,20 @@ static void __packet_set_status(struct packet_sock *po, void *frame, int status)
|
||||
{
|
||||
union tpacket_uhdr h;
|
||||
|
||||
/* WRITE_ONCE() are paired with READ_ONCE() in __packet_get_status */
|
||||
|
||||
h.raw = frame;
|
||||
switch (po->tp_version) {
|
||||
case TPACKET_V1:
|
||||
h.h1->tp_status = status;
|
||||
WRITE_ONCE(h.h1->tp_status, status);
|
||||
flush_dcache_page(pgv_to_page(&h.h1->tp_status));
|
||||
break;
|
||||
case TPACKET_V2:
|
||||
h.h2->tp_status = status;
|
||||
WRITE_ONCE(h.h2->tp_status, status);
|
||||
flush_dcache_page(pgv_to_page(&h.h2->tp_status));
|
||||
break;
|
||||
case TPACKET_V3:
|
||||
h.h3->tp_status = status;
|
||||
WRITE_ONCE(h.h3->tp_status, status);
|
||||
flush_dcache_page(pgv_to_page(&h.h3->tp_status));
|
||||
break;
|
||||
default:
|
||||
@ -391,17 +393,19 @@ static int __packet_get_status(const struct packet_sock *po, void *frame)
|
||||
|
||||
smp_rmb();
|
||||
|
||||
/* READ_ONCE() are paired with WRITE_ONCE() in __packet_set_status */
|
||||
|
||||
h.raw = frame;
|
||||
switch (po->tp_version) {
|
||||
case TPACKET_V1:
|
||||
flush_dcache_page(pgv_to_page(&h.h1->tp_status));
|
||||
return h.h1->tp_status;
|
||||
return READ_ONCE(h.h1->tp_status);
|
||||
case TPACKET_V2:
|
||||
flush_dcache_page(pgv_to_page(&h.h2->tp_status));
|
||||
return h.h2->tp_status;
|
||||
return READ_ONCE(h.h2->tp_status);
|
||||
case TPACKET_V3:
|
||||
flush_dcache_page(pgv_to_page(&h.h3->tp_status));
|
||||
return h.h3->tp_status;
|
||||
return READ_ONCE(h.h3->tp_status);
|
||||
default:
|
||||
WARN(1, "TPACKET version not supported.\n");
|
||||
BUG();
|
||||
|
@ -773,12 +773,10 @@ static void dist_free(struct disttable *d)
|
||||
* signed 16 bit values.
|
||||
*/
|
||||
|
||||
static int get_dist_table(struct Qdisc *sch, struct disttable **tbl,
|
||||
const struct nlattr *attr)
|
||||
static int get_dist_table(struct disttable **tbl, const struct nlattr *attr)
|
||||
{
|
||||
size_t n = nla_len(attr)/sizeof(__s16);
|
||||
const __s16 *data = nla_data(attr);
|
||||
spinlock_t *root_lock;
|
||||
struct disttable *d;
|
||||
int i;
|
||||
|
||||
@ -793,13 +791,7 @@ static int get_dist_table(struct Qdisc *sch, struct disttable **tbl,
|
||||
for (i = 0; i < n; i++)
|
||||
d->table[i] = data[i];
|
||||
|
||||
root_lock = qdisc_root_sleeping_lock(sch);
|
||||
|
||||
spin_lock_bh(root_lock);
|
||||
swap(*tbl, d);
|
||||
spin_unlock_bh(root_lock);
|
||||
|
||||
dist_free(d);
|
||||
*tbl = d;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -956,6 +948,8 @@ static int netem_change(struct Qdisc *sch, struct nlattr *opt,
|
||||
{
|
||||
struct netem_sched_data *q = qdisc_priv(sch);
|
||||
struct nlattr *tb[TCA_NETEM_MAX + 1];
|
||||
struct disttable *delay_dist = NULL;
|
||||
struct disttable *slot_dist = NULL;
|
||||
struct tc_netem_qopt *qopt;
|
||||
struct clgstate old_clg;
|
||||
int old_loss_model = CLG_RANDOM;
|
||||
@ -969,6 +963,18 @@ static int netem_change(struct Qdisc *sch, struct nlattr *opt,
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (tb[TCA_NETEM_DELAY_DIST]) {
|
||||
ret = get_dist_table(&delay_dist, tb[TCA_NETEM_DELAY_DIST]);
|
||||
if (ret)
|
||||
goto table_free;
|
||||
}
|
||||
|
||||
if (tb[TCA_NETEM_SLOT_DIST]) {
|
||||
ret = get_dist_table(&slot_dist, tb[TCA_NETEM_SLOT_DIST]);
|
||||
if (ret)
|
||||
goto table_free;
|
||||
}
|
||||
|
||||
sch_tree_lock(sch);
|
||||
/* backup q->clg and q->loss_model */
|
||||
old_clg = q->clg;
|
||||
@ -978,26 +984,17 @@ static int netem_change(struct Qdisc *sch, struct nlattr *opt,
|
||||
ret = get_loss_clg(q, tb[TCA_NETEM_LOSS]);
|
||||
if (ret) {
|
||||
q->loss_model = old_loss_model;
|
||||
q->clg = old_clg;
|
||||
goto unlock;
|
||||
}
|
||||
} else {
|
||||
q->loss_model = CLG_RANDOM;
|
||||
}
|
||||
|
||||
if (tb[TCA_NETEM_DELAY_DIST]) {
|
||||
ret = get_dist_table(sch, &q->delay_dist,
|
||||
tb[TCA_NETEM_DELAY_DIST]);
|
||||
if (ret)
|
||||
goto get_table_failure;
|
||||
}
|
||||
|
||||
if (tb[TCA_NETEM_SLOT_DIST]) {
|
||||
ret = get_dist_table(sch, &q->slot_dist,
|
||||
tb[TCA_NETEM_SLOT_DIST]);
|
||||
if (ret)
|
||||
goto get_table_failure;
|
||||
}
|
||||
|
||||
if (delay_dist)
|
||||
swap(q->delay_dist, delay_dist);
|
||||
if (slot_dist)
|
||||
swap(q->slot_dist, slot_dist);
|
||||
sch->limit = qopt->limit;
|
||||
|
||||
q->latency = PSCHED_TICKS2NS(qopt->latency);
|
||||
@ -1047,17 +1044,11 @@ static int netem_change(struct Qdisc *sch, struct nlattr *opt,
|
||||
|
||||
unlock:
|
||||
sch_tree_unlock(sch);
|
||||
|
||||
table_free:
|
||||
dist_free(delay_dist);
|
||||
dist_free(slot_dist);
|
||||
return ret;
|
||||
|
||||
get_table_failure:
|
||||
/* recover clg and loss_model, in case of
|
||||
* q->clg and q->loss_model were modified
|
||||
* in get_loss_clg()
|
||||
*/
|
||||
q->clg = old_clg;
|
||||
q->loss_model = old_loss_model;
|
||||
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
static int netem_init(struct Qdisc *sch, struct nlattr *opt,
|
||||
|
@ -177,7 +177,7 @@ void regression1_test(void)
|
||||
nr_threads = 2;
|
||||
pthread_barrier_init(&worker_barrier, NULL, nr_threads);
|
||||
|
||||
threads = malloc(nr_threads * sizeof(pthread_t *));
|
||||
threads = malloc(nr_threads * sizeof(*threads));
|
||||
|
||||
for (i = 0; i < nr_threads; i++) {
|
||||
arg = i;
|
||||
|
@ -4,8 +4,10 @@ ifneq ($(shell $(CC) --version 2>&1 | head -n 1 | grep clang),)
|
||||
CLANG_FLAGS += -no-integrated-as
|
||||
endif
|
||||
|
||||
top_srcdir = ../../../..
|
||||
|
||||
CFLAGS += -O2 -Wall -g -I./ -I../../../../usr/include/ -L$(OUTPUT) -Wl,-rpath=./ \
|
||||
$(CLANG_FLAGS)
|
||||
$(CLANG_FLAGS) -I$(top_srcdir)/tools/include
|
||||
LDLIBS += -lpthread -ldl
|
||||
|
||||
# Own dependencies because we only want to build against 1st prerequisite, but
|
||||
|
@ -29,6 +29,8 @@
|
||||
#include <dlfcn.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include <linux/compiler.h>
|
||||
|
||||
#include "../kselftest.h"
|
||||
#include "rseq.h"
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user