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:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
|
||||
@@ -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
|
||||
-------------------------
|
||||
|
||||
|
||||
@@ -11,9 +11,9 @@
|
||||
dma@7984000 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
qpic-nand@79b0000 {
|
||||
status = "okay";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&nand {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
@@ -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";
|
||||
};
|
||||
|
||||
@@ -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";
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
****************************************************************************/
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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' \
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
@@ -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 = {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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 = {
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -1269,7 +1269,9 @@ int btrfs_quota_disable(struct btrfs_fs_info *fs_info)
|
||||
goto out;
|
||||
}
|
||||
|
||||
spin_lock(&fs_info->trans_lock);
|
||||
list_del("a_root->dirty_list);
|
||||
spin_unlock(&fs_info->trans_lock);
|
||||
|
||||
btrfs_tree_lock(quota_root->node);
|
||||
btrfs_clean_tree_block(quota_root->node);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
42
fs/inode.c
42
fs/inode.c
@@ -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
|
||||
*
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
25
fs/namei.c
25
fs/namei.c
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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! */
|
||||
}
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user