Merge e649333bcf ("octeontx2-pf: Add additional check for MCAM rules") into android13-5.15-lts

Steps on the way to 5.15.121

Change-Id: Ic1648332fcacf8686a9dcb7de46e6afd28eb775c
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
Greg Kroah-Hartman
2023-08-03 11:57:25 +00:00
114 changed files with 885 additions and 387 deletions

View File

@@ -196,7 +196,7 @@ information and return operation results::
struct args_ismountpoint ismountpoint;
};
char path[0];
char path[];
};
The ioctlfd field is a mount point file descriptor of an autofs mount

View File

@@ -467,7 +467,7 @@ Each ioctl is passed a pointer to an `autofs_dev_ioctl` structure::
struct args_ismountpoint ismountpoint;
};
char path[0];
char path[];
};
For the **OPEN_MOUNT** and **IS_MOUNTPOINT** commands, the target

View File

@@ -22,12 +22,11 @@ exclusive.
3) object removal. Locking rules: caller locks parent, finds victim,
locks victim and calls the method. Locks are exclusive.
4) rename() that is _not_ cross-directory. Locking rules: caller locks
the parent and finds source and target. In case of exchange (with
RENAME_EXCHANGE in flags argument) lock both. In any case,
if the target already exists, lock it. If the source is a non-directory,
lock it. If we need to lock both, lock them in inode pointer order.
Then call the method. All locks are exclusive.
4) rename() that is _not_ cross-directory. Locking rules: caller locks the
parent and finds source and target. We lock both (provided they exist). If we
need to lock two inodes of different type (dir vs non-dir), we lock directory
first. If we need to lock two inodes of the same type, lock them in inode
pointer order. Then call the method. All locks are exclusive.
NB: we might get away with locking the source (and target in exchange
case) shared.
@@ -44,15 +43,17 @@ All locks are exclusive.
rules:
* lock the filesystem
* lock parents in "ancestors first" order.
* lock parents in "ancestors first" order. If one is not ancestor of
the other, lock them in inode pointer order.
* find source and target.
* if old parent is equal to or is a descendent of target
fail with -ENOTEMPTY
* if new parent is equal to or is a descendent of source
fail with -ELOOP
* If it's an exchange, lock both the source and the target.
* If the target exists, lock it. If the source is a non-directory,
lock it. If we need to lock both, do so in inode pointer order.
* Lock both the source and the target provided they exist. If we
need to lock two inodes of different type (dir vs non-dir), we lock
the directory first. If we need to lock two inodes of the same type,
lock them in inode pointer order.
* call the method.
All ->i_rwsem are taken exclusive. Again, we might get away with locking
@@ -66,8 +67,9 @@ If no directory is its own ancestor, the scheme above is deadlock-free.
Proof:
First of all, at any moment we have a partial ordering of the
objects - A < B iff A is an ancestor of B.
First of all, at any moment we have a linear ordering of the
objects - A < B iff (A is an ancestor of B) or (B is not an ancestor
of A and ptr(A) < ptr(B)).
That ordering can change. However, the following is true:

View File

@@ -433,6 +433,15 @@ start N bytes into the buffer leaving the first N bytes for the
application to use. The final option is the flags field, but it will
be dealt with in separate sections for each UMEM flag.
SO_BINDTODEVICE setsockopt
--------------------------
This is a generic SOL_SOCKET option that can be used to tie AF_XDP
socket to a particular network interface. It is useful when a socket
is created by a privileged process and passed to a non-privileged one.
Once the option is set, kernel will refuse attempts to bind that socket
to a different interface. Updating the value requires CAP_NET_RAW.
XDP_STATISTICS getsockopt
-------------------------

View File

@@ -11,9 +11,9 @@
dma@7984000 {
status = "okay";
};
qpic-nand@79b0000 {
status = "okay";
};
};
};
&nand {
status = "okay";
};

View File

@@ -102,10 +102,10 @@
status = "okay";
perst-gpio = <&tlmm 38 0x1>;
};
qpic-nand@79b0000 {
pinctrl-0 = <&nand_pins>;
pinctrl-names = "default";
};
};
};
&nand {
pinctrl-0 = <&nand_pins>;
pinctrl-names = "default";
};

View File

@@ -65,11 +65,11 @@
dma@7984000 {
status = "okay";
};
qpic-nand@79b0000 {
pinctrl-0 = <&nand_pins>;
pinctrl-names = "default";
status = "okay";
};
};
};
&nand {
pinctrl-0 = <&nand_pins>;
pinctrl-names = "default";
status = "okay";
};

View File

@@ -63,6 +63,9 @@ static void __init orion5x_dt_init(void)
if (of_machine_is_compatible("maxtor,shared-storage-2"))
mss2_init();
if (of_machine_is_compatible("lacie,d2-network"))
d2net_init();
of_platform_default_populate(NULL, orion5x_auxdata_lookup, NULL);
}

View File

@@ -75,6 +75,12 @@ extern void mss2_init(void);
static inline void mss2_init(void) {}
#endif
#ifdef CONFIG_MACH_D2NET_DT
void d2net_init(void);
#else
static inline void d2net_init(void) {}
#endif
/*****************************************************************************
* Helpers to access Orion registers
****************************************************************************/

View File

@@ -240,7 +240,7 @@ config PPC_EARLY_DEBUG_40x
config PPC_EARLY_DEBUG_CPM
bool "Early serial debugging for Freescale CPM-based serial ports"
depends on SERIAL_CPM
depends on SERIAL_CPM=y
help
Select this to enable early debugging for Freescale chips
using a CPM-based serial port. This assumes that the bootwrapper

View File

@@ -235,7 +235,6 @@ static void __init setup_bootmem(void)
dma_contiguous_reserve(dma32_phys_limit);
if (IS_ENABLED(CONFIG_64BIT))
hugetlb_cma_reserve(PUD_SHIFT - PAGE_SHIFT);
memblock_allow_resize();
}
#ifdef CONFIG_MMU
@@ -868,6 +867,9 @@ void __init paging_init(void)
{
setup_bootmem();
setup_vm_final();
/* Depend on that Linear Mapping is ready */
memblock_allow_resize();
}
void __init misc_mem_init(void)

View File

@@ -69,6 +69,7 @@ struct rv_jit_context {
struct bpf_prog *prog;
u16 *insns; /* RV insns */
int ninsns;
int prologue_len;
int epilogue_offset;
int *offset; /* BPF to RV */
unsigned long flags;
@@ -214,8 +215,8 @@ static inline int rv_offset(int insn, int off, struct rv_jit_context *ctx)
int from, to;
off++; /* BPF branch is from PC+1, RV is from PC */
from = (insn > 0) ? ctx->offset[insn - 1] : 0;
to = (insn + off > 0) ? ctx->offset[insn + off - 1] : 0;
from = (insn > 0) ? ctx->offset[insn - 1] : ctx->prologue_len;
to = (insn + off > 0) ? ctx->offset[insn + off - 1] : ctx->prologue_len;
return ninsns_rvoff(to - from);
}

View File

@@ -83,6 +83,12 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
prog = orig_prog;
goto out_offset;
}
if (build_body(ctx, extra_pass, NULL)) {
prog = orig_prog;
goto out_offset;
}
for (i = 0; i < prog->len; i++) {
prev_ninsns += 32;
ctx->offset[i] = prev_ninsns;
@@ -91,11 +97,15 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
for (i = 0; i < NR_JIT_ITERATIONS; i++) {
pass++;
ctx->ninsns = 0;
bpf_jit_build_prologue(ctx);
ctx->prologue_len = ctx->ninsns;
if (build_body(ctx, extra_pass, ctx->offset)) {
prog = orig_prog;
goto out_offset;
}
bpf_jit_build_prologue(ctx);
ctx->epilogue_offset = ctx->ninsns;
bpf_jit_build_epilogue(ctx);
@@ -154,6 +164,9 @@ skip_init_ctx:
if (!prog->is_func || extra_pass) {
bpf_jit_binary_lock_ro(jit_data->header);
for (i = 0; i < prog->len; i++)
ctx->offset[i] = ninsns_rvoff(ctx->offset[i]);
bpf_prog_fill_jited_linfo(prog, ctx->offset);
out_offset:
kfree(ctx->offset);
kfree(jit_data);

View File

@@ -18,6 +18,18 @@
#include <cpu/dma-register.h>
#include <cpu/dma.h>
/*
* Some of the SoCs feature two DMAC modules. In such a case, the channels are
* distributed equally among them.
*/
#ifdef SH_DMAC_BASE1
#define SH_DMAC_NR_MD_CH (CONFIG_NR_ONCHIP_DMA_CHANNELS / 2)
#else
#define SH_DMAC_NR_MD_CH CONFIG_NR_ONCHIP_DMA_CHANNELS
#endif
#define SH_DMAC_CH_SZ 0x10
/*
* Define the default configuration for dual address memory-memory transfer.
* The 0x400 value represents auto-request, external->external.
@@ -29,7 +41,7 @@ static unsigned long dma_find_base(unsigned int chan)
unsigned long base = SH_DMAC_BASE0;
#ifdef SH_DMAC_BASE1
if (chan >= 6)
if (chan >= SH_DMAC_NR_MD_CH)
base = SH_DMAC_BASE1;
#endif
@@ -40,13 +52,13 @@ static unsigned long dma_base_addr(unsigned int chan)
{
unsigned long base = dma_find_base(chan);
/* Normalize offset calculation */
if (chan >= 9)
chan -= 6;
if (chan >= 4)
base += 0x10;
chan = (chan % SH_DMAC_NR_MD_CH) * SH_DMAC_CH_SZ;
return base + (chan * 0x10);
/* DMAOR is placed inside the channel register space. Step over it. */
if (chan >= DMAOR)
base += SH_DMAC_CH_SZ;
return base + chan;
}
#ifdef CONFIG_SH_DMA_IRQ_MULTI
@@ -250,12 +262,11 @@ static int sh_dmac_get_dma_residue(struct dma_channel *chan)
#define NR_DMAOR 1
#endif
/*
* DMAOR bases are broken out amongst channel groups. DMAOR0 manages
* channels 0 - 5, DMAOR1 6 - 11 (optional).
*/
#define dmaor_read_reg(n) __raw_readw(dma_find_base((n)*6))
#define dmaor_write_reg(n, data) __raw_writew(data, dma_find_base(n)*6)
#define dmaor_read_reg(n) __raw_readw(dma_find_base((n) * \
SH_DMAC_NR_MD_CH) + DMAOR)
#define dmaor_write_reg(n, data) __raw_writew(data, \
dma_find_base((n) * \
SH_DMAC_NR_MD_CH) + DMAOR)
static inline int dmaor_reset(int no)
{

View File

@@ -148,7 +148,7 @@ export LDFLAGS_vmlinux := $(LDFLAGS_EXECSTACK)
# When cleaning we don't include .config, so we don't include
# TT or skas makefiles and don't clean skas_ptregs.h.
CLEAN_FILES += linux x.i gmon.out
MRPROPER_FILES += arch/$(SUBARCH)/include/generated
MRPROPER_FILES += $(HOST_DIR)/include/generated
archclean:
@find . \( -name '*.bb' -o -name '*.bbg' -o -name '*.da' \

View File

@@ -90,7 +90,7 @@ int amiga_partition(struct parsed_partitions *state)
}
blk = be32_to_cpu(rdb->rdb_PartitionList);
put_dev_sector(sect);
for (part = 1; blk>0 && part<=16; part++, put_dev_sector(sect)) {
for (part = 1; (s32) blk>0 && part<=16; part++, put_dev_sector(sect)) {
/* Read in terms partition table understands */
if (check_mul_overflow(blk, (sector_t) blksize, &blk)) {
pr_err("Dev %s: overflow calculating partition block %llu! Skipping partitions %u and beyond\n",

View File

@@ -428,8 +428,7 @@ static int tusb320_typec_probe(struct i2c_client *client,
return 0;
}
static int tusb320_probe(struct i2c_client *client,
const struct i2c_device_id *id)
static int tusb320_probe(struct i2c_client *client)
{
struct tusb320_priv *priv;
const void *match_data;
@@ -502,7 +501,7 @@ static const struct of_device_id tusb320_extcon_dt_match[] = {
MODULE_DEVICE_TABLE(of, tusb320_extcon_dt_match);
static struct i2c_driver tusb320_extcon_driver = {
.probe = tusb320_probe,
.probe_new = tusb320_probe,
.driver = {
.name = "extcon-tusb320",
.of_match_table = tusb320_extcon_dt_match,

View File

@@ -147,9 +147,9 @@
* each other's read-modify-write.
*/
struct ti_sn65dsi86 {
struct auxiliary_device bridge_aux;
struct auxiliary_device gpio_aux;
struct auxiliary_device aux_aux;
struct auxiliary_device *bridge_aux;
struct auxiliary_device *gpio_aux;
struct auxiliary_device *aux_aux;
struct device *dev;
struct regmap *regmap;
@@ -412,27 +412,34 @@ static void ti_sn65dsi86_delete_aux(void *data)
auxiliary_device_delete(data);
}
/*
* AUX bus docs say that a non-NULL release is mandatory, but it makes no
* sense for the model used here where all of the aux devices are allocated
* in the single shared structure. We'll use this noop as a workaround.
*/
static void ti_sn65dsi86_noop(struct device *dev) {}
static void ti_sn65dsi86_aux_device_release(struct device *dev)
{
struct auxiliary_device *aux = container_of(dev, struct auxiliary_device, dev);
kfree(aux);
}
static int ti_sn65dsi86_add_aux_device(struct ti_sn65dsi86 *pdata,
struct auxiliary_device *aux,
struct auxiliary_device **aux_out,
const char *name)
{
struct device *dev = pdata->dev;
struct auxiliary_device *aux;
int ret;
aux = kzalloc(sizeof(*aux), GFP_KERNEL);
if (!aux)
return -ENOMEM;
aux->name = name;
aux->dev.parent = dev;
aux->dev.release = ti_sn65dsi86_noop;
aux->dev.release = ti_sn65dsi86_aux_device_release;
device_set_of_node_from_dev(&aux->dev, dev);
ret = auxiliary_device_init(aux);
if (ret)
if (ret) {
kfree(aux);
return ret;
}
ret = devm_add_action_or_reset(dev, ti_sn65dsi86_uninit_aux, aux);
if (ret)
return ret;
@@ -441,6 +448,8 @@ static int ti_sn65dsi86_add_aux_device(struct ti_sn65dsi86 *pdata,
if (ret)
return ret;
ret = devm_add_action_or_reset(dev, ti_sn65dsi86_delete_aux, aux);
if (!ret)
*aux_out = aux;
return ret;
}

View File

@@ -547,7 +547,7 @@ __vm_create_scratch_for_read(struct i915_address_space *vm, unsigned long size)
if (IS_ERR(obj))
return ERR_CAST(obj);
i915_gem_object_set_cache_coherency(obj, I915_CACHING_CACHED);
i915_gem_object_set_cache_coherency(obj, I915_CACHE_LLC);
vma = i915_vma_instance(obj, vm, NULL);
if (IS_ERR(vma)) {

View File

@@ -2469,6 +2469,7 @@ static const struct panel_desc innolux_at043tn24 = {
.height = 54,
},
.bus_format = MEDIA_BUS_FMT_RGB888_1X24,
.connector_type = DRM_MODE_CONNECTOR_DPI,
.bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE,
};
@@ -3650,6 +3651,7 @@ static const struct drm_display_mode powertip_ph800480t013_idf02_mode = {
.vsync_start = 480 + 49,
.vsync_end = 480 + 49 + 2,
.vtotal = 480 + 49 + 2 + 22,
.flags = DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_NHSYNC,
};
static const struct panel_desc powertip_ph800480t013_idf02 = {

View File

@@ -1752,16 +1752,21 @@ nodma:
if (!clk_freq || clk_freq > I2C_MAX_FAST_MODE_PLUS_FREQ) {
dev_err(qup->dev, "clock frequency not supported %d\n",
clk_freq);
return -EINVAL;
ret = -EINVAL;
goto fail_dma;
}
qup->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(qup->base))
return PTR_ERR(qup->base);
if (IS_ERR(qup->base)) {
ret = PTR_ERR(qup->base);
goto fail_dma;
}
qup->irq = platform_get_irq(pdev, 0);
if (qup->irq < 0)
return qup->irq;
if (qup->irq < 0) {
ret = qup->irq;
goto fail_dma;
}
if (has_acpi_companion(qup->dev)) {
ret = device_property_read_u32(qup->dev,
@@ -1775,13 +1780,15 @@ nodma:
qup->clk = devm_clk_get(qup->dev, "core");
if (IS_ERR(qup->clk)) {
dev_err(qup->dev, "Could not get core clock\n");
return PTR_ERR(qup->clk);
ret = PTR_ERR(qup->clk);
goto fail_dma;
}
qup->pclk = devm_clk_get(qup->dev, "iface");
if (IS_ERR(qup->pclk)) {
dev_err(qup->dev, "Could not get iface clock\n");
return PTR_ERR(qup->pclk);
ret = PTR_ERR(qup->pclk);
goto fail_dma;
}
qup_i2c_enable_clocks(qup);
src_clk_freq = clk_get_rate(qup->clk);

View File

@@ -375,6 +375,9 @@ static irqreturn_t xiic_process(int irq, void *dev_id)
struct xiic_i2c *i2c = dev_id;
u32 pend, isr, ier;
u32 clr = 0;
int xfer_more = 0;
int wakeup_req = 0;
int wakeup_code = 0;
/* Get the interrupt Status from the IPIF. There is no clearing of
* interrupts in the IPIF. Interrupts must be cleared at the source.
@@ -411,10 +414,16 @@ static irqreturn_t xiic_process(int irq, void *dev_id)
*/
xiic_reinit(i2c);
if (i2c->rx_msg)
xiic_wakeup(i2c, STATE_ERROR);
if (i2c->tx_msg)
xiic_wakeup(i2c, STATE_ERROR);
if (i2c->rx_msg) {
wakeup_req = 1;
wakeup_code = STATE_ERROR;
}
if (i2c->tx_msg) {
wakeup_req = 1;
wakeup_code = STATE_ERROR;
}
/* don't try to handle other events */
goto out;
}
if (pend & XIIC_INTR_RX_FULL_MASK) {
/* Receive register/FIFO is full */
@@ -448,8 +457,7 @@ static irqreturn_t xiic_process(int irq, void *dev_id)
i2c->tx_msg++;
dev_dbg(i2c->adap.dev.parent,
"%s will start next...\n", __func__);
__xiic_start_xfer(i2c);
xfer_more = 1;
}
}
}
@@ -463,11 +471,13 @@ static irqreturn_t xiic_process(int irq, void *dev_id)
if (!i2c->tx_msg)
goto out;
if ((i2c->nmsgs == 1) && !i2c->rx_msg &&
xiic_tx_space(i2c) == 0)
xiic_wakeup(i2c, STATE_DONE);
wakeup_req = 1;
if (i2c->nmsgs == 1 && !i2c->rx_msg &&
xiic_tx_space(i2c) == 0)
wakeup_code = STATE_DONE;
else
xiic_wakeup(i2c, STATE_ERROR);
wakeup_code = STATE_ERROR;
}
if (pend & (XIIC_INTR_TX_EMPTY_MASK | XIIC_INTR_TX_HALF_MASK)) {
/* Transmit register/FIFO is empty or ½ empty */
@@ -491,7 +501,7 @@ static irqreturn_t xiic_process(int irq, void *dev_id)
if (i2c->nmsgs > 1) {
i2c->nmsgs--;
i2c->tx_msg++;
__xiic_start_xfer(i2c);
xfer_more = 1;
} else {
xiic_irq_dis(i2c, XIIC_INTR_TX_HALF_MASK);
@@ -509,6 +519,13 @@ out:
dev_dbg(i2c->adap.dev.parent, "%s clr: 0x%x\n", __func__, clr);
xiic_setreg32(i2c, XIIC_IISR_OFFSET, clr);
if (xfer_more)
__xiic_start_xfer(i2c);
if (wakeup_req)
xiic_wakeup(i2c, wakeup_code);
WARN_ON(xfer_more && wakeup_req);
mutex_unlock(&i2c->lock);
return IRQ_HANDLED;
}

View File

@@ -318,6 +318,9 @@ static int netdev_trig_notify(struct notifier_block *nb,
clear_bit(NETDEV_LED_MODE_LINKUP, &trigger_data->mode);
switch (evt) {
case NETDEV_CHANGENAME:
if (netif_carrier_ok(dev))
set_bit(NETDEV_LED_MODE_LINKUP, &trigger_data->mode);
fallthrough;
case NETDEV_REGISTER:
if (trigger_data->net_dev)
dev_put(trigger_data->net_dev);

View File

@@ -385,14 +385,20 @@ static int ti_msgmgr_send_data(struct mbox_chan *chan, void *data)
/* Ensure all unused data is 0 */
data_trail &= 0xFFFFFFFF >> (8 * (sizeof(u32) - trail_bytes));
writel(data_trail, data_reg);
data_reg++;
data_reg += sizeof(u32);
}
/*
* 'data_reg' indicates next register to write. If we did not already
* write on tx complete reg(last reg), we must do so for transmit
* In addition, we also need to make sure all intermediate data
* registers(if any required), are reset to 0 for TISCI backward
* compatibility to be maintained.
*/
if (data_reg <= qinst->queue_buff_end)
writel(0, qinst->queue_buff_end);
while (data_reg <= qinst->queue_buff_end) {
writel(0, data_reg);
data_reg += sizeof(u32);
}
return 0;
}

View File

@@ -885,7 +885,7 @@ static struct btree *mca_cannibalize(struct cache_set *c, struct btree_op *op,
* cannibalize_bucket() will take. This means every time we unlock the root of
* the btree, we need to release this lock if we have it held.
*/
static void bch_cannibalize_unlock(struct cache_set *c)
void bch_cannibalize_unlock(struct cache_set *c)
{
spin_lock(&c->btree_cannibalize_lock);
if (c->btree_cache_alloc_lock == current) {
@@ -1090,10 +1090,12 @@ struct btree *__bch_btree_node_alloc(struct cache_set *c, struct btree_op *op,
struct btree *parent)
{
BKEY_PADDED(key) k;
struct btree *b = ERR_PTR(-EAGAIN);
struct btree *b;
mutex_lock(&c->bucket_lock);
retry:
/* return ERR_PTR(-EAGAIN) when it fails */
b = ERR_PTR(-EAGAIN);
if (__bch_bucket_alloc_set(c, RESERVE_BTREE, &k.key, wait))
goto err;
@@ -1138,7 +1140,7 @@ static struct btree *btree_node_alloc_replacement(struct btree *b,
{
struct btree *n = bch_btree_node_alloc(b->c, op, b->level, b->parent);
if (!IS_ERR_OR_NULL(n)) {
if (!IS_ERR(n)) {
mutex_lock(&n->write_lock);
bch_btree_sort_into(&b->keys, &n->keys, &b->c->sort);
bkey_copy_key(&n->key, &b->key);
@@ -1340,7 +1342,7 @@ static int btree_gc_coalesce(struct btree *b, struct btree_op *op,
memset(new_nodes, 0, sizeof(new_nodes));
closure_init_stack(&cl);
while (nodes < GC_MERGE_NODES && !IS_ERR_OR_NULL(r[nodes].b))
while (nodes < GC_MERGE_NODES && !IS_ERR(r[nodes].b))
keys += r[nodes++].keys;
blocks = btree_default_blocks(b->c) * 2 / 3;
@@ -1352,7 +1354,7 @@ static int btree_gc_coalesce(struct btree *b, struct btree_op *op,
for (i = 0; i < nodes; i++) {
new_nodes[i] = btree_node_alloc_replacement(r[i].b, NULL);
if (IS_ERR_OR_NULL(new_nodes[i]))
if (IS_ERR(new_nodes[i]))
goto out_nocoalesce;
}
@@ -1487,7 +1489,7 @@ out_nocoalesce:
bch_keylist_free(&keylist);
for (i = 0; i < nodes; i++)
if (!IS_ERR_OR_NULL(new_nodes[i])) {
if (!IS_ERR(new_nodes[i])) {
btree_node_free(new_nodes[i]);
rw_unlock(true, new_nodes[i]);
}
@@ -1669,7 +1671,7 @@ static int bch_btree_gc_root(struct btree *b, struct btree_op *op,
if (should_rewrite) {
n = btree_node_alloc_replacement(b, NULL);
if (!IS_ERR_OR_NULL(n)) {
if (!IS_ERR(n)) {
bch_btree_node_write_sync(n);
bch_btree_set_root(n);
@@ -1968,6 +1970,15 @@ static int bch_btree_check_thread(void *arg)
c->gc_stats.nodes++;
bch_btree_op_init(&op, 0);
ret = bcache_btree(check_recurse, p, c->root, &op);
/*
* The op may be added to cache_set's btree_cache_wait
* in mca_cannibalize(), must ensure it is removed from
* the list and release btree_cache_alloc_lock before
* free op memory.
* Otherwise, the btree_cache_wait will be damaged.
*/
bch_cannibalize_unlock(c);
finish_wait(&c->btree_cache_wait, &(&op)->wait);
if (ret)
goto out;
}

View File

@@ -282,6 +282,7 @@ void bch_initial_gc_finish(struct cache_set *c);
void bch_moving_gc(struct cache_set *c);
int bch_btree_check(struct cache_set *c);
void bch_initial_mark_key(struct cache_set *c, int level, struct bkey *k);
void bch_cannibalize_unlock(struct cache_set *c);
static inline void wake_up_gc(struct cache_set *c)
{

View File

@@ -1729,7 +1729,7 @@ static void cache_set_flush(struct closure *cl)
if (!IS_ERR_OR_NULL(c->gc_thread))
kthread_stop(c->gc_thread);
if (!IS_ERR_OR_NULL(c->root))
if (!IS_ERR(c->root))
list_add(&c->root->list, &c->btree_cache);
/*
@@ -2093,7 +2093,7 @@ static int run_cache_set(struct cache_set *c)
err = "cannot allocate new btree root";
c->root = __bch_btree_node_alloc(c, NULL, 0, true, NULL);
if (IS_ERR_OR_NULL(c->root))
if (IS_ERR(c->root))
goto err;
mutex_lock(&c->root->write_lock);

View File

@@ -880,6 +880,16 @@ static int bch_root_node_dirty_init(struct cache_set *c,
if (ret < 0)
pr_warn("sectors dirty init failed, ret=%d!\n", ret);
/*
* The op may be added to cache_set's btree_cache_wait
* in mca_cannibalize(), must ensure it is removed from
* the list and release btree_cache_alloc_lock before
* free op memory.
* Otherwise, the btree_cache_wait will be damaged.
*/
bch_cannibalize_unlock(c);
finish_wait(&c->btree_cache_wait, &(&op.op)->wait);
return ret;
}

View File

@@ -99,6 +99,20 @@ static const struct mmc_fixup __maybe_unused mmc_blk_fixups[] = {
MMC_FIXUP("V10016", CID_MANFID_KINGSTON, CID_OEMID_ANY, add_quirk_mmc,
MMC_QUIRK_TRIM_BROKEN),
/*
* Kingston EMMC04G-M627 advertises TRIM but it does not seems to
* support being used to offload WRITE_ZEROES.
*/
MMC_FIXUP("M62704", CID_MANFID_KINGSTON, 0x0100, add_quirk_mmc,
MMC_QUIRK_TRIM_BROKEN),
/*
* Micron MTFC4GACAJCN-1M advertises TRIM but it does not seems to
* support being used to offload WRITE_ZEROES.
*/
MMC_FIXUP("Q2J54A", CID_MANFID_MICRON, 0x014e, add_quirk_mmc,
MMC_QUIRK_TRIM_BROKEN),
/*
* Some SD cards reports discard support while they don't
*/

View File

@@ -2449,6 +2449,7 @@ static struct amba_driver mmci_driver = {
.drv = {
.name = DRIVER_NAME,
.pm = &mmci_dev_pm_ops,
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
},
.probe = mmci_probe,
.remove = mmci_remove,

View File

@@ -1147,6 +1147,8 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_command *cmd)
}
}
sdhci_config_dma(host);
if (host->flags & SDHCI_REQ_USE_DMA) {
int sg_cnt = sdhci_pre_dma_transfer(host, data, COOKIE_MAPPED);
@@ -1166,8 +1168,6 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_command *cmd)
}
}
sdhci_config_dma(host);
if (!(host->flags & SDHCI_REQ_USE_DMA)) {
int flags;

View File

@@ -1025,17 +1025,17 @@ static int vsc73xx_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
struct vsc73xx *vsc = ds->priv;
return vsc73xx_write(vsc, VSC73XX_BLOCK_MAC, port,
VSC73XX_MAXLEN, new_mtu);
VSC73XX_MAXLEN, new_mtu + ETH_HLEN + ETH_FCS_LEN);
}
/* According to application not "VSC7398 Jumbo Frames" setting
* up the MTU to 9.6 KB does not affect the performance on standard
* up the frame size to 9.6 KB does not affect the performance on standard
* frames. It is clear from the application note that
* "9.6 kilobytes" == 9600 bytes.
*/
static int vsc73xx_get_max_mtu(struct dsa_switch *ds, int port)
{
return 9600;
return 9600 - ETH_HLEN - ETH_FCS_LEN;
}
static const struct dsa_switch_ops vsc73xx_ds_ops = {

View File

@@ -1492,8 +1492,6 @@ int bgmac_enet_probe(struct bgmac *bgmac)
bgmac->in_init = true;
bgmac_chip_intrs_off(bgmac);
net_dev->irq = bgmac->irq;
SET_NETDEV_DEV(net_dev, bgmac->dev);
dev_set_drvdata(bgmac->dev, bgmac);
@@ -1511,6 +1509,8 @@ int bgmac_enet_probe(struct bgmac *bgmac)
*/
bgmac_clk_enable(bgmac, 0);
bgmac_chip_intrs_off(bgmac);
/* This seems to be fixing IRQ by assigning OOB #6 to the core */
if (!(bgmac->feature_flags & BGMAC_FEAT_IDM_MASK)) {
if (bgmac->feature_flags & BGMAC_FEAT_IRQ_ID_OOB_6)

View File

@@ -224,6 +224,7 @@ MODULE_AUTHOR("David S. Miller (davem@redhat.com) and Jeff Garzik (jgarzik@pobox
MODULE_DESCRIPTION("Broadcom Tigon3 ethernet driver");
MODULE_LICENSE("GPL");
MODULE_FIRMWARE(FIRMWARE_TG3);
MODULE_FIRMWARE(FIRMWARE_TG357766);
MODULE_FIRMWARE(FIRMWARE_TG3TSO);
MODULE_FIRMWARE(FIRMWARE_TG3TSO5);

View File

@@ -532,6 +532,9 @@ static int gve_get_link_ksettings(struct net_device *netdev,
err = gve_adminq_report_link_speed(priv);
cmd->base.speed = priv->link_speed;
cmd->base.duplex = DUPLEX_FULL;
return err;
}

View File

@@ -1240,7 +1240,14 @@ static int __ibmvnic_open(struct net_device *netdev)
if (prev_state == VNIC_CLOSED)
enable_irq(adapter->tx_scrq[i]->irq);
enable_scrq_irq(adapter, adapter->tx_scrq[i]);
netdev_tx_reset_queue(netdev_get_tx_queue(netdev, i));
/* netdev_tx_reset_queue will reset dql stats. During NON_FATAL
* resets, don't reset the stats because there could be batched
* skb's waiting to be sent. If we reset dql stats, we risk
* num_completed being greater than num_queued. This will cause
* a BUG_ON in dql_completed().
*/
if (adapter->reset_reason != VNIC_RESET_NON_FATAL)
netdev_tx_reset_queue(netdev_get_tx_queue(netdev, i));
}
rc = set_link_state(adapter, IBMVNIC_LOGICAL_LNK_UP);

View File

@@ -1701,6 +1701,8 @@ static int igc_ethtool_get_link_ksettings(struct net_device *netdev,
/* twisted pair */
cmd->base.port = PORT_TP;
cmd->base.phy_address = hw->phy.addr;
ethtool_link_ksettings_add_link_mode(cmd, supported, TP);
ethtool_link_ksettings_add_link_mode(cmd, advertising, TP);
/* advertising link modes */
if (hw->phy.autoneg_advertised & ADVERTISE_10_HALF)

View File

@@ -708,7 +708,6 @@ static void igc_configure_tx_ring(struct igc_adapter *adapter,
/* disable the queue */
wr32(IGC_TXDCTL(reg_idx), 0);
wrfl();
mdelay(10);
wr32(IGC_TDLEN(reg_idx),
ring->count * sizeof(union igc_adv_tx_desc));
@@ -1014,7 +1013,7 @@ static __le32 igc_tx_launchtime(struct igc_ring *ring, ktime_t txtime,
ktime_t base_time = adapter->base_time;
ktime_t now = ktime_get_clocktai();
ktime_t baset_est, end_of_cycle;
u32 launchtime;
s32 launchtime;
s64 n;
n = div64_s64(ktime_sub_ns(now, base_time), cycle_time);
@@ -1027,7 +1026,7 @@ static __le32 igc_tx_launchtime(struct igc_ring *ring, ktime_t txtime,
*first_flag = true;
ring->last_ff_cycle = baset_est;
if (ktime_compare(txtime, ring->last_tx_cycle) > 0)
if (ktime_compare(end_of_cycle, ring->last_tx_cycle) > 0)
*insert_empty = true;
}
}

View File

@@ -357,16 +357,35 @@ static int igc_ptp_feature_enable_i225(struct ptp_clock_info *ptp,
tsim &= ~IGC_TSICR_TT0;
}
if (on) {
struct timespec64 safe_start;
int i = rq->perout.index;
igc_pin_perout(igc, i, pin, use_freq);
igc->perout[i].start.tv_sec = rq->perout.start.sec;
igc_ptp_read(igc, &safe_start);
/* PPS output start time is triggered by Target time(TT)
* register. Programming any past time value into TT
* register will cause PPS to never start. Need to make
* sure we program the TT register a time ahead in
* future. There isn't a stringent need to fire PPS out
* right away. Adding +2 seconds should take care of
* corner cases. Let's say if the SYSTIML is close to
* wrap up and the timer keeps ticking as we program the
* register, adding +2seconds is safe bet.
*/
safe_start.tv_sec += 2;
if (rq->perout.start.sec < safe_start.tv_sec)
igc->perout[i].start.tv_sec = safe_start.tv_sec;
else
igc->perout[i].start.tv_sec = rq->perout.start.sec;
igc->perout[i].start.tv_nsec = rq->perout.start.nsec;
igc->perout[i].period.tv_sec = ts.tv_sec;
igc->perout[i].period.tv_nsec = ts.tv_nsec;
wr32(trgttimh, rq->perout.start.sec);
wr32(trgttimh, (u32)igc->perout[i].start.tv_sec);
/* For now, always select timer 0 as source. */
wr32(trgttiml, rq->perout.start.nsec | IGC_TT_IO_TIMER_SEL_SYSTIM0);
wr32(trgttiml, (u32)(igc->perout[i].start.tv_nsec |
IGC_TT_IO_TIMER_SEL_SYSTIM0));
if (use_freq)
wr32(freqout, ns);
tsauxc |= tsauxc_mask;

View File

@@ -1474,7 +1474,7 @@ static void mvneta_defaults_set(struct mvneta_port *pp)
*/
if (txq_number == 1)
txq_map = (cpu == pp->rxq_def) ?
MVNETA_CPU_TXQ_ACCESS(1) : 0;
MVNETA_CPU_TXQ_ACCESS(0) : 0;
} else {
txq_map = MVNETA_CPU_TXQ_ACCESS_ALL_MASK;
@@ -4185,7 +4185,7 @@ static void mvneta_percpu_elect(struct mvneta_port *pp)
*/
if (txq_number == 1)
txq_map = (cpu == elected_cpu) ?
MVNETA_CPU_TXQ_ACCESS(1) : 0;
MVNETA_CPU_TXQ_ACCESS(0) : 0;
else
txq_map = mvreg_read(pp, MVNETA_CPU_MAP(cpu)) &
MVNETA_CPU_TXQ_ACCESS_ALL_MASK;

View File

@@ -167,6 +167,9 @@ void cgx_lmac_write(int cgx_id, int lmac_id, u64 offset, u64 val)
{
struct cgx *cgx_dev = cgx_get_pdata(cgx_id);
/* Software must not access disabled LMAC registers */
if (!is_lmac_valid(cgx_dev, lmac_id))
return;
cgx_write(cgx_dev, lmac_id, offset, val);
}
@@ -174,6 +177,10 @@ u64 cgx_lmac_read(int cgx_id, int lmac_id, u64 offset)
{
struct cgx *cgx_dev = cgx_get_pdata(cgx_id);
/* Software must not access disabled LMAC registers */
if (!is_lmac_valid(cgx_dev, lmac_id))
return 0;
return cgx_read(cgx_dev, lmac_id, offset);
}

View File

@@ -23,6 +23,7 @@
#define PCI_DEVID_OCTEONTX2_LBK 0xA061
/* Subsystem Device ID */
#define PCI_SUBSYS_DEVID_98XX 0xB100
#define PCI_SUBSYS_DEVID_96XX 0xB200
#define PCI_SUBSYS_DEVID_CN10K_A 0xB900
@@ -614,6 +615,16 @@ static inline u16 rvu_nix_chan_cpt(struct rvu *rvu, u8 chan)
return rvu->hw->cpt_chan_base + chan;
}
static inline bool is_rvu_supports_nix1(struct rvu *rvu)
{
struct pci_dev *pdev = rvu->pdev;
if (pdev->subsystem_device == PCI_SUBSYS_DEVID_98XX)
return true;
return false;
}
/* Function Prototypes
* RVU
*/

View File

@@ -111,7 +111,7 @@ static void rvu_map_cgx_nix_block(struct rvu *rvu, int pf,
p2x = cgx_lmac_get_p2x(cgx_id, lmac_id);
/* Firmware sets P2X_SELECT as either NIX0 or NIX1 */
pfvf->nix_blkaddr = BLKADDR_NIX0;
if (p2x == CMR_P2X_SEL_NIX1)
if (is_rvu_supports_nix1(rvu) && p2x == CMR_P2X_SEL_NIX1)
pfvf->nix_blkaddr = BLKADDR_NIX1;
}
@@ -724,7 +724,7 @@ static int rvu_cgx_ptp_rx_cfg(struct rvu *rvu, u16 pcifunc, bool enable)
cgxd = rvu_cgx_pdata(cgx_id, rvu);
mac_ops = get_mac_ops(cgxd);
mac_ops->mac_enadis_ptp_config(cgxd, lmac_id, true);
mac_ops->mac_enadis_ptp_config(cgxd, lmac_id, enable);
/* If PTP is enabled then inform NPC that packets to be
* parsed by this PF will have their data shifted by 8 bytes
* and if PTP is disabled then no shift is required

View File

@@ -827,6 +827,14 @@ static int otx2_prepare_flow_request(struct ethtool_rx_flow_spec *fsp,
return -EINVAL;
vlan_etype = be16_to_cpu(fsp->h_ext.vlan_etype);
/* Drop rule with vlan_etype == 802.1Q
* and vlan_id == 0 is not supported
*/
if (vlan_etype == ETH_P_8021Q && !fsp->m_ext.vlan_tci &&
fsp->ring_cookie == RX_CLS_FLOW_DISC)
return -EINVAL;
/* Only ETH_P_8021Q and ETH_P_802AD types supported */
if (vlan_etype != ETH_P_8021Q &&
vlan_etype != ETH_P_8021AD)

View File

@@ -536,6 +536,21 @@ static int otx2_tc_prepare_flow(struct otx2_nic *nic, struct otx2_tc_flow *node,
return -EOPNOTSUPP;
}
if (!match.mask->vlan_id) {
struct flow_action_entry *act;
int i;
flow_action_for_each(i, act, &rule->action) {
if (act->id == FLOW_ACTION_DROP) {
netdev_err(nic->netdev,
"vlan tpid 0x%x with vlan_id %d is not supported for DROP rule.\n",
ntohs(match.key->vlan_tpid),
match.key->vlan_id);
return -EOPNOTSUPP;
}
}
}
if (match.mask->vlan_id ||
match.mask->vlan_dei ||
match.mask->vlan_priority) {

View File

@@ -676,8 +676,10 @@ int mlx5e_ptp_open(struct mlx5e_priv *priv, struct mlx5e_params *params,
c = kvzalloc_node(sizeof(*c), GFP_KERNEL, dev_to_node(mlx5_core_dma_dev(mdev)));
cparams = kvzalloc(sizeof(*cparams), GFP_KERNEL);
if (!c || !cparams)
return -ENOMEM;
if (!c || !cparams) {
err = -ENOMEM;
goto err_free;
}
c->priv = priv;
c->mdev = priv->mdev;

View File

@@ -194,6 +194,7 @@ static int accel_fs_tcp_create_groups(struct mlx5e_flow_table *ft,
in = kvzalloc(inlen, GFP_KERNEL);
if (!in || !ft->g) {
kfree(ft->g);
ft->g = NULL;
kvfree(in);
return -ENOMEM;
}

View File

@@ -1282,7 +1282,8 @@ static void remove_unready_flow(struct mlx5e_tc_flow *flow)
uplink_priv = &rpriv->uplink_priv;
mutex_lock(&uplink_priv->unready_flows_lock);
unready_flow_del(flow);
if (flow_flag_test(flow, NOT_READY))
unready_flow_del(flow);
mutex_unlock(&uplink_priv->unready_flows_lock);
}
@@ -1525,8 +1526,7 @@ static void mlx5e_tc_del_fdb_flow(struct mlx5e_priv *priv,
esw_attr = attr->esw_attr;
mlx5e_put_flow_tunnel_id(flow);
if (flow_flag_test(flow, NOT_READY))
remove_unready_flow(flow);
remove_unready_flow(flow);
if (mlx5e_is_offloaded_flow(flow)) {
if (flow_flag_test(flow, SLOW))

View File

@@ -83,6 +83,18 @@ static int lan743x_csr_light_reset(struct lan743x_adapter *adapter)
!(data & HW_CFG_LRST_), 100000, 10000000);
}
static int lan743x_csr_wait_for_bit_atomic(struct lan743x_adapter *adapter,
int offset, u32 bit_mask,
int target_value, int udelay_min,
int udelay_max, int count)
{
u32 data;
return readx_poll_timeout_atomic(LAN743X_CSR_READ_OP, offset, data,
target_value == !!(data & bit_mask),
udelay_max, udelay_min * count);
}
static int lan743x_csr_wait_for_bit(struct lan743x_adapter *adapter,
int offset, u32 bit_mask,
int target_value, int usleep_min,
@@ -671,8 +683,8 @@ static int lan743x_dp_write(struct lan743x_adapter *adapter,
u32 dp_sel;
int i;
if (lan743x_csr_wait_for_bit(adapter, DP_SEL, DP_SEL_DPRDY_,
1, 40, 100, 100))
if (lan743x_csr_wait_for_bit_atomic(adapter, DP_SEL, DP_SEL_DPRDY_,
1, 40, 100, 100))
return -EIO;
dp_sel = lan743x_csr_read(adapter, DP_SEL);
dp_sel &= ~DP_SEL_MASK_;
@@ -683,8 +695,9 @@ static int lan743x_dp_write(struct lan743x_adapter *adapter,
lan743x_csr_write(adapter, DP_ADDR, addr + i);
lan743x_csr_write(adapter, DP_DATA_0, buf[i]);
lan743x_csr_write(adapter, DP_CMD, DP_CMD_WRITE_);
if (lan743x_csr_wait_for_bit(adapter, DP_SEL, DP_SEL_DPRDY_,
1, 40, 100, 100))
if (lan743x_csr_wait_for_bit_atomic(adapter, DP_SEL,
DP_SEL_DPRDY_,
1, 40, 100, 100))
return -EIO;
}

View File

@@ -451,11 +451,6 @@ static void ionic_qcqs_free(struct ionic_lif *lif)
static void ionic_link_qcq_interrupts(struct ionic_qcq *src_qcq,
struct ionic_qcq *n_qcq)
{
if (WARN_ON(n_qcq->flags & IONIC_QCQ_F_INTR)) {
ionic_intr_free(n_qcq->cq.lif->ionic, n_qcq->intr.index);
n_qcq->flags &= ~IONIC_QCQ_F_INTR;
}
n_qcq->intr.vector = src_qcq->intr.vector;
n_qcq->intr.index = src_qcq->intr.index;
}

View File

@@ -24,6 +24,7 @@
#include <linux/in.h>
#include <linux/ip.h>
#include <linux/rcupdate.h>
#include <linux/security.h>
#include <linux/spinlock.h>
#include <net/sock.h>
@@ -128,6 +129,23 @@ static void del_chan(struct pppox_sock *sock)
spin_unlock(&chan_lock);
}
static struct rtable *pptp_route_output(struct pppox_sock *po,
struct flowi4 *fl4)
{
struct sock *sk = &po->sk;
struct net *net;
net = sock_net(sk);
flowi4_init_output(fl4, sk->sk_bound_dev_if, sk->sk_mark, 0,
RT_SCOPE_UNIVERSE, IPPROTO_GRE, 0,
po->proto.pptp.dst_addr.sin_addr.s_addr,
po->proto.pptp.src_addr.sin_addr.s_addr,
0, 0, sock_net_uid(net, sk));
security_sk_classify_flow(sk, flowi4_to_flowi_common(fl4));
return ip_route_output_flow(net, fl4, sk);
}
static int pptp_xmit(struct ppp_channel *chan, struct sk_buff *skb)
{
struct sock *sk = (struct sock *) chan->private;
@@ -151,11 +169,7 @@ static int pptp_xmit(struct ppp_channel *chan, struct sk_buff *skb)
if (sk_pppox(po)->sk_state & PPPOX_DEAD)
goto tx_error;
rt = ip_route_output_ports(net, &fl4, NULL,
opt->dst_addr.sin_addr.s_addr,
opt->src_addr.sin_addr.s_addr,
0, 0, IPPROTO_GRE,
RT_TOS(0), sk->sk_bound_dev_if);
rt = pptp_route_output(po, &fl4);
if (IS_ERR(rt))
goto tx_error;
@@ -438,12 +452,7 @@ static int pptp_connect(struct socket *sock, struct sockaddr *uservaddr,
po->chan.private = sk;
po->chan.ops = &pptp_chan_ops;
rt = ip_route_output_ports(sock_net(sk), &fl4, sk,
opt->dst_addr.sin_addr.s_addr,
opt->src_addr.sin_addr.s_addr,
0, 0,
IPPROTO_GRE, RT_CONN_FLAGS(sk),
sk->sk_bound_dev_if);
rt = pptp_route_output(po, &fl4);
if (IS_ERR(rt)) {
error = -EHOSTUNREACH;
goto end;

View File

@@ -546,6 +546,7 @@ static int wg_set_device(struct sk_buff *skb, struct genl_info *info)
u8 *private_key = nla_data(info->attrs[WGDEVICE_A_PRIVATE_KEY]);
u8 public_key[NOISE_PUBLIC_KEY_LEN];
struct wg_peer *peer, *temp;
bool send_staged_packets;
if (!crypto_memneq(wg->static_identity.static_private,
private_key, NOISE_PUBLIC_KEY_LEN))
@@ -564,14 +565,17 @@ static int wg_set_device(struct sk_buff *skb, struct genl_info *info)
}
down_write(&wg->static_identity.lock);
wg_noise_set_static_identity_private_key(&wg->static_identity,
private_key);
list_for_each_entry_safe(peer, temp, &wg->peer_list,
peer_list) {
send_staged_packets = !wg->static_identity.has_identity && netif_running(wg->dev);
wg_noise_set_static_identity_private_key(&wg->static_identity, private_key);
send_staged_packets = send_staged_packets && wg->static_identity.has_identity;
wg_cookie_checker_precompute_device_keys(&wg->cookie_checker);
list_for_each_entry_safe(peer, temp, &wg->peer_list, peer_list) {
wg_noise_precompute_static_static(peer);
wg_noise_expire_current_peer_keypairs(peer);
if (send_staged_packets)
wg_packet_send_staged_packets(peer);
}
wg_cookie_checker_precompute_device_keys(&wg->cookie_checker);
up_write(&wg->static_identity.lock);
}
skip_set_private_key:

View File

@@ -28,6 +28,7 @@ int wg_packet_queue_init(struct crypt_queue *queue, work_func_t function,
int ret;
memset(queue, 0, sizeof(*queue));
queue->last_cpu = -1;
ret = ptr_ring_init(&queue->ring, len, GFP_KERNEL);
if (ret)
return ret;

View File

@@ -130,20 +130,17 @@ static inline int wg_cpumask_choose_online(int *stored_cpu, unsigned int id)
return cpu;
}
/* This function is racy, in the sense that next is unlocked, so it could return
* the same CPU twice. A race-free version of this would be to instead store an
* atomic sequence number, do an increment-and-return, and then iterate through
* every possible CPU until we get to that index -- choose_cpu. However that's
* a bit slower, and it doesn't seem like this potential race actually
* introduces any performance loss, so we live with it.
/* This function is racy, in the sense that it's called while last_cpu is
* unlocked, so it could return the same CPU twice. Adding locking or using
* atomic sequence numbers is slower though, and the consequences of racing are
* harmless, so live with it.
*/
static inline int wg_cpumask_next_online(int *next)
static inline int wg_cpumask_next_online(int *last_cpu)
{
int cpu = *next;
while (unlikely(!cpumask_test_cpu(cpu, cpu_online_mask)))
cpu = cpumask_next(cpu, cpu_online_mask) % nr_cpumask_bits;
*next = cpumask_next(cpu, cpu_online_mask) % nr_cpumask_bits;
int cpu = cpumask_next(*last_cpu, cpu_online_mask);
if (cpu >= nr_cpu_ids)
cpu = cpumask_first(cpu_online_mask);
*last_cpu = cpu;
return cpu;
}
@@ -172,7 +169,7 @@ static inline void wg_prev_queue_drop_peeked(struct prev_queue *queue)
static inline int wg_queue_enqueue_per_device_and_peer(
struct crypt_queue *device_queue, struct prev_queue *peer_queue,
struct sk_buff *skb, struct workqueue_struct *wq, int *next_cpu)
struct sk_buff *skb, struct workqueue_struct *wq)
{
int cpu;
@@ -186,7 +183,7 @@ static inline int wg_queue_enqueue_per_device_and_peer(
/* Then we queue it up in the device queue, which consumes the
* packet as soon as it can.
*/
cpu = wg_cpumask_next_online(next_cpu);
cpu = wg_cpumask_next_online(&device_queue->last_cpu);
if (unlikely(ptr_ring_produce_bh(&device_queue->ring, skb)))
return -EPIPE;
queue_work_on(cpu, wq, &per_cpu_ptr(device_queue->worker, cpu)->work);

View File

@@ -531,7 +531,7 @@ static void wg_packet_consume_data(struct wg_device *wg, struct sk_buff *skb)
goto err;
ret = wg_queue_enqueue_per_device_and_peer(&wg->decrypt_queue, &peer->rx_queue, skb,
wg->packet_crypt_wq, &wg->decrypt_queue.last_cpu);
wg->packet_crypt_wq);
if (unlikely(ret == -EPIPE))
wg_queue_enqueue_per_peer_rx(skb, PACKET_STATE_DEAD);
if (likely(!ret || ret == -EPIPE)) {

View File

@@ -318,7 +318,7 @@ static void wg_packet_create_data(struct wg_peer *peer, struct sk_buff *first)
goto err;
ret = wg_queue_enqueue_per_device_and_peer(&wg->encrypt_queue, &peer->tx_queue, first,
wg->packet_crypt_wq, &wg->encrypt_queue.last_cpu);
wg->packet_crypt_wq);
if (unlikely(ret == -EPIPE))
wg_queue_enqueue_per_peer_tx(first, PACKET_STATE_DEAD);
err:

View File

@@ -1336,12 +1336,17 @@ static struct pci_driver amd_ntb_pci_driver = {
static int __init amd_ntb_pci_driver_init(void)
{
int ret;
pr_info("%s %s\n", NTB_DESC, NTB_VER);
if (debugfs_initialized())
debugfs_dir = debugfs_create_dir(KBUILD_MODNAME, NULL);
return pci_register_driver(&amd_ntb_pci_driver);
ret = pci_register_driver(&amd_ntb_pci_driver);
if (ret)
debugfs_remove_recursive(debugfs_dir);
return ret;
}
module_init(amd_ntb_pci_driver_init);

View File

@@ -2891,6 +2891,7 @@ static struct pci_driver idt_pci_driver = {
static int __init idt_pci_driver_init(void)
{
int ret;
pr_info("%s %s\n", NTB_DESC, NTB_VER);
/* Create the top DebugFS directory if the FS is initialized */
@@ -2898,7 +2899,11 @@ static int __init idt_pci_driver_init(void)
dbgfs_topdir = debugfs_create_dir(KBUILD_MODNAME, NULL);
/* Register the NTB hardware driver to handle the PCI device */
return pci_register_driver(&idt_pci_driver);
ret = pci_register_driver(&idt_pci_driver);
if (ret)
debugfs_remove_recursive(dbgfs_topdir);
return ret;
}
module_init(idt_pci_driver_init);

View File

@@ -2060,12 +2060,17 @@ static struct pci_driver intel_ntb_pci_driver = {
static int __init intel_ntb_pci_driver_init(void)
{
int ret;
pr_info("%s %s\n", NTB_DESC, NTB_VER);
if (debugfs_initialized())
debugfs_dir = debugfs_create_dir(KBUILD_MODNAME, NULL);
return pci_register_driver(&intel_ntb_pci_driver);
ret = pci_register_driver(&intel_ntb_pci_driver);
if (ret)
debugfs_remove_recursive(debugfs_dir);
return ret;
}
module_init(intel_ntb_pci_driver_init);

View File

@@ -410,7 +410,7 @@ int ntb_transport_register_client_dev(char *device_name)
rc = device_register(dev);
if (rc) {
kfree(client_dev);
put_device(dev);
goto err;
}

View File

@@ -998,6 +998,8 @@ static int tool_init_mws(struct tool_ctx *tc)
tc->peers[pidx].outmws =
devm_kcalloc(&tc->ntb->dev, tc->peers[pidx].outmw_cnt,
sizeof(*tc->peers[pidx].outmws), GFP_KERNEL);
if (tc->peers[pidx].outmws == NULL)
return -ENOMEM;
for (widx = 0; widx < tc->peers[pidx].outmw_cnt; widx++) {
tc->peers[pidx].outmws[widx].pidx = pidx;

View File

@@ -39,7 +39,7 @@ MODULE_LICENSE("GPL");
static LIST_HEAD(wmi_block_list);
struct guid_block {
char guid[16];
guid_t guid;
union {
char object_id[2];
struct {
@@ -124,7 +124,7 @@ static bool find_guid(const char *guid_string, struct wmi_block **out)
list_for_each_entry(wblock, &wmi_block_list, list) {
block = &wblock->gblock;
if (memcmp(block->guid, &guid_input, 16) == 0) {
if (guid_equal(&block->guid, &guid_input)) {
if (out)
*out = wblock;
return true;
@@ -133,11 +133,20 @@ static bool find_guid(const char *guid_string, struct wmi_block **out)
return false;
}
static bool guid_parse_and_compare(const char *string, const guid_t *guid)
{
guid_t guid_input;
if (guid_parse(string, &guid_input))
return false;
return guid_equal(&guid_input, guid);
}
static const void *find_guid_context(struct wmi_block *wblock,
struct wmi_driver *wdriver)
{
const struct wmi_device_id *id;
guid_t guid_input;
if (wblock == NULL || wdriver == NULL)
return NULL;
@@ -146,9 +155,7 @@ static const void *find_guid_context(struct wmi_block *wblock,
id = wdriver->id_table;
while (*id->guid_string) {
if (guid_parse(id->guid_string, &guid_input))
continue;
if (!memcmp(wblock->gblock.guid, &guid_input, 16))
if (guid_parse_and_compare(id->guid_string, &wblock->gblock.guid))
return id->context;
id++;
}
@@ -460,7 +467,7 @@ EXPORT_SYMBOL_GPL(wmi_set_block);
static void wmi_dump_wdg(const struct guid_block *g)
{
pr_info("%pUL:\n", g->guid);
pr_info("%pUL:\n", &g->guid);
if (g->flags & ACPI_WMI_EVENT)
pr_info("\tnotify_id: 0x%02X\n", g->notify_id);
else
@@ -542,7 +549,7 @@ wmi_notify_handler handler, void *data)
list_for_each_entry(block, &wmi_block_list, list) {
acpi_status wmi_status;
if (memcmp(block->gblock.guid, &guid_input, 16) == 0) {
if (guid_equal(&block->gblock.guid, &guid_input)) {
if (block->handler &&
block->handler != wmi_notify_debug)
return AE_ALREADY_ACQUIRED;
@@ -582,7 +589,7 @@ acpi_status wmi_remove_notify_handler(const char *guid)
list_for_each_entry(block, &wmi_block_list, list) {
acpi_status wmi_status;
if (memcmp(block->gblock.guid, &guid_input, 16) == 0) {
if (guid_equal(&block->gblock.guid, &guid_input)) {
if (!block->handler ||
block->handler == wmi_notify_debug)
return AE_NULL_ENTRY;
@@ -618,7 +625,6 @@ acpi_status wmi_get_event_data(u32 event, struct acpi_buffer *out)
{
struct acpi_object_list input;
union acpi_object params[1];
struct guid_block *gblock;
struct wmi_block *wblock;
input.count = 1;
@@ -627,7 +633,7 @@ acpi_status wmi_get_event_data(u32 event, struct acpi_buffer *out)
params[0].integer.value = event;
list_for_each_entry(wblock, &wmi_block_list, list) {
gblock = &wblock->gblock;
struct guid_block *gblock = &wblock->gblock;
if ((gblock->flags & ACPI_WMI_EVENT) &&
(gblock->notify_id == event))
@@ -693,7 +699,7 @@ static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
{
struct wmi_block *wblock = dev_to_wblock(dev);
return sprintf(buf, "wmi:%pUL\n", wblock->gblock.guid);
return sprintf(buf, "wmi:%pUL\n", &wblock->gblock.guid);
}
static DEVICE_ATTR_RO(modalias);
@@ -702,7 +708,7 @@ static ssize_t guid_show(struct device *dev, struct device_attribute *attr,
{
struct wmi_block *wblock = dev_to_wblock(dev);
return sprintf(buf, "%pUL\n", wblock->gblock.guid);
return sprintf(buf, "%pUL\n", &wblock->gblock.guid);
}
static DEVICE_ATTR_RO(guid);
@@ -785,10 +791,10 @@ static int wmi_dev_uevent(struct device *dev, struct kobj_uevent_env *env)
{
struct wmi_block *wblock = dev_to_wblock(dev);
if (add_uevent_var(env, "MODALIAS=wmi:%pUL", wblock->gblock.guid))
if (add_uevent_var(env, "MODALIAS=wmi:%pUL", &wblock->gblock.guid))
return -ENOMEM;
if (add_uevent_var(env, "WMI_GUID=%pUL", wblock->gblock.guid))
if (add_uevent_var(env, "WMI_GUID=%pUL", &wblock->gblock.guid))
return -ENOMEM;
return 0;
@@ -811,11 +817,7 @@ static int wmi_dev_match(struct device *dev, struct device_driver *driver)
return 0;
while (*id->guid_string) {
guid_t driver_guid;
if (WARN_ON(guid_parse(id->guid_string, &driver_guid)))
continue;
if (!memcmp(&driver_guid, wblock->gblock.guid, 16))
if (guid_parse_and_compare(id->guid_string, &wblock->gblock.guid))
return 1;
id++;
@@ -1046,7 +1048,6 @@ static const struct device_type wmi_type_data = {
};
static int wmi_create_device(struct device *wmi_bus_dev,
const struct guid_block *gblock,
struct wmi_block *wblock,
struct acpi_device *device)
{
@@ -1054,12 +1055,12 @@ static int wmi_create_device(struct device *wmi_bus_dev,
char method[5];
int result;
if (gblock->flags & ACPI_WMI_EVENT) {
if (wblock->gblock.flags & ACPI_WMI_EVENT) {
wblock->dev.dev.type = &wmi_type_event;
goto out_init;
}
if (gblock->flags & ACPI_WMI_METHOD) {
if (wblock->gblock.flags & ACPI_WMI_METHOD) {
wblock->dev.dev.type = &wmi_type_method;
mutex_init(&wblock->char_mutex);
goto out_init;
@@ -1109,7 +1110,7 @@ static int wmi_create_device(struct device *wmi_bus_dev,
wblock->dev.dev.bus = &wmi_bus_type;
wblock->dev.dev.parent = wmi_bus_dev;
dev_set_name(&wblock->dev.dev, "%pUL", gblock->guid);
dev_set_name(&wblock->dev.dev, "%pUL", &wblock->gblock.guid);
device_initialize(&wblock->dev.dev);
@@ -1129,12 +1130,12 @@ static void wmi_free_devices(struct acpi_device *device)
}
}
static bool guid_already_parsed(struct acpi_device *device, const u8 *guid)
static bool guid_already_parsed(struct acpi_device *device, const guid_t *guid)
{
struct wmi_block *wblock;
list_for_each_entry(wblock, &wmi_block_list, list) {
if (memcmp(wblock->gblock.guid, guid, 16) == 0) {
if (guid_equal(&wblock->gblock.guid, guid)) {
/*
* Because we historically didn't track the relationship
* between GUIDs and ACPI nodes, we don't know whether
@@ -1189,7 +1190,7 @@ static int parse_wdg(struct device *wmi_bus_dev, struct acpi_device *device)
* case yet, so for now, we'll just ignore the duplicate
* for device creation.
*/
if (guid_already_parsed(device, gblock[i].guid))
if (guid_already_parsed(device, &gblock[i].guid))
continue;
wblock = kzalloc(sizeof(struct wmi_block), GFP_KERNEL);
@@ -1201,7 +1202,7 @@ static int parse_wdg(struct device *wmi_bus_dev, struct acpi_device *device)
wblock->acpi_device = device;
wblock->gblock = gblock[i];
retval = wmi_create_device(wmi_bus_dev, &gblock[i], wblock, device);
retval = wmi_create_device(wmi_bus_dev, wblock, device);
if (retval) {
kfree(wblock);
continue;
@@ -1226,7 +1227,7 @@ static int parse_wdg(struct device *wmi_bus_dev, struct acpi_device *device)
retval = device_add(&wblock->dev.dev);
if (retval) {
dev_err(wmi_bus_dev, "failed to register %pUL\n",
wblock->gblock.guid);
&wblock->gblock.guid);
if (debug_event)
wmi_method_enable(wblock, 0);
list_del(&wblock->list);
@@ -1283,12 +1284,11 @@ acpi_wmi_ec_space_handler(u32 function, acpi_physical_address address,
static void acpi_wmi_notify_handler(acpi_handle handle, u32 event,
void *context)
{
struct guid_block *block;
struct wmi_block *wblock;
bool found_it = false;
list_for_each_entry(wblock, &wmi_block_list, list) {
block = &wblock->gblock;
struct guid_block *block = &wblock->gblock;
if (wblock->acpi_device->handle == handle &&
(block->flags & ACPI_WMI_EVENT) &&
@@ -1334,7 +1334,7 @@ static void acpi_wmi_notify_handler(acpi_handle handle, u32 event,
}
if (debug_event)
pr_info("DEBUG Event GUID: %pUL\n", wblock->gblock.guid);
pr_info("DEBUG Event GUID: %pUL\n", &wblock->gblock.guid);
acpi_bus_generate_netlink_event(
wblock->acpi_device->pnp.device_class,

View File

@@ -652,7 +652,7 @@ static QETH_DEVICE_ATTR(vipa_add4, add4, 0644,
static ssize_t qeth_l3_dev_vipa_del4_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
return qeth_l3_vipa_store(dev, buf, true, count, QETH_PROT_IPV4);
return qeth_l3_vipa_store(dev, buf, false, count, QETH_PROT_IPV4);
}
static QETH_DEVICE_ATTR(vipa_del4, del4, 0200, NULL,

View File

@@ -3898,7 +3898,7 @@ qla2x00_start_sp(srb_t *sp)
pkt = __qla2x00_alloc_iocbs(sp->qpair, sp);
if (!pkt) {
rval = EAGAIN;
rval = -EAGAIN;
ql_log(ql_log_warn, vha, 0x700c,
"qla2x00_alloc_iocbs failed.\n");
goto done;

View File

@@ -1370,13 +1370,9 @@ int bcm_qspi_probe(struct platform_device *pdev,
res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
"mspi");
if (res) {
qspi->base[MSPI] = devm_ioremap_resource(dev, res);
if (IS_ERR(qspi->base[MSPI]))
return PTR_ERR(qspi->base[MSPI]);
} else {
return 0;
}
qspi->base[MSPI] = devm_ioremap_resource(dev, res);
if (IS_ERR(qspi->base[MSPI]))
return PTR_ERR(qspi->base[MSPI]);
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "bspi");
if (res) {

View File

@@ -2632,6 +2632,7 @@ OF_EARLYCON_DECLARE(lpuart, "fsl,vf610-lpuart", lpuart_early_console_setup);
OF_EARLYCON_DECLARE(lpuart32, "fsl,ls1021a-lpuart", lpuart32_early_console_setup);
OF_EARLYCON_DECLARE(lpuart32, "fsl,ls1028a-lpuart", ls1028a_early_console_setup);
OF_EARLYCON_DECLARE(lpuart32, "fsl,imx7ulp-lpuart", lpuart32_imx_early_console_setup);
OF_EARLYCON_DECLARE(lpuart32, "fsl,imx8ulp-lpuart", lpuart32_imx_early_console_setup);
OF_EARLYCON_DECLARE(lpuart32, "fsl,imx8qxp-lpuart", lpuart32_imx_early_console_setup);
EARLYCON_DECLARE(lpuart, lpuart_early_console_setup);
EARLYCON_DECLARE(lpuart32, lpuart32_early_console_setup);

View File

@@ -78,14 +78,21 @@ static u64 btrfs_reduce_alloc_profile(struct btrfs_fs_info *fs_info, u64 flags)
}
allowed &= flags;
if (allowed & BTRFS_BLOCK_GROUP_RAID6)
/* Select the highest-redundancy RAID level. */
if (allowed & BTRFS_BLOCK_GROUP_RAID1C4)
allowed = BTRFS_BLOCK_GROUP_RAID1C4;
else if (allowed & BTRFS_BLOCK_GROUP_RAID6)
allowed = BTRFS_BLOCK_GROUP_RAID6;
else if (allowed & BTRFS_BLOCK_GROUP_RAID1C3)
allowed = BTRFS_BLOCK_GROUP_RAID1C3;
else if (allowed & BTRFS_BLOCK_GROUP_RAID5)
allowed = BTRFS_BLOCK_GROUP_RAID5;
else if (allowed & BTRFS_BLOCK_GROUP_RAID10)
allowed = BTRFS_BLOCK_GROUP_RAID10;
else if (allowed & BTRFS_BLOCK_GROUP_RAID1)
allowed = BTRFS_BLOCK_GROUP_RAID1;
else if (allowed & BTRFS_BLOCK_GROUP_DUP)
allowed = BTRFS_BLOCK_GROUP_DUP;
else if (allowed & BTRFS_BLOCK_GROUP_RAID0)
allowed = BTRFS_BLOCK_GROUP_RAID0;
@@ -1534,8 +1541,15 @@ void btrfs_reclaim_bgs_work(struct work_struct *work)
}
spin_unlock(&bg->lock);
/* Get out fast, in case we're unmounting the filesystem */
if (btrfs_fs_closing(fs_info)) {
/*
* Get out fast, in case we're read-only or unmounting the
* filesystem. It is OK to drop block groups from the list even
* for the read-only case. As we did sb_start_write(),
* "mount -o remount,ro" won't happen and read-only filesystem
* means it is forced read-only due to a fatal error. So, it
* never gets back to read-write to let us reclaim again.
*/
if (btrfs_need_cleaner_sleep(fs_info)) {
up_write(&space_info->groups_sem);
goto next;
}
@@ -1566,11 +1580,27 @@ void btrfs_reclaim_bgs_work(struct work_struct *work)
}
next:
if (ret)
btrfs_mark_bg_to_reclaim(bg);
btrfs_put_block_group(bg);
mutex_unlock(&fs_info->reclaim_bgs_lock);
/*
* Reclaiming all the block groups in the list can take really
* long. Prioritize cleaning up unused block groups.
*/
btrfs_delete_unused_bgs(fs_info);
/*
* If we are interrupted by a balance, we can just bail out. The
* cleaner thread restart again if necessary.
*/
if (!mutex_trylock(&fs_info->reclaim_bgs_lock))
goto end;
spin_lock(&fs_info->unused_bgs_lock);
}
spin_unlock(&fs_info->unused_bgs_lock);
mutex_unlock(&fs_info->reclaim_bgs_lock);
end:
btrfs_exclop_finish(fs_info);
sb_end_write(fs_info->sb);
}

View File

@@ -457,9 +457,14 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans,
btrfs_header_backref_rev(buf) < BTRFS_MIXED_BACKREF_REV)
parent_start = buf->start;
atomic_inc(&cow->refs);
ret = btrfs_tree_mod_log_insert_root(root->node, cow, true);
BUG_ON(ret < 0);
if (ret < 0) {
btrfs_tree_unlock(cow);
free_extent_buffer(cow);
btrfs_abort_transaction(trans, ret);
return ret;
}
atomic_inc(&cow->refs);
rcu_assign_pointer(root->node, cow);
btrfs_free_tree_block(trans, btrfs_root_id(root), buf,
@@ -912,7 +917,12 @@ static noinline int balance_level(struct btrfs_trans_handle *trans,
}
ret = btrfs_tree_mod_log_insert_root(root->node, child, true);
BUG_ON(ret < 0);
if (ret < 0) {
btrfs_tree_unlock(child);
free_extent_buffer(child);
btrfs_abort_transaction(trans, ret);
goto enospc;
}
rcu_assign_pointer(root->node, child);
add_root_to_dirty_list(root);
@@ -994,7 +1004,10 @@ static noinline int balance_level(struct btrfs_trans_handle *trans,
btrfs_node_key(right, &right_key, 0);
ret = btrfs_tree_mod_log_insert_key(parent, pslot + 1,
BTRFS_MOD_LOG_KEY_REPLACE, GFP_NOFS);
BUG_ON(ret < 0);
if (ret < 0) {
btrfs_abort_transaction(trans, ret);
goto enospc;
}
btrfs_set_node_key(parent, &right_key, pslot + 1);
btrfs_mark_buffer_dirty(parent);
}
@@ -1040,7 +1053,10 @@ static noinline int balance_level(struct btrfs_trans_handle *trans,
btrfs_node_key(mid, &mid_key, 0);
ret = btrfs_tree_mod_log_insert_key(parent, pslot,
BTRFS_MOD_LOG_KEY_REPLACE, GFP_NOFS);
BUG_ON(ret < 0);
if (ret < 0) {
btrfs_abort_transaction(trans, ret);
goto enospc;
}
btrfs_set_node_key(parent, &mid_key, pslot);
btrfs_mark_buffer_dirty(parent);
}
@@ -2626,6 +2642,8 @@ static noinline int split_node(struct btrfs_trans_handle *trans,
ret = btrfs_tree_mod_log_eb_copy(split, c, 0, mid, c_nritems - mid);
if (ret) {
btrfs_tree_unlock(split);
free_extent_buffer(split);
btrfs_abort_transaction(trans, ret);
return ret;
}

View File

@@ -1269,7 +1269,9 @@ int btrfs_quota_disable(struct btrfs_fs_info *fs_info)
goto out;
}
spin_lock(&fs_info->trans_lock);
list_del(&quota_root->dirty_list);
spin_unlock(&fs_info->trans_lock);
btrfs_tree_lock(quota_root->node);
btrfs_clean_tree_block(quota_root->node);

View File

@@ -3848,19 +3848,10 @@ static int ext4_rename(struct user_namespace *mnt_userns, struct inode *old_dir,
return retval;
}
/*
* We need to protect against old.inode directory getting converted
* from inline directory format into a normal one.
*/
if (S_ISDIR(old.inode->i_mode))
inode_lock_nested(old.inode, I_MUTEX_NONDIR2);
old.bh = ext4_find_entry(old.dir, &old.dentry->d_name, &old.de,
&old.inlined);
if (IS_ERR(old.bh)) {
retval = PTR_ERR(old.bh);
goto unlock_moved_dir;
}
if (IS_ERR(old.bh))
return PTR_ERR(old.bh);
/*
* Check for inode number is _not_ due to possible IO errors.
@@ -4050,10 +4041,6 @@ release_bh:
brelse(old.bh);
brelse(new.bh);
unlock_moved_dir:
if (S_ISDIR(old.inode->i_mode))
inode_unlock(old.inode);
return retval;
}

View File

@@ -995,20 +995,12 @@ static int f2fs_rename(struct user_namespace *mnt_userns, struct inode *old_dir,
goto out;
}
/*
* Copied from ext4_rename: we need to protect against old.inode
* directory getting converted from inline directory format into
* a normal one.
*/
if (S_ISDIR(old_inode->i_mode))
inode_lock_nested(old_inode, I_MUTEX_NONDIR2);
err = -ENOENT;
old_entry = f2fs_find_entry(old_dir, &old_dentry->d_name, &old_page);
if (!old_entry) {
if (IS_ERR(old_page))
err = PTR_ERR(old_page);
goto out_unlock_old;
goto out;
}
if (S_ISDIR(old_inode->i_mode)) {
@@ -1116,9 +1108,6 @@ static int f2fs_rename(struct user_namespace *mnt_userns, struct inode *old_dir,
f2fs_unlock_op(sbi);
if (S_ISDIR(old_inode->i_mode))
inode_unlock(old_inode);
if (IS_DIRSYNC(old_dir) || IS_DIRSYNC(new_dir))
f2fs_sync_fs(sbi->sb, 1);
@@ -1133,9 +1122,6 @@ out_dir:
f2fs_put_page(old_dir_page, 0);
out_old:
f2fs_put_page(old_page, 0);
out_unlock_old:
if (S_ISDIR(old_inode->i_mode))
inode_unlock(old_inode);
out:
iput(whiteout);
return err;

View File

@@ -942,8 +942,10 @@ static int truncate_dnode(struct dnode_of_data *dn)
dn->ofs_in_node = 0;
f2fs_truncate_data_blocks(dn);
err = truncate_node(dn);
if (err)
if (err) {
f2fs_put_page(page, 1);
return err;
}
return 1;
}

View File

@@ -561,7 +561,8 @@ static int legacy_parse_param(struct fs_context *fc, struct fs_parameter *param)
return -ENOMEM;
}
ctx->legacy_data[size++] = ',';
if (size)
ctx->legacy_data[size++] = ',';
len = strlen(param->key);
memcpy(ctx->legacy_data + size, param->key, len);
size += len;

View File

@@ -1023,6 +1023,48 @@ void discard_new_inode(struct inode *inode)
}
EXPORT_SYMBOL(discard_new_inode);
/**
* lock_two_inodes - lock two inodes (may be regular files but also dirs)
*
* Lock any non-NULL argument. The caller must make sure that if he is passing
* in two directories, one is not ancestor of the other. Zero, one or two
* objects may be locked by this function.
*
* @inode1: first inode to lock
* @inode2: second inode to lock
* @subclass1: inode lock subclass for the first lock obtained
* @subclass2: inode lock subclass for the second lock obtained
*/
void lock_two_inodes(struct inode *inode1, struct inode *inode2,
unsigned subclass1, unsigned subclass2)
{
if (!inode1 || !inode2) {
/*
* Make sure @subclass1 will be used for the acquired lock.
* This is not strictly necessary (no current caller cares) but
* let's keep things consistent.
*/
if (!inode1)
swap(inode1, inode2);
goto lock;
}
/*
* If one object is directory and the other is not, we must make sure
* to lock directory first as the other object may be its child.
*/
if (S_ISDIR(inode2->i_mode) == S_ISDIR(inode1->i_mode)) {
if (inode1 > inode2)
swap(inode1, inode2);
} else if (!S_ISDIR(inode1->i_mode))
swap(inode1, inode2);
lock:
if (inode1)
inode_lock_nested(inode1, subclass1);
if (inode2 && inode2 != inode1)
inode_lock_nested(inode2, subclass2);
}
/**
* lock_two_nondirectories - take two i_mutexes on non-directory objects
*

View File

@@ -152,6 +152,8 @@ extern void inode_add_lru(struct inode *inode);
int dentry_needs_remove_privs(struct user_namespace *, struct dentry *dentry);
bool in_group_or_capable(struct user_namespace *mnt_userns,
const struct inode *inode, kgid_t gid);
void lock_two_inodes(struct inode *inode1, struct inode *inode2,
unsigned subclass1, unsigned subclass2);
/*
* fs-writeback.c

View File

@@ -211,7 +211,10 @@ static int jffs2_build_filesystem(struct jffs2_sb_info *c)
ic->scan_dents = NULL;
cond_resched();
}
jffs2_build_xattr_subsystem(c);
ret = jffs2_build_xattr_subsystem(c);
if (ret)
goto exit;
c->flags &= ~JFFS2_SB_FLAG_BUILDING;
dbg_fsbuild("FS build complete\n");

View File

@@ -772,10 +772,10 @@ void jffs2_clear_xattr_subsystem(struct jffs2_sb_info *c)
}
#define XREF_TMPHASH_SIZE (128)
void jffs2_build_xattr_subsystem(struct jffs2_sb_info *c)
int jffs2_build_xattr_subsystem(struct jffs2_sb_info *c)
{
struct jffs2_xattr_ref *ref, *_ref;
struct jffs2_xattr_ref *xref_tmphash[XREF_TMPHASH_SIZE];
struct jffs2_xattr_ref **xref_tmphash;
struct jffs2_xattr_datum *xd, *_xd;
struct jffs2_inode_cache *ic;
struct jffs2_raw_node_ref *raw;
@@ -784,9 +784,12 @@ void jffs2_build_xattr_subsystem(struct jffs2_sb_info *c)
BUG_ON(!(c->flags & JFFS2_SB_FLAG_BUILDING));
xref_tmphash = kcalloc(XREF_TMPHASH_SIZE,
sizeof(struct jffs2_xattr_ref *), GFP_KERNEL);
if (!xref_tmphash)
return -ENOMEM;
/* Phase.1 : Merge same xref */
for (i=0; i < XREF_TMPHASH_SIZE; i++)
xref_tmphash[i] = NULL;
for (ref=c->xref_temp; ref; ref=_ref) {
struct jffs2_xattr_ref *tmp;
@@ -884,6 +887,8 @@ void jffs2_build_xattr_subsystem(struct jffs2_sb_info *c)
"%u of xref (%u dead, %u orphan) found.\n",
xdatum_count, xdatum_unchecked_count, xdatum_orphan_count,
xref_count, xref_dead_count, xref_orphan_count);
kfree(xref_tmphash);
return 0;
}
struct jffs2_xattr_datum *jffs2_setup_xattr_datum(struct jffs2_sb_info *c,

View File

@@ -71,7 +71,7 @@ static inline int is_xattr_ref_dead(struct jffs2_xattr_ref *ref)
#ifdef CONFIG_JFFS2_FS_XATTR
extern void jffs2_init_xattr_subsystem(struct jffs2_sb_info *c);
extern void jffs2_build_xattr_subsystem(struct jffs2_sb_info *c);
extern int jffs2_build_xattr_subsystem(struct jffs2_sb_info *c);
extern void jffs2_clear_xattr_subsystem(struct jffs2_sb_info *c);
extern struct jffs2_xattr_datum *jffs2_setup_xattr_datum(struct jffs2_sb_info *c,
@@ -103,7 +103,7 @@ extern ssize_t jffs2_listxattr(struct dentry *, char *, size_t);
#else
#define jffs2_init_xattr_subsystem(c)
#define jffs2_build_xattr_subsystem(c)
#define jffs2_build_xattr_subsystem(c) (0)
#define jffs2_clear_xattr_subsystem(c)
#define jffs2_xattr_do_crccheck_inode(c, ic)

View File

@@ -184,24 +184,31 @@ static void __handle_ksmbd_work(struct ksmbd_work *work,
goto send;
}
if (conn->ops->check_user_session) {
rc = conn->ops->check_user_session(work);
if (rc < 0) {
command = conn->ops->get_cmd_val(work);
conn->ops->set_rsp_status(work,
STATUS_USER_SESSION_DELETED);
goto send;
} else if (rc > 0) {
rc = conn->ops->get_ksmbd_tcon(work);
do {
if (conn->ops->check_user_session) {
rc = conn->ops->check_user_session(work);
if (rc < 0) {
conn->ops->set_rsp_status(work,
STATUS_NETWORK_NAME_DELETED);
if (rc == -EINVAL)
conn->ops->set_rsp_status(work,
STATUS_INVALID_PARAMETER);
else
conn->ops->set_rsp_status(work,
STATUS_USER_SESSION_DELETED);
goto send;
} else if (rc > 0) {
rc = conn->ops->get_ksmbd_tcon(work);
if (rc < 0) {
if (rc == -EINVAL)
conn->ops->set_rsp_status(work,
STATUS_INVALID_PARAMETER);
else
conn->ops->set_rsp_status(work,
STATUS_NETWORK_NAME_DELETED);
goto send;
}
}
}
}
do {
rc = __process_request(work, conn, &command);
if (rc == SERVER_HANDLER_ABORT)
break;

View File

@@ -347,19 +347,21 @@ static int smb2_validate_credit_charge(struct ksmbd_conn *conn,
int ksmbd_smb2_check_message(struct ksmbd_work *work)
{
struct smb2_pdu *pdu = work->request_buf;
struct smb2_pdu *pdu = ksmbd_req_buf_next(work);
struct smb2_hdr *hdr = &pdu->hdr;
int command;
__u32 clc_len; /* calculated length */
__u32 len = get_rfc1002_len(pdu);
__u32 len = get_rfc1002_len(work->request_buf);
__u32 req_struct_size, next_cmd = le32_to_cpu(hdr->NextCommand);
if (work->next_smb2_rcv_hdr_off) {
pdu = ksmbd_req_buf_next(work);
hdr = &pdu->hdr;
if ((u64)work->next_smb2_rcv_hdr_off + next_cmd > len) {
pr_err("next command(%u) offset exceeds smb msg size\n",
next_cmd);
return 1;
}
if (le32_to_cpu(hdr->NextCommand) > 0)
len = le32_to_cpu(hdr->NextCommand);
if (next_cmd > 0)
len = next_cmd;
else if (work->next_smb2_rcv_hdr_off)
len -= work->next_smb2_rcv_hdr_off;
@@ -379,17 +381,9 @@ int ksmbd_smb2_check_message(struct ksmbd_work *work)
}
if (smb2_req_struct_sizes[command] != pdu->StructureSize2) {
if (command != SMB2_OPLOCK_BREAK_HE &&
(hdr->Status == 0 || pdu->StructureSize2 != SMB2_ERROR_STRUCTURE_SIZE2_LE)) {
/* error packets have 9 byte structure size */
ksmbd_debug(SMB,
"Illegal request size %u for command %d\n",
le16_to_cpu(pdu->StructureSize2), command);
return 1;
} else if (command == SMB2_OPLOCK_BREAK_HE &&
hdr->Status == 0 &&
le16_to_cpu(pdu->StructureSize2) != OP_BREAK_STRUCT_SIZE_20 &&
le16_to_cpu(pdu->StructureSize2) != OP_BREAK_STRUCT_SIZE_21) {
if (command == SMB2_OPLOCK_BREAK_HE &&
le16_to_cpu(pdu->StructureSize2) != OP_BREAK_STRUCT_SIZE_20 &&
le16_to_cpu(pdu->StructureSize2) != OP_BREAK_STRUCT_SIZE_21) {
/* special case for SMB2.1 lease break message */
ksmbd_debug(SMB,
"Illegal request size %d for oplock break\n",
@@ -398,6 +392,14 @@ int ksmbd_smb2_check_message(struct ksmbd_work *work)
}
}
req_struct_size = le16_to_cpu(pdu->StructureSize2) +
__SMB2_HEADER_STRUCTURE_SIZE;
if (command == SMB2_LOCK_HE)
req_struct_size -= sizeof(struct smb2_lock_element);
if (req_struct_size > len + 1)
return 1;
if (smb2_calc_size(hdr, &clc_len))
return 1;

View File

@@ -97,7 +97,6 @@ int smb2_get_ksmbd_tcon(struct ksmbd_work *work)
struct smb2_hdr *req_hdr = work->request_buf;
int tree_id;
work->tcon = NULL;
if (work->conn->ops->get_cmd_val(work) == SMB2_TREE_CONNECT_HE ||
work->conn->ops->get_cmd_val(work) == SMB2_CANCEL_HE ||
work->conn->ops->get_cmd_val(work) == SMB2_LOGOFF_HE) {
@@ -111,10 +110,28 @@ int smb2_get_ksmbd_tcon(struct ksmbd_work *work)
}
tree_id = le32_to_cpu(req_hdr->Id.SyncId.TreeId);
/*
* If request is not the first in Compound request,
* Just validate tree id in header with work->tcon->id.
*/
if (work->next_smb2_rcv_hdr_off) {
if (!work->tcon) {
pr_err("The first operation in the compound does not have tcon\n");
return -EINVAL;
}
if (work->tcon->id != tree_id) {
pr_err("tree id(%u) is different with id(%u) in first operation\n",
tree_id, work->tcon->id);
return -EINVAL;
}
return 1;
}
work->tcon = ksmbd_tree_conn_lookup(work->sess, tree_id);
if (!work->tcon) {
pr_err("Invalid tid %d\n", tree_id);
return -EINVAL;
return -ENOENT;
}
return 1;
@@ -569,7 +586,6 @@ int smb2_check_user_session(struct ksmbd_work *work)
unsigned int cmd = conn->ops->get_cmd_val(work);
unsigned long long sess_id;
work->sess = NULL;
/*
* SMB2_ECHO, SMB2_NEGOTIATE, SMB2_SESSION_SETUP command do not
* require a session id, so no need to validate user session's for
@@ -580,15 +596,33 @@ int smb2_check_user_session(struct ksmbd_work *work)
return 0;
if (!ksmbd_conn_good(work))
return -EINVAL;
return -EIO;
sess_id = le64_to_cpu(req_hdr->SessionId);
/*
* If request is not the first in Compound request,
* Just validate session id in header with work->sess->id.
*/
if (work->next_smb2_rcv_hdr_off) {
if (!work->sess) {
pr_err("The first operation in the compound does not have sess\n");
return -EINVAL;
}
if (work->sess->id != sess_id) {
pr_err("session id(%llu) is different with the first operation(%lld)\n",
sess_id, work->sess->id);
return -EINVAL;
}
return 1;
}
/* Check for validity of user session */
work->sess = ksmbd_session_lookup_all(conn, sess_id);
if (work->sess)
return 1;
ksmbd_debug(SMB, "Invalid user session, Uid %llu\n", sess_id);
return -EINVAL;
return -ENOENT;
}
static void destroy_previous_session(struct ksmbd_conn *conn,

View File

@@ -2984,8 +2984,8 @@ struct dentry *lock_rename(struct dentry *p1, struct dentry *p2)
return p;
}
inode_lock_nested(p1->d_inode, I_MUTEX_PARENT);
inode_lock_nested(p2->d_inode, I_MUTEX_PARENT2);
lock_two_inodes(p1->d_inode, p2->d_inode,
I_MUTEX_PARENT, I_MUTEX_PARENT2);
return NULL;
}
EXPORT_SYMBOL(lock_rename);
@@ -4618,7 +4618,7 @@ SYSCALL_DEFINE2(link, const char __user *, oldname, const char __user *, newname
* sb->s_vfs_rename_mutex. We might be more accurate, but that's another
* story.
* c) we have to lock _four_ objects - parents and victim (if it exists),
* and source (if it is not a directory).
* and source.
* And that - after we got ->i_mutex on parents (until then we don't know
* whether the target exists). Solution: try to be smart with locking
* order for inodes. We rely on the fact that tree topology may change
@@ -4702,10 +4702,16 @@ int vfs_rename(struct renamedata *rd)
take_dentry_name_snapshot(&old_name, old_dentry);
dget(new_dentry);
if (!is_dir || (flags & RENAME_EXCHANGE))
lock_two_nondirectories(source, target);
else if (target)
inode_lock(target);
/*
* Lock all moved children. Moved directories may need to change parent
* pointer so they need the lock to prevent against concurrent
* directory changes moving parent pointer. For regular files we've
* historically always done this. The lockdep locking subclasses are
* somewhat arbitrary but RENAME_EXCHANGE in particular can swap
* regular files and directories so it's difficult to tell which
* subclasses to use.
*/
lock_two_inodes(source, target, I_MUTEX_NORMAL, I_MUTEX_NONDIR2);
error = -EPERM;
if (IS_SWAPFILE(source) || (target && IS_SWAPFILE(target)))
@@ -4753,9 +4759,8 @@ int vfs_rename(struct renamedata *rd)
d_exchange(old_dentry, new_dentry);
}
out:
if (!is_dir || (flags & RENAME_EXCHANGE))
unlock_two_nondirectories(source, target);
else if (target)
inode_unlock(source);
if (target)
inode_unlock(target);
dput(new_dentry);
if (!error) {

View File

@@ -3816,7 +3816,7 @@ nfsd4_encode_open(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_op
p = xdr_reserve_space(xdr, 32);
if (!p)
return nfserr_resource;
*p++ = cpu_to_be32(0);
*p++ = cpu_to_be32(open->op_recall);
/*
* TODO: space_limit's in delegations

View File

@@ -1337,8 +1337,11 @@ static int fanotify_test_fid(struct path *path, __kernel_fsid_t *fsid)
return 0;
}
static int fanotify_events_supported(struct path *path, __u64 mask)
static int fanotify_events_supported(struct path *path, __u64 mask,
unsigned int flags)
{
unsigned int mark_type = flags & FANOTIFY_MARK_TYPE_BITS;
/*
* Some filesystems such as 'proc' acquire unusual locks when opening
* files. For them fanotify permission events have high chances of
@@ -1350,6 +1353,21 @@ static int fanotify_events_supported(struct path *path, __u64 mask)
if (mask & FANOTIFY_PERM_EVENTS &&
path->mnt->mnt_sb->s_type->fs_flags & FS_DISALLOW_NOTIFY_PERM)
return -EINVAL;
/*
* mount and sb marks are not allowed on kernel internal pseudo fs,
* like pipe_mnt, because that would subscribe to events on all the
* anonynous pipes in the system.
*
* SB_NOUSER covers all of the internal pseudo fs whose objects are not
* exposed to user's mount namespace, but there are other SB_KERNMOUNT
* fs, like nsfs, debugfs, for which the value of allowing sb and mount
* mark is questionable. For now we leave them alone.
*/
if (mark_type != FAN_MARK_INODE &&
path->mnt->mnt_sb->s_flags & SB_NOUSER)
return -EINVAL;
return 0;
}
@@ -1476,7 +1494,7 @@ static int do_fanotify_mark(int fanotify_fd, unsigned int flags, __u64 mask,
goto fput_and_out;
if (flags & FAN_MARK_ADD) {
ret = fanotify_events_supported(&path, mask);
ret = fanotify_events_supported(&path, mask, flags);
if (ret)
goto path_put_and_out;
}

View File

@@ -178,6 +178,9 @@ static ssize_t ntfs_list_ea(struct ntfs_inode *ni, char *buffer,
for (ret = 0, off = 0; off < size; off += unpacked_ea_size(ea)) {
ea = Add2Ptr(ea_all, off);
if (!ea->name_len)
break;
if (buffer) {
if (ret + ea->name_len + 1 > bytes_per_buffer) {
err = -ERANGE;

View File

@@ -453,7 +453,15 @@ struct posix_acl *ovl_get_acl(struct inode *inode, int type, bool rcu)
const struct cred *old_cred;
struct posix_acl *acl;
if (!IS_ENABLED(CONFIG_FS_POSIX_ACL) || !IS_POSIXACL(realinode))
if (!IS_ENABLED(CONFIG_FS_POSIX_ACL))
return NULL;
if (!realinode) {
WARN_ON(!rcu);
return ERR_PTR(-ECHILD);
}
if (!IS_POSIXACL(realinode))
return NULL;
if (rcu)

View File

@@ -274,7 +274,7 @@ int ramfs_init_fs_context(struct fs_context *fc)
return 0;
}
static void ramfs_kill_sb(struct super_block *sb)
void ramfs_kill_sb(struct super_block *sb)
{
kfree(sb->s_fs_info);
kill_litter_super(sb);

View File

@@ -7,6 +7,7 @@
struct inode *ramfs_get_inode(struct super_block *sb, const struct inode *dir,
umode_t mode, dev_t dev);
extern int ramfs_init_fs_context(struct fs_context *fc);
extern void ramfs_kill_sb(struct super_block *sb);
#ifdef CONFIG_MMU
static inline int

View File

@@ -69,7 +69,6 @@ enum {
WORK_OFFQ_FLAG_BASE = WORK_STRUCT_COLOR_SHIFT,
__WORK_OFFQ_CANCELING = WORK_OFFQ_FLAG_BASE,
WORK_OFFQ_CANCELING = (1 << __WORK_OFFQ_CANCELING),
/*
* When a work item is off queue, its high bits point to the last
@@ -80,12 +79,6 @@ enum {
WORK_OFFQ_POOL_SHIFT = WORK_OFFQ_FLAG_BASE + WORK_OFFQ_FLAG_BITS,
WORK_OFFQ_LEFT = BITS_PER_LONG - WORK_OFFQ_POOL_SHIFT,
WORK_OFFQ_POOL_BITS = WORK_OFFQ_LEFT <= 31 ? WORK_OFFQ_LEFT : 31,
WORK_OFFQ_POOL_NONE = (1LU << WORK_OFFQ_POOL_BITS) - 1,
/* convenience constants */
WORK_STRUCT_FLAG_MASK = (1UL << WORK_STRUCT_FLAG_BITS) - 1,
WORK_STRUCT_WQ_DATA_MASK = ~WORK_STRUCT_FLAG_MASK,
WORK_STRUCT_NO_POOL = (unsigned long)WORK_OFFQ_POOL_NONE << WORK_OFFQ_POOL_SHIFT,
/* bit mask for work_busy() return values */
WORK_BUSY_PENDING = 1 << 0,
@@ -95,6 +88,14 @@ enum {
WORKER_DESC_LEN = 24,
};
/* Convenience constants - of type 'unsigned long', not 'enum'! */
#define WORK_OFFQ_CANCELING (1ul << __WORK_OFFQ_CANCELING)
#define WORK_OFFQ_POOL_NONE ((1ul << WORK_OFFQ_POOL_BITS) - 1)
#define WORK_STRUCT_NO_POOL (WORK_OFFQ_POOL_NONE << WORK_OFFQ_POOL_SHIFT)
#define WORK_STRUCT_FLAG_MASK ((1ul << WORK_STRUCT_FLAG_BITS) - 1)
#define WORK_STRUCT_WQ_DATA_MASK (~WORK_STRUCT_FLAG_MASK)
struct work_struct {
atomic_long_t data;
struct list_head entry;

View File

@@ -109,7 +109,7 @@ struct autofs_dev_ioctl {
struct args_ismountpoint ismountpoint;
};
char path[0];
char path[];
};
static inline void init_autofs_dev_ioctl(struct autofs_dev_ioctl *in)

View File

@@ -2217,9 +2217,12 @@ static void tctx_task_work(struct callback_head *cb)
}
req->io_task_work.func(req, &locked);
node = next;
if (unlikely(need_resched())) {
ctx_flush_and_put(ctx, &locked);
ctx = NULL;
cond_resched();
}
} while (node);
cond_resched();
}
ctx_flush_and_put(ctx, &locked);
@@ -7796,7 +7799,7 @@ static inline int io_cqring_wait_schedule(struct io_ring_ctx *ctx,
struct io_wait_queue *iowq,
ktime_t *timeout)
{
int ret;
int token, ret;
/* make sure we run task_work before checking for signals */
ret = io_run_task_work_sig();
@@ -7806,9 +7809,17 @@ static inline int io_cqring_wait_schedule(struct io_ring_ctx *ctx,
if (test_bit(0, &ctx->check_cq_overflow))
return 1;
/*
* Use io_schedule_prepare/finish, so cpufreq can take into account
* that the task is waiting for IO - turns out to be important for low
* QD IO.
*/
token = io_schedule_prepare();
ret = 1;
if (!schedule_hrtimeout(timeout, HRTIMER_MODE_ABS))
return -ETIME;
return 1;
ret = -ETIME;
io_schedule_finish(token);
return ret;
}
/*
@@ -9714,7 +9725,18 @@ static void io_ring_exit_work(struct work_struct *work)
/* there is little hope left, don't run it too often */
interval = HZ * 60;
}
} while (!wait_for_completion_timeout(&ctx->ref_comp, interval));
/*
* This is really an uninterruptible wait, as it has to be
* complete. But it's also run from a kworker, which doesn't
* take signals, so it's fine to make it interruptible. This
* avoids scenarios where we knowingly can wait much longer
* on completions, for example if someone does a SIGSTOP on
* a task that needs to finish task_work to make this loop
* complete. That's a synthetic situation that should not
* cause a stuck task backtrace, and hence a potential panic
* on stuck tasks if that is enabled.
*/
} while (!wait_for_completion_interruptible_timeout(&ctx->ref_comp, interval));
init_completion(&exit.completion);
init_task_work(&exit.task_work, io_tctx_exit_cb);
@@ -9739,7 +9761,12 @@ static void io_ring_exit_work(struct work_struct *work)
wake_up_process(node->task);
mutex_unlock(&ctx->uring_lock);
wait_for_completion(&exit.completion);
/*
* See comment above for
* wait_for_completion_interruptible_timeout() on why this
* wait is marked as interruptible.
*/
wait_for_completion_interruptible(&exit.completion);
mutex_lock(&ctx->uring_lock);
}
mutex_unlock(&ctx->uring_lock);

View File

@@ -3761,8 +3761,9 @@ continue_func:
verbose(env, "verifier bug. subprog has tail_call and async cb\n");
return -EFAULT;
}
/* async callbacks don't increase bpf prog stack size */
continue;
/* async callbacks don't increase bpf prog stack size unless called directly */
if (!bpf_pseudo_call(insn + i))
continue;
}
i = next_insn;

View File

@@ -725,6 +725,7 @@ static int enable_trace_eprobe(struct trace_event_call *call,
struct trace_eprobe *ep;
bool enabled;
int ret = 0;
int cnt = 0;
tp = trace_probe_primary_from_call(call);
if (WARN_ON_ONCE(!tp))
@@ -748,12 +749,25 @@ static int enable_trace_eprobe(struct trace_event_call *call,
if (ret)
break;
enabled = true;
cnt++;
}
if (ret) {
/* Failed to enable one of them. Roll back all */
if (enabled)
disable_eprobe(ep, file->tr);
if (enabled) {
/*
* It's a bug if one failed for something other than memory
* not being available but another eprobe succeeded.
*/
WARN_ON_ONCE(ret != -ENOMEM);
list_for_each_entry(pos, trace_probe_probe_list(tp), list) {
ep = container_of(pos, struct trace_eprobe, tp);
disable_eprobe(ep, file->tr);
if (!--cnt)
break;
}
}
if (file)
trace_probe_remove_file(tp, file);
else

View File

@@ -704,12 +704,17 @@ static void clear_work_data(struct work_struct *work)
set_work_data(work, WORK_STRUCT_NO_POOL, 0);
}
static inline struct pool_workqueue *work_struct_pwq(unsigned long data)
{
return (struct pool_workqueue *)(data & WORK_STRUCT_WQ_DATA_MASK);
}
static struct pool_workqueue *get_work_pwq(struct work_struct *work)
{
unsigned long data = atomic_long_read(&work->data);
if (data & WORK_STRUCT_PWQ)
return (void *)(data & WORK_STRUCT_WQ_DATA_MASK);
return work_struct_pwq(data);
else
return NULL;
}
@@ -737,8 +742,7 @@ static struct worker_pool *get_work_pool(struct work_struct *work)
assert_rcu_or_pool_mutex();
if (data & WORK_STRUCT_PWQ)
return ((struct pool_workqueue *)
(data & WORK_STRUCT_WQ_DATA_MASK))->pool;
return work_struct_pwq(data)->pool;
pool_id = data >> WORK_OFFQ_POOL_SHIFT;
if (pool_id == WORK_OFFQ_POOL_NONE)
@@ -759,8 +763,7 @@ static int get_work_pool_id(struct work_struct *work)
unsigned long data = atomic_long_read(&work->data);
if (data & WORK_STRUCT_PWQ)
return ((struct pool_workqueue *)
(data & WORK_STRUCT_WQ_DATA_MASK))->pool->id;
return work_struct_pwq(data)->pool->id;
return data >> WORK_OFFQ_POOL_SHIFT;
}

View File

@@ -4044,7 +4044,7 @@ static struct file_system_type shmem_fs_type = {
.name = "tmpfs",
.init_fs_context = ramfs_init_fs_context,
.parameters = ramfs_fs_parameters,
.kill_sb = kill_litter_super,
.kill_sb = ramfs_kill_sb,
.fs_flags = FS_USERNS_MOUNT,
};

View File

@@ -157,8 +157,9 @@ void br_manage_promisc(struct net_bridge *br)
* This lets us disable promiscuous mode and write
* this config to hw.
*/
if (br->auto_cnt == 0 ||
(br->auto_cnt == 1 && br_auto_port(p)))
if ((p->dev->priv_flags & IFF_UNICAST_FLT) &&
(br->auto_cnt == 0 ||
(br->auto_cnt == 1 && br_auto_port(p))))
br_port_clear_promisc(p);
else
br_port_set_promisc(p);

View File

@@ -3906,6 +3906,11 @@ struct sk_buff *skb_segment_list(struct sk_buff *skb,
skb_push(skb, -skb_network_offset(skb) + offset);
/* Ensure the head is writeable before touching the shared info */
err = skb_unclone(skb, GFP_ATOMIC);
if (err)
goto err_linearize;
skb_shinfo(skb)->frag_list = NULL;
while (list_skb) {

View File

@@ -100,8 +100,8 @@ static void sja1105_meta_unpack(const struct sk_buff *skb,
* a unified unpacking command for both device series.
*/
packing(buf, &meta->tstamp, 31, 0, 4, UNPACK, 0);
packing(buf + 4, &meta->dmac_byte_4, 7, 0, 1, UNPACK, 0);
packing(buf + 5, &meta->dmac_byte_3, 7, 0, 1, UNPACK, 0);
packing(buf + 4, &meta->dmac_byte_3, 7, 0, 1, UNPACK, 0);
packing(buf + 5, &meta->dmac_byte_4, 7, 0, 1, UNPACK, 0);
packing(buf + 6, &meta->source_port, 7, 0, 1, UNPACK, 0);
packing(buf + 7, &meta->switch_id, 7, 0, 1, UNPACK, 0);
}

View File

@@ -3585,8 +3585,11 @@ static int tcp_ack_update_window(struct sock *sk, const struct sk_buff *skb, u32
static bool __tcp_oow_rate_limited(struct net *net, int mib_idx,
u32 *last_oow_ack_time)
{
if (*last_oow_ack_time) {
s32 elapsed = (s32)(tcp_jiffies32 - *last_oow_ack_time);
/* Paired with the WRITE_ONCE() in this function. */
u32 val = READ_ONCE(*last_oow_ack_time);
if (val) {
s32 elapsed = (s32)(tcp_jiffies32 - val);
if (0 <= elapsed &&
elapsed < READ_ONCE(net->ipv4.sysctl_tcp_invalid_ratelimit)) {
@@ -3595,7 +3598,10 @@ static bool __tcp_oow_rate_limited(struct net *net, int mib_idx,
}
}
*last_oow_ack_time = tcp_jiffies32;
/* Paired with the prior READ_ONCE() and with itself,
* as we might be lockless.
*/
WRITE_ONCE(*last_oow_ack_time, tcp_jiffies32);
return false; /* not rate-limited: go ahead, send dupack now! */
}

View File

@@ -325,9 +325,8 @@ static void addrconf_del_dad_work(struct inet6_ifaddr *ifp)
static void addrconf_mod_rs_timer(struct inet6_dev *idev,
unsigned long when)
{
if (!timer_pending(&idev->rs_timer))
if (!mod_timer(&idev->rs_timer, jiffies + when))
in6_dev_hold(idev);
mod_timer(&idev->rs_timer, jiffies + when);
}
static void addrconf_mod_dad_work(struct inet6_ifaddr *ifp,

Some files were not shown because too many files have changed in this diff Show More