mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-05 02:21:52 +09:00
Merge 0264d6b73e ("can: ems_pci: move ASIX AX99100 ids to pci_ids.h") into android14-6.1-lts
Steps on the way to 6.1.129 Resolves merge conflicts in: drivers/i3c/master/i3c-master-cdns.c include/linux/iommu.h net/ipv4/icmp.c Change-Id: I27a81ad93ee7a865b5eb17d7866220fd3cf0bb11 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
@@ -42,6 +42,8 @@ struct pt_regs {
|
||||
unsigned long trap_a0;
|
||||
unsigned long trap_a1;
|
||||
unsigned long trap_a2;
|
||||
/* This makes the stack 16-byte aligned as GCC expects */
|
||||
unsigned long __pad0;
|
||||
/* These are saved by PAL-code: */
|
||||
unsigned long ps;
|
||||
unsigned long pc;
|
||||
|
||||
@@ -32,7 +32,9 @@ void foo(void)
|
||||
DEFINE(CRED_EGID, offsetof(struct cred, egid));
|
||||
BLANK();
|
||||
|
||||
DEFINE(SP_OFF, offsetof(struct pt_regs, ps));
|
||||
DEFINE(SIZEOF_PT_REGS, sizeof(struct pt_regs));
|
||||
DEFINE(SWITCH_STACK_SIZE, sizeof(struct switch_stack));
|
||||
DEFINE(PT_PTRACED, PT_PTRACED);
|
||||
DEFINE(CLONE_VM, CLONE_VM);
|
||||
DEFINE(CLONE_UNTRACED, CLONE_UNTRACED);
|
||||
|
||||
@@ -15,10 +15,6 @@
|
||||
.set noat
|
||||
.cfi_sections .debug_frame
|
||||
|
||||
/* Stack offsets. */
|
||||
#define SP_OFF 184
|
||||
#define SWITCH_STACK_SIZE 320
|
||||
|
||||
.macro CFI_START_OSF_FRAME func
|
||||
.align 4
|
||||
.globl \func
|
||||
@@ -199,8 +195,8 @@ CFI_END_OSF_FRAME entArith
|
||||
CFI_START_OSF_FRAME entMM
|
||||
SAVE_ALL
|
||||
/* save $9 - $15 so the inline exception code can manipulate them. */
|
||||
subq $sp, 56, $sp
|
||||
.cfi_adjust_cfa_offset 56
|
||||
subq $sp, 64, $sp
|
||||
.cfi_adjust_cfa_offset 64
|
||||
stq $9, 0($sp)
|
||||
stq $10, 8($sp)
|
||||
stq $11, 16($sp)
|
||||
@@ -215,7 +211,7 @@ CFI_START_OSF_FRAME entMM
|
||||
.cfi_rel_offset $13, 32
|
||||
.cfi_rel_offset $14, 40
|
||||
.cfi_rel_offset $15, 48
|
||||
addq $sp, 56, $19
|
||||
addq $sp, 64, $19
|
||||
/* handle the fault */
|
||||
lda $8, 0x3fff
|
||||
bic $sp, $8, $8
|
||||
@@ -228,7 +224,7 @@ CFI_START_OSF_FRAME entMM
|
||||
ldq $13, 32($sp)
|
||||
ldq $14, 40($sp)
|
||||
ldq $15, 48($sp)
|
||||
addq $sp, 56, $sp
|
||||
addq $sp, 64, $sp
|
||||
.cfi_restore $9
|
||||
.cfi_restore $10
|
||||
.cfi_restore $11
|
||||
@@ -236,7 +232,7 @@ CFI_START_OSF_FRAME entMM
|
||||
.cfi_restore $13
|
||||
.cfi_restore $14
|
||||
.cfi_restore $15
|
||||
.cfi_adjust_cfa_offset -56
|
||||
.cfi_adjust_cfa_offset -64
|
||||
/* finish up the syscall as normal. */
|
||||
br ret_from_sys_call
|
||||
CFI_END_OSF_FRAME entMM
|
||||
@@ -383,8 +379,8 @@ entUnaUser:
|
||||
.cfi_restore $0
|
||||
.cfi_adjust_cfa_offset -256
|
||||
SAVE_ALL /* setup normal kernel stack */
|
||||
lda $sp, -56($sp)
|
||||
.cfi_adjust_cfa_offset 56
|
||||
lda $sp, -64($sp)
|
||||
.cfi_adjust_cfa_offset 64
|
||||
stq $9, 0($sp)
|
||||
stq $10, 8($sp)
|
||||
stq $11, 16($sp)
|
||||
@@ -400,7 +396,7 @@ entUnaUser:
|
||||
.cfi_rel_offset $14, 40
|
||||
.cfi_rel_offset $15, 48
|
||||
lda $8, 0x3fff
|
||||
addq $sp, 56, $19
|
||||
addq $sp, 64, $19
|
||||
bic $sp, $8, $8
|
||||
jsr $26, do_entUnaUser
|
||||
ldq $9, 0($sp)
|
||||
@@ -410,7 +406,7 @@ entUnaUser:
|
||||
ldq $13, 32($sp)
|
||||
ldq $14, 40($sp)
|
||||
ldq $15, 48($sp)
|
||||
lda $sp, 56($sp)
|
||||
lda $sp, 64($sp)
|
||||
.cfi_restore $9
|
||||
.cfi_restore $10
|
||||
.cfi_restore $11
|
||||
@@ -418,7 +414,7 @@ entUnaUser:
|
||||
.cfi_restore $13
|
||||
.cfi_restore $14
|
||||
.cfi_restore $15
|
||||
.cfi_adjust_cfa_offset -56
|
||||
.cfi_adjust_cfa_offset -64
|
||||
br ret_from_sys_call
|
||||
CFI_END_OSF_FRAME entUna
|
||||
|
||||
|
||||
@@ -707,7 +707,7 @@ s_reg_to_mem (unsigned long s_reg)
|
||||
static int unauser_reg_offsets[32] = {
|
||||
R(r0), R(r1), R(r2), R(r3), R(r4), R(r5), R(r6), R(r7), R(r8),
|
||||
/* r9 ... r15 are stored in front of regs. */
|
||||
-56, -48, -40, -32, -24, -16, -8,
|
||||
-64, -56, -48, -40, -32, -24, -16, /* padding at -8 */
|
||||
R(r16), R(r17), R(r18),
|
||||
R(r19), R(r20), R(r21), R(r22), R(r23), R(r24), R(r25), R(r26),
|
||||
R(r27), R(r28), R(gp),
|
||||
|
||||
@@ -78,8 +78,8 @@ __load_new_mm_context(struct mm_struct *next_mm)
|
||||
|
||||
/* Macro for exception fixup code to access integer registers. */
|
||||
#define dpf_reg(r) \
|
||||
(((unsigned long *)regs)[(r) <= 8 ? (r) : (r) <= 15 ? (r)-16 : \
|
||||
(r) <= 18 ? (r)+10 : (r)-10])
|
||||
(((unsigned long *)regs)[(r) <= 8 ? (r) : (r) <= 15 ? (r)-17 : \
|
||||
(r) <= 18 ? (r)+11 : (r)-10])
|
||||
|
||||
asmlinkage void
|
||||
do_page_fault(unsigned long address, unsigned long mmcsr,
|
||||
|
||||
@@ -1558,7 +1558,7 @@
|
||||
};
|
||||
|
||||
dce-fabric@de00000 {
|
||||
compatible = "nvidia,tegra234-sce-fabric";
|
||||
compatible = "nvidia,tegra234-dce-fabric";
|
||||
reg = <0xde00000 0x40000>;
|
||||
interrupts = <GIC_SPI 381 IRQ_TYPE_LEVEL_HIGH>;
|
||||
status = "okay";
|
||||
|
||||
@@ -38,6 +38,7 @@ SECTIONS
|
||||
*/
|
||||
/DISCARD/ : {
|
||||
*(.note.GNU-stack .note.gnu.property)
|
||||
*(.ARM.attributes)
|
||||
}
|
||||
.note : { *(.note.*) } :text :note
|
||||
|
||||
|
||||
@@ -182,6 +182,7 @@ SECTIONS
|
||||
/DISCARD/ : {
|
||||
*(.interp .dynamic)
|
||||
*(.dynsym .dynstr .hash .gnu.hash)
|
||||
*(.ARM.attributes)
|
||||
}
|
||||
|
||||
. = KIMAGE_VADDR;
|
||||
|
||||
@@ -173,7 +173,6 @@ EXPORT_SYMBOL_GPL(arch_static_call_transform);
|
||||
noinstr void __static_call_update_early(void *tramp, void *func)
|
||||
{
|
||||
BUG_ON(system_state != SYSTEM_BOOTING);
|
||||
BUG_ON(!early_boot_irqs_disabled);
|
||||
BUG_ON(static_call_initialized);
|
||||
__text_gen_insn(tramp, JMP32_INSN_OPCODE, tramp, func, JMP32_INSN_SIZE);
|
||||
sync_core();
|
||||
|
||||
@@ -51,13 +51,25 @@ int mac_partition(struct parsed_partitions *state)
|
||||
}
|
||||
secsize = be16_to_cpu(md->block_size);
|
||||
put_dev_sector(sect);
|
||||
|
||||
/*
|
||||
* If the "block size" is not a power of 2, things get weird - we might
|
||||
* end up with a partition straddling a sector boundary, so we wouldn't
|
||||
* be able to read a partition entry with read_part_sector().
|
||||
* Real block sizes are probably (?) powers of two, so just require
|
||||
* that.
|
||||
*/
|
||||
if (!is_power_of_2(secsize))
|
||||
return -1;
|
||||
datasize = round_down(secsize, 512);
|
||||
data = read_part_sector(state, datasize / 512, §);
|
||||
if (!data)
|
||||
return -1;
|
||||
partoffset = secsize % 512;
|
||||
if (partoffset + sizeof(*part) > datasize)
|
||||
if (partoffset + sizeof(*part) > datasize) {
|
||||
put_dev_sector(sect);
|
||||
return -1;
|
||||
}
|
||||
part = (struct mac_partition *) (data + partoffset);
|
||||
if (be16_to_cpu(part->signature) != MAC_PARTITION_MAGIC) {
|
||||
put_dev_sector(sect);
|
||||
@@ -110,8 +122,8 @@ int mac_partition(struct parsed_partitions *state)
|
||||
int i, l;
|
||||
|
||||
goodness++;
|
||||
l = strlen(part->name);
|
||||
if (strcmp(part->name, "/") == 0)
|
||||
l = strnlen(part->name, sizeof(part->name));
|
||||
if (strncmp(part->name, "/", sizeof(part->name)) == 0)
|
||||
goodness++;
|
||||
for (i = 0; i <= l - 4; ++i) {
|
||||
if (strncasecmp(part->name + i, "root",
|
||||
|
||||
@@ -1059,6 +1059,7 @@ err_alloc:
|
||||
kfree(d->wake_buf);
|
||||
kfree(d->mask_buf_def);
|
||||
kfree(d->mask_buf);
|
||||
kfree(d->main_status_buf);
|
||||
kfree(d->status_buf);
|
||||
kfree(d->status_reg_buf);
|
||||
if (d->virt_buf) {
|
||||
@@ -1139,6 +1140,7 @@ void regmap_del_irq_chip(int irq, struct regmap_irq_chip_data *d)
|
||||
kfree(d->wake_buf);
|
||||
kfree(d->mask_buf_def);
|
||||
kfree(d->mask_buf);
|
||||
kfree(d->main_status_buf);
|
||||
kfree(d->status_reg_buf);
|
||||
kfree(d->status_buf);
|
||||
if (d->config_buf) {
|
||||
|
||||
@@ -835,13 +835,15 @@ char * __init efi_md_typeattr_format(char *buf, size_t size,
|
||||
EFI_MEMORY_WB | EFI_MEMORY_UCE | EFI_MEMORY_RO |
|
||||
EFI_MEMORY_WP | EFI_MEMORY_RP | EFI_MEMORY_XP |
|
||||
EFI_MEMORY_NV | EFI_MEMORY_SP | EFI_MEMORY_CPU_CRYPTO |
|
||||
EFI_MEMORY_RUNTIME | EFI_MEMORY_MORE_RELIABLE))
|
||||
EFI_MEMORY_MORE_RELIABLE | EFI_MEMORY_HOT_PLUGGABLE |
|
||||
EFI_MEMORY_RUNTIME))
|
||||
snprintf(pos, size, "|attr=0x%016llx]",
|
||||
(unsigned long long)attr);
|
||||
else
|
||||
snprintf(pos, size,
|
||||
"|%3s|%2s|%2s|%2s|%2s|%2s|%2s|%2s|%2s|%3s|%2s|%2s|%2s|%2s]",
|
||||
"|%3s|%2s|%2s|%2s|%2s|%2s|%2s|%2s|%2s|%2s|%3s|%2s|%2s|%2s|%2s]",
|
||||
attr & EFI_MEMORY_RUNTIME ? "RUN" : "",
|
||||
attr & EFI_MEMORY_HOT_PLUGGABLE ? "HP" : "",
|
||||
attr & EFI_MEMORY_MORE_RELIABLE ? "MR" : "",
|
||||
attr & EFI_MEMORY_CPU_CRYPTO ? "CC" : "",
|
||||
attr & EFI_MEMORY_SP ? "SP" : "",
|
||||
|
||||
@@ -25,6 +25,9 @@ static unsigned long get_entry_num_slots(efi_memory_desc_t *md,
|
||||
if (md->type != EFI_CONVENTIONAL_MEMORY)
|
||||
return 0;
|
||||
|
||||
if (md->attribute & EFI_MEMORY_HOT_PLUGGABLE)
|
||||
return 0;
|
||||
|
||||
if (efi_soft_reserve_enabled() &&
|
||||
(md->attribute & EFI_MEMORY_SP))
|
||||
return 0;
|
||||
|
||||
@@ -53,6 +53,9 @@ efi_status_t efi_low_alloc_above(unsigned long size, unsigned long align,
|
||||
if (desc->type != EFI_CONVENTIONAL_MEMORY)
|
||||
continue;
|
||||
|
||||
if (desc->attribute & EFI_MEMORY_HOT_PLUGGABLE)
|
||||
continue;
|
||||
|
||||
if (efi_soft_reserve_enabled() &&
|
||||
(desc->attribute & EFI_MEMORY_SP))
|
||||
continue;
|
||||
|
||||
@@ -191,7 +191,7 @@ static void stmpe_gpio_irq_sync_unlock(struct irq_data *d)
|
||||
[REG_IE][CSB] = STMPE_IDX_IEGPIOR_CSB,
|
||||
[REG_IE][MSB] = STMPE_IDX_IEGPIOR_MSB,
|
||||
};
|
||||
int i, j;
|
||||
int ret, i, j;
|
||||
|
||||
/*
|
||||
* STMPE1600: to be able to get IRQ from pins,
|
||||
@@ -199,8 +199,16 @@ static void stmpe_gpio_irq_sync_unlock(struct irq_data *d)
|
||||
* GPSR or GPCR registers
|
||||
*/
|
||||
if (stmpe->partnum == STMPE1600) {
|
||||
stmpe_reg_read(stmpe, stmpe->regs[STMPE_IDX_GPMR_LSB]);
|
||||
stmpe_reg_read(stmpe, stmpe->regs[STMPE_IDX_GPMR_CSB]);
|
||||
ret = stmpe_reg_read(stmpe, stmpe->regs[STMPE_IDX_GPMR_LSB]);
|
||||
if (ret < 0) {
|
||||
dev_err(stmpe->dev, "Failed to read GPMR_LSB: %d\n", ret);
|
||||
goto err;
|
||||
}
|
||||
ret = stmpe_reg_read(stmpe, stmpe->regs[STMPE_IDX_GPMR_CSB]);
|
||||
if (ret < 0) {
|
||||
dev_err(stmpe->dev, "Failed to read GPMR_CSB: %d\n", ret);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < CACHE_NR_REGS; i++) {
|
||||
@@ -222,6 +230,7 @@ static void stmpe_gpio_irq_sync_unlock(struct irq_data *d)
|
||||
}
|
||||
}
|
||||
|
||||
err:
|
||||
mutex_unlock(&stmpe_gpio->irq_lock);
|
||||
}
|
||||
|
||||
|
||||
@@ -1640,6 +1640,20 @@ static const struct dmi_system_id gpiolib_acpi_quirks[] __initconst = {
|
||||
.ignore_wake = "PNP0C50:00@8",
|
||||
},
|
||||
},
|
||||
{
|
||||
/*
|
||||
* Spurious wakeups from GPIO 11
|
||||
* Found in BIOS 1.04
|
||||
* https://gitlab.freedesktop.org/drm/amd/-/issues/3954
|
||||
*/
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
|
||||
DMI_MATCH(DMI_PRODUCT_FAMILY, "Acer Nitro V 14"),
|
||||
},
|
||||
.driver_data = &(struct acpi_gpiolib_dmi_quirk) {
|
||||
.ignore_interrupt = "AMDI0030:00@11",
|
||||
},
|
||||
},
|
||||
{} /* Terminating entry */
|
||||
};
|
||||
|
||||
|
||||
@@ -599,7 +599,7 @@ void dispc_k2g_set_irqenable(struct dispc_device *dispc, dispc_irq_t mask)
|
||||
{
|
||||
dispc_irq_t old_mask = dispc_k2g_read_irqenable(dispc);
|
||||
|
||||
/* clear the irqstatus for newly enabled irqs */
|
||||
/* clear the irqstatus for irqs that will be enabled */
|
||||
dispc_k2g_clear_irqstatus(dispc, (mask ^ old_mask) & mask);
|
||||
|
||||
dispc_k2g_vp_set_irqenable(dispc, 0, mask);
|
||||
@@ -607,6 +607,9 @@ void dispc_k2g_set_irqenable(struct dispc_device *dispc, dispc_irq_t mask)
|
||||
|
||||
dispc_write(dispc, DISPC_IRQENABLE_SET, (1 << 0) | (1 << 7));
|
||||
|
||||
/* clear the irqstatus for irqs that were disabled */
|
||||
dispc_k2g_clear_irqstatus(dispc, (mask ^ old_mask) & old_mask);
|
||||
|
||||
/* flush posted write */
|
||||
dispc_k2g_read_irqenable(dispc);
|
||||
}
|
||||
@@ -679,24 +682,20 @@ static
|
||||
void dispc_k3_clear_irqstatus(struct dispc_device *dispc, dispc_irq_t clearmask)
|
||||
{
|
||||
unsigned int i;
|
||||
u32 top_clear = 0;
|
||||
|
||||
for (i = 0; i < dispc->feat->num_vps; ++i) {
|
||||
if (clearmask & DSS_IRQ_VP_MASK(i)) {
|
||||
if (clearmask & DSS_IRQ_VP_MASK(i))
|
||||
dispc_k3_vp_write_irqstatus(dispc, i, clearmask);
|
||||
top_clear |= BIT(i);
|
||||
}
|
||||
}
|
||||
for (i = 0; i < dispc->feat->num_planes; ++i) {
|
||||
if (clearmask & DSS_IRQ_PLANE_MASK(i)) {
|
||||
if (clearmask & DSS_IRQ_PLANE_MASK(i))
|
||||
dispc_k3_vid_write_irqstatus(dispc, i, clearmask);
|
||||
top_clear |= BIT(4 + i);
|
||||
}
|
||||
}
|
||||
if (dispc->feat->subrev == DISPC_K2G)
|
||||
return;
|
||||
|
||||
dispc_write(dispc, DISPC_IRQSTATUS, top_clear);
|
||||
/* always clear the top level irqstatus */
|
||||
dispc_write(dispc, DISPC_IRQSTATUS, dispc_read(dispc, DISPC_IRQSTATUS));
|
||||
|
||||
/* Flush posted writes */
|
||||
dispc_read(dispc, DISPC_IRQSTATUS);
|
||||
@@ -742,7 +741,7 @@ static void dispc_k3_set_irqenable(struct dispc_device *dispc,
|
||||
|
||||
old_mask = dispc_k3_read_irqenable(dispc);
|
||||
|
||||
/* clear the irqstatus for newly enabled irqs */
|
||||
/* clear the irqstatus for irqs that will be enabled */
|
||||
dispc_k3_clear_irqstatus(dispc, (old_mask ^ mask) & mask);
|
||||
|
||||
for (i = 0; i < dispc->feat->num_vps; ++i) {
|
||||
@@ -767,6 +766,9 @@ static void dispc_k3_set_irqenable(struct dispc_device *dispc,
|
||||
if (main_disable)
|
||||
dispc_write(dispc, DISPC_IRQENABLE_CLR, main_disable);
|
||||
|
||||
/* clear the irqstatus for irqs that were disabled */
|
||||
dispc_k3_clear_irqstatus(dispc, (old_mask ^ mask) & old_mask);
|
||||
|
||||
/* Flush posted writes */
|
||||
dispc_read(dispc, DISPC_IRQENABLE_SET);
|
||||
}
|
||||
|
||||
@@ -175,6 +175,7 @@ int v3d_perfmon_destroy_ioctl(struct drm_device *dev, void *data,
|
||||
{
|
||||
struct v3d_file_priv *v3d_priv = file_priv->driver_priv;
|
||||
struct drm_v3d_perfmon_destroy *req = data;
|
||||
struct v3d_dev *v3d = v3d_priv->v3d;
|
||||
struct v3d_perfmon *perfmon;
|
||||
|
||||
mutex_lock(&v3d_priv->perfmon.lock);
|
||||
@@ -184,6 +185,10 @@ int v3d_perfmon_destroy_ioctl(struct drm_device *dev, void *data,
|
||||
if (!perfmon)
|
||||
return -EINVAL;
|
||||
|
||||
/* If the active perfmon is being destroyed, stop it first */
|
||||
if (perfmon == v3d->active_perfmon)
|
||||
v3d_perfmon_stop(v3d, perfmon, false);
|
||||
|
||||
v3d_perfmon_put(perfmon);
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -262,6 +262,7 @@
|
||||
#define MSDC_PAD_TUNE_CMD_SEL BIT(21) /* RW */
|
||||
|
||||
#define PAD_DS_TUNE_DLY_SEL BIT(0) /* RW */
|
||||
#define PAD_DS_TUNE_DLY2_SEL BIT(1) /* RW */
|
||||
#define PAD_DS_TUNE_DLY1 GENMASK(6, 2) /* RW */
|
||||
#define PAD_DS_TUNE_DLY2 GENMASK(11, 7) /* RW */
|
||||
#define PAD_DS_TUNE_DLY3 GENMASK(16, 12) /* RW */
|
||||
@@ -307,6 +308,7 @@
|
||||
|
||||
/* EMMC50_PAD_DS_TUNE mask */
|
||||
#define PAD_DS_DLY_SEL BIT(16) /* RW */
|
||||
#define PAD_DS_DLY2_SEL BIT(15) /* RW */
|
||||
#define PAD_DS_DLY1 GENMASK(14, 10) /* RW */
|
||||
#define PAD_DS_DLY3 GENMASK(4, 0) /* RW */
|
||||
|
||||
@@ -2293,13 +2295,23 @@ tune_done:
|
||||
static int msdc_prepare_hs400_tuning(struct mmc_host *mmc, struct mmc_ios *ios)
|
||||
{
|
||||
struct msdc_host *host = mmc_priv(mmc);
|
||||
|
||||
host->hs400_mode = true;
|
||||
|
||||
if (host->top_base)
|
||||
writel(host->hs400_ds_delay,
|
||||
host->top_base + EMMC50_PAD_DS_TUNE);
|
||||
else
|
||||
writel(host->hs400_ds_delay, host->base + PAD_DS_TUNE);
|
||||
if (host->top_base) {
|
||||
if (host->hs400_ds_dly3)
|
||||
sdr_set_field(host->top_base + EMMC50_PAD_DS_TUNE,
|
||||
PAD_DS_DLY3, host->hs400_ds_dly3);
|
||||
if (host->hs400_ds_delay)
|
||||
writel(host->hs400_ds_delay,
|
||||
host->top_base + EMMC50_PAD_DS_TUNE);
|
||||
} else {
|
||||
if (host->hs400_ds_dly3)
|
||||
sdr_set_field(host->base + PAD_DS_TUNE,
|
||||
PAD_DS_TUNE_DLY3, host->hs400_ds_dly3);
|
||||
if (host->hs400_ds_delay)
|
||||
writel(host->hs400_ds_delay, host->base + PAD_DS_TUNE);
|
||||
}
|
||||
/* hs400 mode must set it to 0 */
|
||||
sdr_clr_bits(host->base + MSDC_PATCH_BIT2, MSDC_PATCH_BIT2_CFGCRCSTS);
|
||||
/* to improve read performance, set outstanding to 2 */
|
||||
@@ -2319,14 +2331,11 @@ static int msdc_execute_hs400_tuning(struct mmc_host *mmc, struct mmc_card *card
|
||||
if (host->top_base) {
|
||||
sdr_set_bits(host->top_base + EMMC50_PAD_DS_TUNE,
|
||||
PAD_DS_DLY_SEL);
|
||||
if (host->hs400_ds_dly3)
|
||||
sdr_set_field(host->top_base + EMMC50_PAD_DS_TUNE,
|
||||
PAD_DS_DLY3, host->hs400_ds_dly3);
|
||||
sdr_clr_bits(host->top_base + EMMC50_PAD_DS_TUNE,
|
||||
PAD_DS_DLY2_SEL);
|
||||
} else {
|
||||
sdr_set_bits(host->base + PAD_DS_TUNE, PAD_DS_TUNE_DLY_SEL);
|
||||
if (host->hs400_ds_dly3)
|
||||
sdr_set_field(host->base + PAD_DS_TUNE,
|
||||
PAD_DS_TUNE_DLY3, host->hs400_ds_dly3);
|
||||
sdr_clr_bits(host->base + PAD_DS_TUNE, PAD_DS_TUNE_DLY2_SEL);
|
||||
}
|
||||
|
||||
host->hs400_tuning = true;
|
||||
|
||||
@@ -395,15 +395,16 @@ static int c_can_plat_probe(struct platform_device *pdev)
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "registering %s failed (err=%d)\n",
|
||||
KBUILD_MODNAME, ret);
|
||||
goto exit_free_device;
|
||||
goto exit_pm_runtime;
|
||||
}
|
||||
|
||||
dev_info(&pdev->dev, "%s device registered (regs=%p, irq=%d)\n",
|
||||
KBUILD_MODNAME, priv->base, dev->irq);
|
||||
return 0;
|
||||
|
||||
exit_free_device:
|
||||
exit_pm_runtime:
|
||||
pm_runtime_disable(priv->device);
|
||||
exit_free_device:
|
||||
free_c_can_dev(dev);
|
||||
exit:
|
||||
dev_err(&pdev->dev, "probe failed\n");
|
||||
|
||||
@@ -867,10 +867,12 @@ static void ctucan_err_interrupt(struct net_device *ndev, u32 isr)
|
||||
}
|
||||
break;
|
||||
case CAN_STATE_ERROR_ACTIVE:
|
||||
cf->can_id |= CAN_ERR_CNT;
|
||||
cf->data[1] = CAN_ERR_CRTL_ACTIVE;
|
||||
cf->data[6] = bec.txerr;
|
||||
cf->data[7] = bec.rxerr;
|
||||
if (skb) {
|
||||
cf->can_id |= CAN_ERR_CNT;
|
||||
cf->data[1] = CAN_ERR_CRTL_ACTIVE;
|
||||
cf->data[6] = bec.txerr;
|
||||
cf->data[7] = bec.rxerr;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
netdev_warn(ndev, "unhandled error state (%d:%s)!\n",
|
||||
|
||||
@@ -768,7 +768,9 @@ static void __mlxsw_sp_port_get_stats(struct net_device *dev,
|
||||
err = mlxsw_sp_get_hw_stats_by_group(&hw_stats, &len, grp);
|
||||
if (err)
|
||||
return;
|
||||
mlxsw_sp_port_get_stats_raw(dev, grp, prio, ppcnt_pl);
|
||||
err = mlxsw_sp_port_get_stats_raw(dev, grp, prio, ppcnt_pl);
|
||||
if (err)
|
||||
return;
|
||||
for (i = 0; i < len; i++) {
|
||||
data[data_index + i] = hw_stats[i].getter(ppcnt_pl);
|
||||
if (!hw_stats[i].cells_bytes)
|
||||
|
||||
@@ -345,6 +345,7 @@ static inline int is_omap1510_8250(struct uart_8250_port *pt)
|
||||
|
||||
#ifdef CONFIG_SERIAL_8250_DMA
|
||||
extern int serial8250_tx_dma(struct uart_8250_port *);
|
||||
extern void serial8250_tx_dma_flush(struct uart_8250_port *);
|
||||
extern int serial8250_rx_dma(struct uart_8250_port *);
|
||||
extern void serial8250_rx_dma_flush(struct uart_8250_port *);
|
||||
extern int serial8250_request_dma(struct uart_8250_port *);
|
||||
@@ -377,6 +378,7 @@ static inline int serial8250_tx_dma(struct uart_8250_port *p)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
static inline void serial8250_tx_dma_flush(struct uart_8250_port *p) { }
|
||||
static inline int serial8250_rx_dma(struct uart_8250_port *p)
|
||||
{
|
||||
return -1;
|
||||
|
||||
@@ -133,6 +133,22 @@ err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
void serial8250_tx_dma_flush(struct uart_8250_port *p)
|
||||
{
|
||||
struct uart_8250_dma *dma = p->dma;
|
||||
|
||||
if (!dma->tx_running)
|
||||
return;
|
||||
|
||||
/*
|
||||
* kfifo_reset() has been called by the serial core, avoid
|
||||
* advancing and underflowing in __dma_tx_complete().
|
||||
*/
|
||||
dma->tx_size = 0;
|
||||
|
||||
dmaengine_terminate_async(dma->rxchan);
|
||||
}
|
||||
|
||||
int serial8250_rx_dma(struct uart_8250_port *p)
|
||||
{
|
||||
struct uart_8250_dma *dma = p->dma;
|
||||
|
||||
@@ -1975,7 +1975,6 @@ pci_moxa_setup(struct serial_private *priv,
|
||||
#define PCI_DEVICE_ID_WCH_CH355_4S 0x7173
|
||||
#define PCI_VENDOR_ID_AGESTAR 0x5372
|
||||
#define PCI_DEVICE_ID_AGESTAR_9375 0x6872
|
||||
#define PCI_VENDOR_ID_ASIX 0x9710
|
||||
#define PCI_DEVICE_ID_BROADCOM_TRUMANAGE 0x160a
|
||||
#define PCI_DEVICE_ID_AMCC_ADDIDATA_APCI7800 0x818e
|
||||
|
||||
|
||||
@@ -2558,6 +2558,14 @@ static unsigned int npcm_get_divisor(struct uart_8250_port *up,
|
||||
return DIV_ROUND_CLOSEST(port->uartclk, 16 * baud + 2) - 2;
|
||||
}
|
||||
|
||||
static void serial8250_flush_buffer(struct uart_port *port)
|
||||
{
|
||||
struct uart_8250_port *up = up_to_u8250p(port);
|
||||
|
||||
if (up->dma)
|
||||
serial8250_tx_dma_flush(up);
|
||||
}
|
||||
|
||||
static unsigned int serial8250_do_get_divisor(struct uart_port *port,
|
||||
unsigned int baud,
|
||||
unsigned int *frac)
|
||||
@@ -3273,6 +3281,7 @@ static const struct uart_ops serial8250_pops = {
|
||||
.break_ctl = serial8250_break_ctl,
|
||||
.startup = serial8250_startup,
|
||||
.shutdown = serial8250_shutdown,
|
||||
.flush_buffer = serial8250_flush_buffer,
|
||||
.set_termios = serial8250_set_termios,
|
||||
.set_ldisc = serial8250_set_ldisc,
|
||||
.pm = serial8250_pm,
|
||||
|
||||
@@ -360,7 +360,7 @@ static void acm_process_notification(struct acm *acm, unsigned char *buf)
|
||||
static void acm_ctrl_irq(struct urb *urb)
|
||||
{
|
||||
struct acm *acm = urb->context;
|
||||
struct usb_cdc_notification *dr = urb->transfer_buffer;
|
||||
struct usb_cdc_notification *dr;
|
||||
unsigned int current_size = urb->actual_length;
|
||||
unsigned int expected_size, copy_size, alloc_size;
|
||||
int retval;
|
||||
@@ -387,14 +387,25 @@ static void acm_ctrl_irq(struct urb *urb)
|
||||
|
||||
usb_mark_last_busy(acm->dev);
|
||||
|
||||
if (acm->nb_index)
|
||||
if (acm->nb_index == 0) {
|
||||
/*
|
||||
* The first chunk of a message must contain at least the
|
||||
* notification header with the length field, otherwise we
|
||||
* can't get an expected_size.
|
||||
*/
|
||||
if (current_size < sizeof(struct usb_cdc_notification)) {
|
||||
dev_dbg(&acm->control->dev, "urb too short\n");
|
||||
goto exit;
|
||||
}
|
||||
dr = urb->transfer_buffer;
|
||||
} else {
|
||||
dr = (struct usb_cdc_notification *)acm->notification_buffer;
|
||||
|
||||
}
|
||||
/* size = notification-header + (optional) data */
|
||||
expected_size = sizeof(struct usb_cdc_notification) +
|
||||
le16_to_cpu(dr->wLength);
|
||||
|
||||
if (current_size < expected_size) {
|
||||
if (acm->nb_index != 0 || current_size < expected_size) {
|
||||
/* notification is transmitted fragmented, reassemble */
|
||||
if (acm->nb_size < expected_size) {
|
||||
u8 *new_buffer;
|
||||
@@ -1703,13 +1714,16 @@ static const struct usb_device_id acm_ids[] = {
|
||||
{ USB_DEVICE(0x0870, 0x0001), /* Metricom GS Modem */
|
||||
.driver_info = NO_UNION_NORMAL, /* has no union descriptor */
|
||||
},
|
||||
{ USB_DEVICE(0x045b, 0x023c), /* Renesas USB Download mode */
|
||||
{ USB_DEVICE(0x045b, 0x023c), /* Renesas R-Car H3 USB Download mode */
|
||||
.driver_info = DISABLE_ECHO, /* Don't echo banner */
|
||||
},
|
||||
{ USB_DEVICE(0x045b, 0x0248), /* Renesas USB Download mode */
|
||||
{ USB_DEVICE(0x045b, 0x0247), /* Renesas R-Car D3 USB Download mode */
|
||||
.driver_info = DISABLE_ECHO, /* Don't echo banner */
|
||||
},
|
||||
{ USB_DEVICE(0x045b, 0x024D), /* Renesas USB Download mode */
|
||||
{ USB_DEVICE(0x045b, 0x0248), /* Renesas R-Car M3-N USB Download mode */
|
||||
.driver_info = DISABLE_ECHO, /* Don't echo banner */
|
||||
},
|
||||
{ USB_DEVICE(0x045b, 0x024D), /* Renesas R-Car E3 USB Download mode */
|
||||
.driver_info = DISABLE_ECHO, /* Don't echo banner */
|
||||
},
|
||||
{ USB_DEVICE(0x0e8d, 0x0003), /* FIREFLY, MediaTek Inc; andrey.arapov@gmail.com */
|
||||
|
||||
@@ -1818,6 +1818,17 @@ static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id)
|
||||
desc = intf->cur_altsetting;
|
||||
hdev = interface_to_usbdev(intf);
|
||||
|
||||
/*
|
||||
* The USB 2.0 spec prohibits hubs from having more than one
|
||||
* configuration or interface, and we rely on this prohibition.
|
||||
* Refuse to accept a device that violates it.
|
||||
*/
|
||||
if (hdev->descriptor.bNumConfigurations > 1 ||
|
||||
hdev->actconfig->desc.bNumInterfaces > 1) {
|
||||
dev_err(&intf->dev, "Invalid hub with more than one config or interface\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set default autosuspend delay as 0 to speedup bus suspend,
|
||||
* based on the below considerations:
|
||||
@@ -4718,7 +4729,6 @@ void usb_ep0_reinit(struct usb_device *udev)
|
||||
EXPORT_SYMBOL_GPL(usb_ep0_reinit);
|
||||
|
||||
#define usb_sndaddr0pipe() (PIPE_CONTROL << 30)
|
||||
#define usb_rcvaddr0pipe() ((PIPE_CONTROL << 30) | USB_DIR_IN)
|
||||
|
||||
static int hub_set_address(struct usb_device *udev, int devnum)
|
||||
{
|
||||
@@ -4824,7 +4834,7 @@ static int get_bMaxPacketSize0(struct usb_device *udev,
|
||||
for (i = 0; i < GET_MAXPACKET0_TRIES; ++i) {
|
||||
/* Start with invalid values in case the transfer fails */
|
||||
buf->bDescriptorType = buf->bMaxPacketSize0 = 0;
|
||||
rc = usb_control_msg(udev, usb_rcvaddr0pipe(),
|
||||
rc = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
|
||||
USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
|
||||
USB_DT_DEVICE << 8, 0,
|
||||
buf, size,
|
||||
|
||||
@@ -432,6 +432,9 @@ static const struct usb_device_id usb_quirk_list[] = {
|
||||
{ USB_DEVICE(0x0c45, 0x7056), .driver_info =
|
||||
USB_QUIRK_IGNORE_REMOTE_WAKEUP },
|
||||
|
||||
/* Sony Xperia XZ1 Compact (lilac) smartphone in fastboot mode */
|
||||
{ USB_DEVICE(0x0fce, 0x0dde), .driver_info = USB_QUIRK_NO_LPM },
|
||||
|
||||
/* Action Semiconductor flash disk */
|
||||
{ USB_DEVICE(0x10d6, 0x2200), .driver_info =
|
||||
USB_QUIRK_STRING_FETCH_255 },
|
||||
@@ -522,6 +525,9 @@ static const struct usb_device_id usb_quirk_list[] = {
|
||||
/* Blackmagic Design UltraStudio SDI */
|
||||
{ USB_DEVICE(0x1edb, 0xbd4f), .driver_info = USB_QUIRK_NO_LPM },
|
||||
|
||||
/* Teclast disk */
|
||||
{ USB_DEVICE(0x1f75, 0x0917), .driver_info = USB_QUIRK_NO_LPM },
|
||||
|
||||
/* Hauppauge HVR-950q */
|
||||
{ USB_DEVICE(0x2040, 0x7200), .driver_info =
|
||||
USB_QUIRK_CONFIG_INTF_STRINGS },
|
||||
|
||||
@@ -4613,6 +4613,7 @@ static int dwc2_hsotg_udc_stop(struct usb_gadget *gadget)
|
||||
spin_lock_irqsave(&hsotg->lock, flags);
|
||||
|
||||
hsotg->driver = NULL;
|
||||
hsotg->gadget.dev.of_node = NULL;
|
||||
hsotg->gadget.speed = USB_SPEED_UNKNOWN;
|
||||
hsotg->enabled = 0;
|
||||
|
||||
|
||||
@@ -999,11 +999,11 @@ static int f_midi_bind(struct usb_configuration *c, struct usb_function *f)
|
||||
}
|
||||
|
||||
/* configure the endpoint descriptors ... */
|
||||
ms_out_desc.bLength = USB_DT_MS_ENDPOINT_SIZE(midi->in_ports);
|
||||
ms_out_desc.bNumEmbMIDIJack = midi->in_ports;
|
||||
ms_out_desc.bLength = USB_DT_MS_ENDPOINT_SIZE(midi->out_ports);
|
||||
ms_out_desc.bNumEmbMIDIJack = midi->out_ports;
|
||||
|
||||
ms_in_desc.bLength = USB_DT_MS_ENDPOINT_SIZE(midi->out_ports);
|
||||
ms_in_desc.bNumEmbMIDIJack = midi->out_ports;
|
||||
ms_in_desc.bLength = USB_DT_MS_ENDPOINT_SIZE(midi->in_ports);
|
||||
ms_in_desc.bNumEmbMIDIJack = midi->in_ports;
|
||||
|
||||
/* ... and add them to the list */
|
||||
endpoint_descriptor_index = i;
|
||||
|
||||
@@ -309,7 +309,7 @@ struct renesas_usb3_request {
|
||||
struct list_head queue;
|
||||
};
|
||||
|
||||
#define USB3_EP_NAME_SIZE 8
|
||||
#define USB3_EP_NAME_SIZE 16
|
||||
struct renesas_usb3_ep {
|
||||
struct usb_ep ep;
|
||||
struct renesas_usb3 *usb3;
|
||||
|
||||
@@ -946,6 +946,15 @@ static void quirk_usb_disable_ehci(struct pci_dev *pdev)
|
||||
* booting from USB disk or using a usb keyboard
|
||||
*/
|
||||
hcc_params = readl(base + EHCI_HCC_PARAMS);
|
||||
|
||||
/* LS7A EHCI controller doesn't have extended capabilities, the
|
||||
* EECP (EHCI Extended Capabilities Pointer) field of HCCPARAMS
|
||||
* register should be 0x0 but it reads as 0xa0. So clear it to
|
||||
* avoid error messages on boot.
|
||||
*/
|
||||
if (pdev->vendor == PCI_VENDOR_ID_LOONGSON && pdev->device == 0x7a14)
|
||||
hcc_params &= ~(0xffL << 8);
|
||||
|
||||
offset = (hcc_params >> 8) & 0xff;
|
||||
while (offset && --count) {
|
||||
pci_read_config_dword(pdev, offset, &cap);
|
||||
|
||||
@@ -619,15 +619,6 @@ static void option_instat_callback(struct urb *urb);
|
||||
/* Luat Air72*U series based on UNISOC UIS8910 uses UNISOC's vendor ID */
|
||||
#define LUAT_PRODUCT_AIR720U 0x4e00
|
||||
|
||||
/* MeiG Smart Technology products */
|
||||
#define MEIGSMART_VENDOR_ID 0x2dee
|
||||
/* MeiG Smart SRM815/SRM825L based on Qualcomm 315 */
|
||||
#define MEIGSMART_PRODUCT_SRM825L 0x4d22
|
||||
/* MeiG Smart SLM320 based on UNISOC UIS8910 */
|
||||
#define MEIGSMART_PRODUCT_SLM320 0x4d41
|
||||
/* MeiG Smart SLM770A based on ASR1803 */
|
||||
#define MEIGSMART_PRODUCT_SLM770A 0x4d57
|
||||
|
||||
/* Device flags */
|
||||
|
||||
/* Highest interface number which can be used with NCTRL() and RSVD() */
|
||||
@@ -1367,15 +1358,15 @@ static const struct usb_device_id option_ids[] = {
|
||||
.driver_info = NCTRL(2) | RSVD(3) },
|
||||
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1063, 0xff), /* Telit LN920 (ECM) */
|
||||
.driver_info = NCTRL(0) | RSVD(1) },
|
||||
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1070, 0xff), /* Telit FN990 (rmnet) */
|
||||
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1070, 0xff), /* Telit FN990A (rmnet) */
|
||||
.driver_info = NCTRL(0) | RSVD(1) | RSVD(2) },
|
||||
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1071, 0xff), /* Telit FN990 (MBIM) */
|
||||
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1071, 0xff), /* Telit FN990A (MBIM) */
|
||||
.driver_info = NCTRL(0) | RSVD(1) },
|
||||
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1072, 0xff), /* Telit FN990 (RNDIS) */
|
||||
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1072, 0xff), /* Telit FN990A (RNDIS) */
|
||||
.driver_info = NCTRL(2) | RSVD(3) },
|
||||
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1073, 0xff), /* Telit FN990 (ECM) */
|
||||
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1073, 0xff), /* Telit FN990A (ECM) */
|
||||
.driver_info = NCTRL(0) | RSVD(1) },
|
||||
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1075, 0xff), /* Telit FN990 (PCIe) */
|
||||
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1075, 0xff), /* Telit FN990A (PCIe) */
|
||||
.driver_info = RSVD(0) },
|
||||
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1080, 0xff), /* Telit FE990 (rmnet) */
|
||||
.driver_info = NCTRL(0) | RSVD(1) | RSVD(2) },
|
||||
@@ -1403,6 +1394,22 @@ static const struct usb_device_id option_ids[] = {
|
||||
.driver_info = RSVD(0) | NCTRL(3) },
|
||||
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10c8, 0xff), /* Telit FE910C04 (rmnet) */
|
||||
.driver_info = RSVD(0) | NCTRL(2) | RSVD(3) | RSVD(4) },
|
||||
{ USB_DEVICE_INTERFACE_PROTOCOL(TELIT_VENDOR_ID, 0x10d0, 0x60) }, /* Telit FN990B (rmnet) */
|
||||
{ USB_DEVICE_INTERFACE_PROTOCOL(TELIT_VENDOR_ID, 0x10d0, 0x40) },
|
||||
{ USB_DEVICE_INTERFACE_PROTOCOL(TELIT_VENDOR_ID, 0x10d0, 0x30),
|
||||
.driver_info = NCTRL(5) },
|
||||
{ USB_DEVICE_INTERFACE_PROTOCOL(TELIT_VENDOR_ID, 0x10d1, 0x60) }, /* Telit FN990B (MBIM) */
|
||||
{ USB_DEVICE_INTERFACE_PROTOCOL(TELIT_VENDOR_ID, 0x10d1, 0x40) },
|
||||
{ USB_DEVICE_INTERFACE_PROTOCOL(TELIT_VENDOR_ID, 0x10d1, 0x30),
|
||||
.driver_info = NCTRL(6) },
|
||||
{ USB_DEVICE_INTERFACE_PROTOCOL(TELIT_VENDOR_ID, 0x10d2, 0x60) }, /* Telit FN990B (RNDIS) */
|
||||
{ USB_DEVICE_INTERFACE_PROTOCOL(TELIT_VENDOR_ID, 0x10d2, 0x40) },
|
||||
{ USB_DEVICE_INTERFACE_PROTOCOL(TELIT_VENDOR_ID, 0x10d2, 0x30),
|
||||
.driver_info = NCTRL(6) },
|
||||
{ USB_DEVICE_INTERFACE_PROTOCOL(TELIT_VENDOR_ID, 0x10d3, 0x60) }, /* Telit FN990B (ECM) */
|
||||
{ USB_DEVICE_INTERFACE_PROTOCOL(TELIT_VENDOR_ID, 0x10d3, 0x40) },
|
||||
{ USB_DEVICE_INTERFACE_PROTOCOL(TELIT_VENDOR_ID, 0x10d3, 0x30),
|
||||
.driver_info = NCTRL(6) },
|
||||
{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_ME910),
|
||||
.driver_info = NCTRL(0) | RSVD(1) | RSVD(3) },
|
||||
{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_ME910_DUAL_MODEM),
|
||||
@@ -2347,6 +2354,14 @@ static const struct usb_device_id option_ids[] = {
|
||||
{ USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x0a05, 0xff) }, /* Fibocom FM650-CN (NCM mode) */
|
||||
{ USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x0a06, 0xff) }, /* Fibocom FM650-CN (RNDIS mode) */
|
||||
{ USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x0a07, 0xff) }, /* Fibocom FM650-CN (MBIM mode) */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x2dee, 0x4d41, 0xff, 0, 0) }, /* MeiG Smart SLM320 */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x2dee, 0x4d57, 0xff, 0, 0) }, /* MeiG Smart SLM770A */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x2dee, 0x4d22, 0xff, 0, 0) }, /* MeiG Smart SRM815 */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x2dee, 0x4d22, 0xff, 0x10, 0x02) }, /* MeiG Smart SLM828 */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x2dee, 0x4d22, 0xff, 0x10, 0x03) }, /* MeiG Smart SLM828 */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x2dee, 0x4d22, 0xff, 0xff, 0x30) }, /* MeiG Smart SRM815 and SRM825L */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x2dee, 0x4d22, 0xff, 0xff, 0x40) }, /* MeiG Smart SRM825L */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x2dee, 0x4d22, 0xff, 0xff, 0x60) }, /* MeiG Smart SRM825L */
|
||||
{ USB_DEVICE_INTERFACE_CLASS(0x2df3, 0x9d03, 0xff) }, /* LongSung M5710 */
|
||||
{ USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1404, 0xff) }, /* GosunCn GM500 RNDIS */
|
||||
{ USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1405, 0xff) }, /* GosunCn GM500 MBIM */
|
||||
@@ -2403,12 +2418,6 @@ static const struct usb_device_id option_ids[] = {
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(SIERRA_VENDOR_ID, SIERRA_PRODUCT_EM9191, 0xff, 0, 0) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(UNISOC_VENDOR_ID, TOZED_PRODUCT_LT70C, 0xff, 0, 0) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(UNISOC_VENDOR_ID, LUAT_PRODUCT_AIR720U, 0xff, 0, 0) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SLM320, 0xff, 0, 0) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SLM770A, 0xff, 0, 0) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SRM825L, 0xff, 0, 0) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SRM825L, 0xff, 0xff, 0x30) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SRM825L, 0xff, 0xff, 0x40) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SRM825L, 0xff, 0xff, 0x60) },
|
||||
{ USB_DEVICE_INTERFACE_CLASS(0x1bbb, 0x0530, 0xff), /* TCL IK512 MBIM */
|
||||
.driver_info = NCTRL(1) },
|
||||
{ USB_DEVICE_INTERFACE_CLASS(0x1bbb, 0x0640, 0xff), /* TCL IK512 ECM */
|
||||
|
||||
@@ -1122,7 +1122,6 @@ static int btrfs_write_check(struct kiocb *iocb, struct iov_iter *from,
|
||||
loff_t pos = iocb->ki_pos;
|
||||
int ret;
|
||||
loff_t oldsize;
|
||||
loff_t start_pos;
|
||||
|
||||
/*
|
||||
* Quickly bail out on NOWAIT writes if we don't have the nodatacow or
|
||||
@@ -1147,9 +1146,8 @@ static int btrfs_write_check(struct kiocb *iocb, struct iov_iter *from,
|
||||
*/
|
||||
update_time_for_write(inode);
|
||||
|
||||
start_pos = round_down(pos, fs_info->sectorsize);
|
||||
oldsize = i_size_read(inode);
|
||||
if (start_pos > oldsize) {
|
||||
if (pos > oldsize) {
|
||||
/* Expand hole size to cover write data, preventing empty gap */
|
||||
loff_t end_pos = round_up(pos + count, fs_info->sectorsize);
|
||||
|
||||
|
||||
@@ -162,7 +162,7 @@ static int nilfs_writepages(struct address_space *mapping,
|
||||
int err = 0;
|
||||
|
||||
if (sb_rdonly(inode->i_sb)) {
|
||||
nilfs_clear_dirty_pages(mapping, false);
|
||||
nilfs_clear_dirty_pages(mapping);
|
||||
return -EROFS;
|
||||
}
|
||||
|
||||
@@ -185,7 +185,7 @@ static int nilfs_writepage(struct page *page, struct writeback_control *wbc)
|
||||
* have dirty pages that try to be flushed in background.
|
||||
* So, here we simply discard this dirty page.
|
||||
*/
|
||||
nilfs_clear_dirty_page(page, false);
|
||||
nilfs_clear_dirty_page(page);
|
||||
unlock_page(page);
|
||||
return -EROFS;
|
||||
}
|
||||
|
||||
@@ -411,7 +411,7 @@ nilfs_mdt_write_page(struct page *page, struct writeback_control *wbc)
|
||||
* have dirty pages that try to be flushed in background.
|
||||
* So, here we simply discard this dirty page.
|
||||
*/
|
||||
nilfs_clear_dirty_page(page, false);
|
||||
nilfs_clear_dirty_page(page);
|
||||
unlock_page(page);
|
||||
return -EROFS;
|
||||
}
|
||||
@@ -634,10 +634,10 @@ void nilfs_mdt_restore_from_shadow_map(struct inode *inode)
|
||||
if (mi->mi_palloc_cache)
|
||||
nilfs_palloc_clear_cache(inode);
|
||||
|
||||
nilfs_clear_dirty_pages(inode->i_mapping, true);
|
||||
nilfs_clear_dirty_pages(inode->i_mapping);
|
||||
nilfs_copy_back_pages(inode->i_mapping, shadow->inode->i_mapping);
|
||||
|
||||
nilfs_clear_dirty_pages(ii->i_assoc_inode->i_mapping, true);
|
||||
nilfs_clear_dirty_pages(ii->i_assoc_inode->i_mapping);
|
||||
nilfs_copy_back_pages(ii->i_assoc_inode->i_mapping,
|
||||
NILFS_I(shadow->inode)->i_assoc_inode->i_mapping);
|
||||
|
||||
|
||||
@@ -354,9 +354,8 @@ repeat:
|
||||
/**
|
||||
* nilfs_clear_dirty_pages - discard dirty pages in address space
|
||||
* @mapping: address space with dirty pages for discarding
|
||||
* @silent: suppress [true] or print [false] warning messages
|
||||
*/
|
||||
void nilfs_clear_dirty_pages(struct address_space *mapping, bool silent)
|
||||
void nilfs_clear_dirty_pages(struct address_space *mapping)
|
||||
{
|
||||
struct pagevec pvec;
|
||||
unsigned int i;
|
||||
@@ -377,7 +376,7 @@ void nilfs_clear_dirty_pages(struct address_space *mapping, bool silent)
|
||||
* was acquired. Skip processing in that case.
|
||||
*/
|
||||
if (likely(page->mapping == mapping))
|
||||
nilfs_clear_dirty_page(page, silent);
|
||||
nilfs_clear_dirty_page(page);
|
||||
|
||||
unlock_page(page);
|
||||
}
|
||||
@@ -389,44 +388,54 @@ void nilfs_clear_dirty_pages(struct address_space *mapping, bool silent)
|
||||
/**
|
||||
* nilfs_clear_dirty_page - discard dirty page
|
||||
* @page: dirty page that will be discarded
|
||||
* @silent: suppress [true] or print [false] warning messages
|
||||
*
|
||||
* nilfs_clear_dirty_page() clears working states including dirty state for
|
||||
* the page and its buffers. If the page has buffers, clear only if it is
|
||||
* confirmed that none of the buffer heads are busy (none have valid
|
||||
* references and none are locked).
|
||||
*/
|
||||
void nilfs_clear_dirty_page(struct page *page, bool silent)
|
||||
void nilfs_clear_dirty_page(struct page *page)
|
||||
{
|
||||
struct inode *inode = page->mapping->host;
|
||||
struct super_block *sb = inode->i_sb;
|
||||
|
||||
BUG_ON(!PageLocked(page));
|
||||
|
||||
if (!silent)
|
||||
nilfs_warn(sb, "discard dirty page: offset=%lld, ino=%lu",
|
||||
page_offset(page), inode->i_ino);
|
||||
|
||||
ClearPageUptodate(page);
|
||||
ClearPageMappedToDisk(page);
|
||||
ClearPageChecked(page);
|
||||
|
||||
if (page_has_buffers(page)) {
|
||||
struct buffer_head *bh, *head;
|
||||
struct buffer_head *bh, *head = page_buffers(page);
|
||||
const unsigned long clear_bits =
|
||||
(BIT(BH_Uptodate) | BIT(BH_Dirty) | BIT(BH_Mapped) |
|
||||
BIT(BH_Async_Write) | BIT(BH_NILFS_Volatile) |
|
||||
BIT(BH_NILFS_Checked) | BIT(BH_NILFS_Redirected) |
|
||||
BIT(BH_Delay));
|
||||
bool busy, invalidated = false;
|
||||
|
||||
bh = head = page_buffers(page);
|
||||
recheck_buffers:
|
||||
busy = false;
|
||||
bh = head;
|
||||
do {
|
||||
if (atomic_read(&bh->b_count) | buffer_locked(bh)) {
|
||||
busy = true;
|
||||
break;
|
||||
}
|
||||
} while (bh = bh->b_this_page, bh != head);
|
||||
|
||||
if (busy) {
|
||||
if (invalidated)
|
||||
return;
|
||||
invalidate_bh_lrus();
|
||||
invalidated = true;
|
||||
goto recheck_buffers;
|
||||
}
|
||||
|
||||
bh = head;
|
||||
do {
|
||||
lock_buffer(bh);
|
||||
if (!silent)
|
||||
nilfs_warn(sb,
|
||||
"discard dirty block: blocknr=%llu, size=%zu",
|
||||
(u64)bh->b_blocknr, bh->b_size);
|
||||
|
||||
set_mask_bits(&bh->b_state, clear_bits, 0);
|
||||
unlock_buffer(bh);
|
||||
} while (bh = bh->b_this_page, bh != head);
|
||||
}
|
||||
|
||||
ClearPageUptodate(page);
|
||||
ClearPageMappedToDisk(page);
|
||||
ClearPageChecked(page);
|
||||
__nilfs_clear_page_dirty(page);
|
||||
}
|
||||
|
||||
|
||||
@@ -41,8 +41,8 @@ void nilfs_page_bug(struct page *);
|
||||
|
||||
int nilfs_copy_dirty_pages(struct address_space *, struct address_space *);
|
||||
void nilfs_copy_back_pages(struct address_space *, struct address_space *);
|
||||
void nilfs_clear_dirty_page(struct page *, bool);
|
||||
void nilfs_clear_dirty_pages(struct address_space *, bool);
|
||||
void nilfs_clear_dirty_page(struct page *page);
|
||||
void nilfs_clear_dirty_pages(struct address_space *mapping);
|
||||
unsigned int nilfs_page_count_clean_buffers(struct page *, unsigned int,
|
||||
unsigned int);
|
||||
unsigned long nilfs_find_uncommitted_extent(struct inode *inode,
|
||||
|
||||
@@ -732,7 +732,6 @@ static size_t nilfs_lookup_dirty_data_buffers(struct inode *inode,
|
||||
}
|
||||
if (!page_has_buffers(page))
|
||||
create_empty_buffers(page, i_blocksize(inode), 0);
|
||||
unlock_page(page);
|
||||
|
||||
bh = head = page_buffers(page);
|
||||
do {
|
||||
@@ -742,11 +741,14 @@ static size_t nilfs_lookup_dirty_data_buffers(struct inode *inode,
|
||||
list_add_tail(&bh->b_assoc_buffers, listp);
|
||||
ndirties++;
|
||||
if (unlikely(ndirties >= nlimit)) {
|
||||
unlock_page(page);
|
||||
pagevec_release(&pvec);
|
||||
cond_resched();
|
||||
return ndirties;
|
||||
}
|
||||
} while (bh = bh->b_this_page, bh != head);
|
||||
|
||||
unlock_page(page);
|
||||
}
|
||||
pagevec_release(&pvec);
|
||||
cond_resched();
|
||||
|
||||
@@ -71,9 +71,6 @@ enum {
|
||||
|
||||
/* Cgroup is frozen. */
|
||||
CGRP_FROZEN,
|
||||
|
||||
/* Control group has to be killed. */
|
||||
CGRP_KILL,
|
||||
};
|
||||
|
||||
/* cgroup_root->flags */
|
||||
@@ -424,6 +421,9 @@ struct cgroup {
|
||||
|
||||
int nr_threaded_children; /* # of live threaded child cgroups */
|
||||
|
||||
/* sequence number for cgroup.kill, serialized by css_set_lock. */
|
||||
unsigned int kill_seq;
|
||||
|
||||
struct kernfs_node *kn; /* cgroup kernfs entry */
|
||||
struct cgroup_file procs_file; /* handle for "cgroup.procs" */
|
||||
struct cgroup_file events_file; /* handle for "cgroup.events" */
|
||||
|
||||
@@ -125,6 +125,7 @@ typedef struct {
|
||||
#define EFI_MEMORY_RO ((u64)0x0000000000020000ULL) /* read-only */
|
||||
#define EFI_MEMORY_SP ((u64)0x0000000000040000ULL) /* soft reserved */
|
||||
#define EFI_MEMORY_CPU_CRYPTO ((u64)0x0000000000080000ULL) /* supports encryption */
|
||||
#define EFI_MEMORY_HOT_PLUGGABLE BIT_ULL(20) /* supports unplugging at runtime */
|
||||
#define EFI_MEMORY_RUNTIME ((u64)0x8000000000000000ULL) /* range requires runtime mapping */
|
||||
#define EFI_MEMORY_DESCRIPTOR_VERSION 1
|
||||
|
||||
|
||||
@@ -1153,7 +1153,7 @@ u32 iommu_sva_get_pasid(struct iommu_sva *handle);
|
||||
static inline struct iommu_sva *
|
||||
iommu_sva_bind_device(struct device *dev, struct mm_struct *mm)
|
||||
{
|
||||
return NULL;
|
||||
return ERR_PTR(-ENODEV);
|
||||
}
|
||||
|
||||
static inline void iommu_sva_unbind_device(struct iommu_sva *handle)
|
||||
|
||||
@@ -2576,6 +2576,12 @@ struct net *dev_net(const struct net_device *dev)
|
||||
return read_pnet(&dev->nd_net);
|
||||
}
|
||||
|
||||
static inline
|
||||
struct net *dev_net_rcu(const struct net_device *dev)
|
||||
{
|
||||
return read_pnet_rcu(&dev->nd_net);
|
||||
}
|
||||
|
||||
static inline
|
||||
void dev_net_set(struct net_device *dev, struct net *net)
|
||||
{
|
||||
|
||||
@@ -1754,6 +1754,10 @@
|
||||
#define PCI_SUBDEVICE_ID_AT_2700FX 0x2701
|
||||
#define PCI_SUBDEVICE_ID_AT_2701FX 0x2703
|
||||
|
||||
#define PCI_VENDOR_ID_ASIX 0x125b
|
||||
#define PCI_DEVICE_ID_ASIX_AX99100 0x9100
|
||||
#define PCI_DEVICE_ID_ASIX_AX99100_LB 0x9110
|
||||
|
||||
#define PCI_VENDOR_ID_ESS 0x125d
|
||||
#define PCI_DEVICE_ID_ESS_ESS1968 0x1968
|
||||
#define PCI_DEVICE_ID_ESS_ESS1978 0x1978
|
||||
|
||||
@@ -38,6 +38,7 @@ struct kernel_clone_args {
|
||||
void *fn_arg;
|
||||
struct cgroup *cgrp;
|
||||
struct css_set *cset;
|
||||
unsigned int kill_seq;
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
@@ -382,21 +382,30 @@ static inline void put_net_track(struct net *net, netns_tracker *tracker)
|
||||
|
||||
typedef struct {
|
||||
#ifdef CONFIG_NET_NS
|
||||
struct net *net;
|
||||
struct net __rcu *net;
|
||||
#endif
|
||||
} possible_net_t;
|
||||
|
||||
static inline void write_pnet(possible_net_t *pnet, struct net *net)
|
||||
{
|
||||
#ifdef CONFIG_NET_NS
|
||||
pnet->net = net;
|
||||
rcu_assign_pointer(pnet->net, net);
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline struct net *read_pnet(const possible_net_t *pnet)
|
||||
{
|
||||
#ifdef CONFIG_NET_NS
|
||||
return pnet->net;
|
||||
return rcu_dereference_protected(pnet->net, true);
|
||||
#else
|
||||
return &init_net;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline struct net *read_pnet_rcu(const possible_net_t *pnet)
|
||||
{
|
||||
#ifdef CONFIG_NET_NS
|
||||
return rcu_dereference(pnet->net);
|
||||
#else
|
||||
return &init_net;
|
||||
#endif
|
||||
|
||||
@@ -362,10 +362,15 @@ static inline int inet_iif(const struct sk_buff *skb)
|
||||
static inline int ip4_dst_hoplimit(const struct dst_entry *dst)
|
||||
{
|
||||
int hoplimit = dst_metric_raw(dst, RTAX_HOPLIMIT);
|
||||
struct net *net = dev_net(dst->dev);
|
||||
|
||||
if (hoplimit == 0)
|
||||
if (hoplimit == 0) {
|
||||
const struct net *net;
|
||||
|
||||
rcu_read_lock();
|
||||
net = dev_net_rcu(dst->dev);
|
||||
hoplimit = READ_ONCE(net->ipv4.sysctl_ip_default_ttl);
|
||||
rcu_read_unlock();
|
||||
}
|
||||
return hoplimit;
|
||||
}
|
||||
|
||||
|
||||
@@ -3961,7 +3961,7 @@ static void __cgroup_kill(struct cgroup *cgrp)
|
||||
lockdep_assert_held(&cgroup_mutex);
|
||||
|
||||
spin_lock_irq(&css_set_lock);
|
||||
set_bit(CGRP_KILL, &cgrp->flags);
|
||||
cgrp->kill_seq++;
|
||||
spin_unlock_irq(&css_set_lock);
|
||||
|
||||
css_task_iter_start(&cgrp->self, CSS_TASK_ITER_PROCS | CSS_TASK_ITER_THREADED, &it);
|
||||
@@ -3977,10 +3977,6 @@ static void __cgroup_kill(struct cgroup *cgrp)
|
||||
send_sig(SIGKILL, task, 0);
|
||||
}
|
||||
css_task_iter_end(&it);
|
||||
|
||||
spin_lock_irq(&css_set_lock);
|
||||
clear_bit(CGRP_KILL, &cgrp->flags);
|
||||
spin_unlock_irq(&css_set_lock);
|
||||
}
|
||||
|
||||
static void cgroup_kill(struct cgroup *cgrp)
|
||||
@@ -6425,6 +6421,10 @@ static int cgroup_css_set_fork(struct kernel_clone_args *kargs)
|
||||
spin_lock_irq(&css_set_lock);
|
||||
cset = task_css_set(current);
|
||||
get_css_set(cset);
|
||||
if (kargs->cgrp)
|
||||
kargs->kill_seq = kargs->cgrp->kill_seq;
|
||||
else
|
||||
kargs->kill_seq = cset->dfl_cgrp->kill_seq;
|
||||
spin_unlock_irq(&css_set_lock);
|
||||
|
||||
if (!(kargs->flags & CLONE_INTO_CGROUP)) {
|
||||
@@ -6608,6 +6608,7 @@ void cgroup_post_fork(struct task_struct *child,
|
||||
struct kernel_clone_args *kargs)
|
||||
__releases(&cgroup_threadgroup_rwsem) __releases(&cgroup_mutex)
|
||||
{
|
||||
unsigned int cgrp_kill_seq = 0;
|
||||
unsigned long cgrp_flags = 0;
|
||||
bool kill = false;
|
||||
struct cgroup_subsys *ss;
|
||||
@@ -6621,10 +6622,13 @@ void cgroup_post_fork(struct task_struct *child,
|
||||
|
||||
/* init tasks are special, only link regular threads */
|
||||
if (likely(child->pid)) {
|
||||
if (kargs->cgrp)
|
||||
if (kargs->cgrp) {
|
||||
cgrp_flags = kargs->cgrp->flags;
|
||||
else
|
||||
cgrp_kill_seq = kargs->cgrp->kill_seq;
|
||||
} else {
|
||||
cgrp_flags = cset->dfl_cgrp->flags;
|
||||
cgrp_kill_seq = cset->dfl_cgrp->kill_seq;
|
||||
}
|
||||
|
||||
WARN_ON_ONCE(!list_empty(&child->cg_list));
|
||||
cset->nr_tasks++;
|
||||
@@ -6659,7 +6663,7 @@ void cgroup_post_fork(struct task_struct *child,
|
||||
* child down right after we finished preparing it for
|
||||
* userspace.
|
||||
*/
|
||||
kill = test_bit(CGRP_KILL, &cgrp_flags);
|
||||
kill = kargs->kill_seq != cgrp_kill_seq;
|
||||
}
|
||||
|
||||
spin_unlock_irq(&css_set_lock);
|
||||
|
||||
@@ -576,6 +576,8 @@ static void kdb_msg_write(const char *msg, int msg_len)
|
||||
continue;
|
||||
if (c == dbg_io_ops->cons)
|
||||
continue;
|
||||
if (!c->write)
|
||||
continue;
|
||||
/*
|
||||
* Set oops_in_progress to encourage the console drivers to
|
||||
* disregard their internal spin locks: in the current calling
|
||||
|
||||
@@ -348,16 +348,18 @@ void clocksource_verify_percpu(struct clocksource *cs)
|
||||
cpumask_clear(&cpus_ahead);
|
||||
cpumask_clear(&cpus_behind);
|
||||
cpus_read_lock();
|
||||
preempt_disable();
|
||||
migrate_disable();
|
||||
clocksource_verify_choose_cpus();
|
||||
if (cpumask_empty(&cpus_chosen)) {
|
||||
preempt_enable();
|
||||
migrate_enable();
|
||||
cpus_read_unlock();
|
||||
pr_warn("Not enough CPUs to check clocksource '%s'.\n", cs->name);
|
||||
return;
|
||||
}
|
||||
testcpu = smp_processor_id();
|
||||
pr_warn("Checking clocksource %s synchronization from CPU %d to CPUs %*pbl.\n", cs->name, testcpu, cpumask_pr_args(&cpus_chosen));
|
||||
pr_info("Checking clocksource %s synchronization from CPU %d to CPUs %*pbl.\n",
|
||||
cs->name, testcpu, cpumask_pr_args(&cpus_chosen));
|
||||
preempt_disable();
|
||||
for_each_cpu(cpu, &cpus_chosen) {
|
||||
if (cpu == testcpu)
|
||||
continue;
|
||||
@@ -377,6 +379,7 @@ void clocksource_verify_percpu(struct clocksource *cs)
|
||||
cs_nsec_min = cs_nsec;
|
||||
}
|
||||
preempt_enable();
|
||||
migrate_enable();
|
||||
cpus_read_unlock();
|
||||
if (!cpumask_empty(&cpus_ahead))
|
||||
pr_warn(" CPUs %*pbl ahead of CPU %d for clocksource %s.\n",
|
||||
|
||||
14
mm/gup.c
14
mm/gup.c
@@ -1944,14 +1944,14 @@ struct page *get_dump_page(unsigned long addr)
|
||||
/*
|
||||
* Returns the number of collected pages. Return value is always >= 0.
|
||||
*/
|
||||
static unsigned long collect_longterm_unpinnable_pages(
|
||||
static void collect_longterm_unpinnable_pages(
|
||||
struct list_head *movable_page_list,
|
||||
unsigned long nr_pages,
|
||||
struct page **pages)
|
||||
{
|
||||
unsigned long i, collected = 0;
|
||||
struct folio *prev_folio = NULL;
|
||||
bool drain_allow = true;
|
||||
unsigned long i;
|
||||
|
||||
for (i = 0; i < nr_pages; i++) {
|
||||
struct folio *folio = page_folio(pages[i]);
|
||||
@@ -1963,8 +1963,6 @@ static unsigned long collect_longterm_unpinnable_pages(
|
||||
if (folio_is_longterm_pinnable(folio))
|
||||
continue;
|
||||
|
||||
collected++;
|
||||
|
||||
if (folio_is_device_coherent(folio))
|
||||
continue;
|
||||
|
||||
@@ -1986,8 +1984,6 @@ static unsigned long collect_longterm_unpinnable_pages(
|
||||
NR_ISOLATED_ANON + folio_is_file_lru(folio),
|
||||
folio_nr_pages(folio));
|
||||
}
|
||||
|
||||
return collected;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2080,12 +2076,10 @@ err:
|
||||
static long check_and_migrate_movable_pages(unsigned long nr_pages,
|
||||
struct page **pages)
|
||||
{
|
||||
unsigned long collected;
|
||||
LIST_HEAD(movable_page_list);
|
||||
|
||||
collected = collect_longterm_unpinnable_pages(&movable_page_list,
|
||||
nr_pages, pages);
|
||||
if (!collected)
|
||||
collect_longterm_unpinnable_pages(&movable_page_list, nr_pages, pages);
|
||||
if (list_empty(&movable_page_list))
|
||||
return 0;
|
||||
|
||||
return migrate_longterm_unpinnable_pages(&movable_page_list, nr_pages,
|
||||
|
||||
@@ -1132,7 +1132,7 @@ static int j1939_sk_send_loop(struct j1939_priv *priv, struct sock *sk,
|
||||
|
||||
todo_size = size;
|
||||
|
||||
while (todo_size) {
|
||||
do {
|
||||
struct j1939_sk_buff_cb *skcb;
|
||||
|
||||
segment_size = min_t(size_t, J1939_MAX_TP_PACKET_SIZE,
|
||||
@@ -1177,7 +1177,7 @@ static int j1939_sk_send_loop(struct j1939_priv *priv, struct sock *sk,
|
||||
|
||||
todo_size -= segment_size;
|
||||
session->total_queued_size += segment_size;
|
||||
}
|
||||
} while (todo_size);
|
||||
|
||||
switch (ret) {
|
||||
case 0: /* OK */
|
||||
|
||||
@@ -382,8 +382,9 @@ sk_buff *j1939_session_skb_get_by_offset(struct j1939_session *session,
|
||||
skb_queue_walk(&session->skb_queue, do_skb) {
|
||||
do_skcb = j1939_skb_to_cb(do_skb);
|
||||
|
||||
if (offset_start >= do_skcb->offset &&
|
||||
offset_start < (do_skcb->offset + do_skb->len)) {
|
||||
if ((offset_start >= do_skcb->offset &&
|
||||
offset_start < (do_skcb->offset + do_skb->len)) ||
|
||||
(offset_start == 0 && do_skcb->offset == 0 && do_skb->len == 0)) {
|
||||
skb = do_skb;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1004,10 +1004,12 @@ bool __skb_flow_dissect(const struct net *net,
|
||||
FLOW_DISSECTOR_KEY_BASIC,
|
||||
target_container);
|
||||
|
||||
rcu_read_lock();
|
||||
|
||||
if (skb) {
|
||||
if (!net) {
|
||||
if (skb->dev)
|
||||
net = dev_net(skb->dev);
|
||||
net = dev_net_rcu(skb->dev);
|
||||
else if (skb->sk)
|
||||
net = sock_net(skb->sk);
|
||||
}
|
||||
@@ -1018,7 +1020,6 @@ bool __skb_flow_dissect(const struct net *net,
|
||||
enum netns_bpf_attach_type type = NETNS_BPF_FLOW_DISSECTOR;
|
||||
struct bpf_prog_array *run_array;
|
||||
|
||||
rcu_read_lock();
|
||||
run_array = rcu_dereference(init_net.bpf.run_array[type]);
|
||||
if (!run_array)
|
||||
run_array = rcu_dereference(net->bpf.run_array[type]);
|
||||
@@ -1046,17 +1047,17 @@ bool __skb_flow_dissect(const struct net *net,
|
||||
prog = READ_ONCE(run_array->items[0].prog);
|
||||
result = bpf_flow_dissect(prog, &ctx, n_proto, nhoff,
|
||||
hlen, flags);
|
||||
if (result == BPF_FLOW_DISSECTOR_CONTINUE)
|
||||
goto dissect_continue;
|
||||
__skb_flow_bpf_to_target(&flow_keys, flow_dissector,
|
||||
target_container);
|
||||
rcu_read_unlock();
|
||||
return result == BPF_OK;
|
||||
if (result != BPF_FLOW_DISSECTOR_CONTINUE) {
|
||||
__skb_flow_bpf_to_target(&flow_keys, flow_dissector,
|
||||
target_container);
|
||||
rcu_read_unlock();
|
||||
return result == BPF_OK;
|
||||
}
|
||||
}
|
||||
dissect_continue:
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
rcu_read_unlock();
|
||||
|
||||
if (dissector_uses_key(flow_dissector,
|
||||
FLOW_DISSECTOR_KEY_ETH_ADDRS)) {
|
||||
struct ethhdr *eth = eth_hdr(skb);
|
||||
|
||||
@@ -3498,10 +3498,12 @@ static const struct seq_operations neigh_stat_seq_ops = {
|
||||
static void __neigh_notify(struct neighbour *n, int type, int flags,
|
||||
u32 pid)
|
||||
{
|
||||
struct net *net = dev_net(n->dev);
|
||||
struct sk_buff *skb;
|
||||
int err = -ENOBUFS;
|
||||
struct net *net;
|
||||
|
||||
rcu_read_lock();
|
||||
net = dev_net_rcu(n->dev);
|
||||
skb = nlmsg_new(neigh_nlmsg_size(), GFP_ATOMIC);
|
||||
if (skb == NULL)
|
||||
goto errout;
|
||||
@@ -3514,10 +3516,11 @@ static void __neigh_notify(struct neighbour *n, int type, int flags,
|
||||
goto errout;
|
||||
}
|
||||
rtnl_notify(skb, net, 0, RTNLGRP_NEIGH, NULL, GFP_ATOMIC);
|
||||
return;
|
||||
goto out;
|
||||
errout:
|
||||
if (err < 0)
|
||||
rtnl_set_sk_err(net, RTNLGRP_NEIGH, err);
|
||||
rtnl_set_sk_err(net, RTNLGRP_NEIGH, err);
|
||||
out:
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
void neigh_app_ns(struct neighbour *n)
|
||||
|
||||
@@ -658,10 +658,12 @@ static int arp_xmit_finish(struct net *net, struct sock *sk, struct sk_buff *skb
|
||||
*/
|
||||
void arp_xmit(struct sk_buff *skb)
|
||||
{
|
||||
rcu_read_lock();
|
||||
/* Send it off, maybe filter it using firewalling first. */
|
||||
NF_HOOK(NFPROTO_ARP, NF_ARP_OUT,
|
||||
dev_net(skb->dev), NULL, skb, NULL, skb->dev,
|
||||
dev_net_rcu(skb->dev), NULL, skb, NULL, skb->dev,
|
||||
arp_xmit_finish);
|
||||
rcu_read_unlock();
|
||||
}
|
||||
EXPORT_SYMBOL(arp_xmit);
|
||||
|
||||
|
||||
@@ -1320,10 +1320,11 @@ __be32 inet_select_addr(const struct net_device *dev, __be32 dst, int scope)
|
||||
__be32 addr = 0;
|
||||
unsigned char localnet_scope = RT_SCOPE_HOST;
|
||||
struct in_device *in_dev;
|
||||
struct net *net = dev_net(dev);
|
||||
struct net *net;
|
||||
int master_idx;
|
||||
|
||||
rcu_read_lock();
|
||||
net = dev_net_rcu(dev);
|
||||
in_dev = __in_dev_get_rcu(dev);
|
||||
if (!in_dev)
|
||||
goto no_in_dev;
|
||||
|
||||
@@ -393,9 +393,9 @@ static void icmp_push_reply(struct sock *sk,
|
||||
|
||||
static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb)
|
||||
{
|
||||
struct ipcm_cookie ipc;
|
||||
struct rtable *rt = skb_rtable(skb);
|
||||
struct net *net = dev_net(rt->dst.dev);
|
||||
struct net *net = dev_net_rcu(rt->dst.dev);
|
||||
struct ipcm_cookie ipc;
|
||||
struct flowi4 fl4;
|
||||
struct sock *sk;
|
||||
struct inet_sock *inet;
|
||||
@@ -597,12 +597,14 @@ void __icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info,
|
||||
struct sock *sk;
|
||||
|
||||
if (!rt)
|
||||
goto out;
|
||||
return;
|
||||
|
||||
rcu_read_lock();
|
||||
|
||||
if (rt->dst.dev)
|
||||
net = dev_net(rt->dst.dev);
|
||||
net = dev_net_rcu(rt->dst.dev);
|
||||
else if (skb_in->dev)
|
||||
net = dev_net(skb_in->dev);
|
||||
net = dev_net_rcu(skb_in->dev);
|
||||
else
|
||||
goto out;
|
||||
|
||||
@@ -771,7 +773,8 @@ out_unlock:
|
||||
icmp_xmit_unlock(sk);
|
||||
out_bh_enable:
|
||||
local_bh_enable();
|
||||
out:;
|
||||
out:
|
||||
rcu_read_unlock();
|
||||
}
|
||||
EXPORT_SYMBOL(__icmp_send);
|
||||
|
||||
@@ -820,7 +823,7 @@ static void icmp_socket_deliver(struct sk_buff *skb, u32 info)
|
||||
* avoid additional coding at protocol handlers.
|
||||
*/
|
||||
if (!pskb_may_pull(skb, iph->ihl * 4 + 8)) {
|
||||
__ICMP_INC_STATS(dev_net(skb->dev), ICMP_MIB_INERRORS);
|
||||
__ICMP_INC_STATS(dev_net_rcu(skb->dev), ICMP_MIB_INERRORS);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -854,7 +857,7 @@ static enum skb_drop_reason icmp_unreach(struct sk_buff *skb)
|
||||
struct net *net;
|
||||
u32 info = 0;
|
||||
|
||||
net = dev_net(skb_dst(skb)->dev);
|
||||
net = dev_net_rcu(skb_dst(skb)->dev);
|
||||
|
||||
/*
|
||||
* Incomplete header ?
|
||||
@@ -965,7 +968,7 @@ out_err:
|
||||
static enum skb_drop_reason icmp_redirect(struct sk_buff *skb)
|
||||
{
|
||||
if (skb->len < sizeof(struct iphdr)) {
|
||||
__ICMP_INC_STATS(dev_net(skb->dev), ICMP_MIB_INERRORS);
|
||||
__ICMP_INC_STATS(dev_net_rcu(skb->dev), ICMP_MIB_INERRORS);
|
||||
return SKB_DROP_REASON_PKT_TOO_SMALL;
|
||||
}
|
||||
|
||||
@@ -997,7 +1000,7 @@ static enum skb_drop_reason icmp_echo(struct sk_buff *skb)
|
||||
struct icmp_bxm icmp_param;
|
||||
struct net *net;
|
||||
|
||||
net = dev_net(skb_dst(skb)->dev);
|
||||
net = dev_net_rcu(skb_dst(skb)->dev);
|
||||
/* should there be an ICMP stat for ignored echos? */
|
||||
if (READ_ONCE(net->ipv4.sysctl_icmp_echo_ignore_all))
|
||||
return SKB_NOT_DROPPED_YET;
|
||||
@@ -1026,9 +1029,9 @@ static enum skb_drop_reason icmp_echo(struct sk_buff *skb)
|
||||
|
||||
bool icmp_build_probe(struct sk_buff *skb, struct icmphdr *icmphdr)
|
||||
{
|
||||
struct net *net = dev_net_rcu(skb->dev);
|
||||
struct icmp_ext_hdr *ext_hdr, _ext_hdr;
|
||||
struct icmp_ext_echo_iio *iio, _iio;
|
||||
struct net *net = dev_net(skb->dev);
|
||||
struct inet6_dev *in6_dev;
|
||||
struct in_device *in_dev;
|
||||
struct net_device *dev;
|
||||
@@ -1167,7 +1170,7 @@ static enum skb_drop_reason icmp_timestamp(struct sk_buff *skb)
|
||||
return SKB_NOT_DROPPED_YET;
|
||||
|
||||
out_err:
|
||||
__ICMP_INC_STATS(dev_net(skb_dst(skb)->dev), ICMP_MIB_INERRORS);
|
||||
__ICMP_INC_STATS(dev_net_rcu(skb_dst(skb)->dev), ICMP_MIB_INERRORS);
|
||||
return SKB_DROP_REASON_PKT_TOO_SMALL;
|
||||
}
|
||||
|
||||
@@ -1184,7 +1187,7 @@ int icmp_rcv(struct sk_buff *skb)
|
||||
{
|
||||
enum skb_drop_reason reason = SKB_DROP_REASON_NOT_SPECIFIED;
|
||||
struct rtable *rt = skb_rtable(skb);
|
||||
struct net *net = dev_net(rt->dst.dev);
|
||||
struct net *net = dev_net_rcu(rt->dst.dev);
|
||||
struct icmphdr *icmph;
|
||||
|
||||
if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) {
|
||||
@@ -1357,9 +1360,9 @@ int icmp_err(struct sk_buff *skb, u32 info)
|
||||
struct iphdr *iph = (struct iphdr *)skb->data;
|
||||
int offset = iph->ihl<<2;
|
||||
struct icmphdr *icmph = (struct icmphdr *)(skb->data + offset);
|
||||
struct net *net = dev_net_rcu(skb->dev);
|
||||
int type = icmp_hdr(skb)->type;
|
||||
int code = icmp_hdr(skb)->code;
|
||||
struct net *net = dev_net(skb->dev);
|
||||
|
||||
/*
|
||||
* Use ping_err to handle all icmp errors except those
|
||||
|
||||
@@ -393,7 +393,13 @@ static inline int ip_rt_proc_init(void)
|
||||
|
||||
static inline bool rt_is_expired(const struct rtable *rth)
|
||||
{
|
||||
return rth->rt_genid != rt_genid_ipv4(dev_net(rth->dst.dev));
|
||||
bool res;
|
||||
|
||||
rcu_read_lock();
|
||||
res = rth->rt_genid != rt_genid_ipv4(dev_net_rcu(rth->dst.dev));
|
||||
rcu_read_unlock();
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void rt_cache_flush(struct net *net)
|
||||
@@ -1014,9 +1020,9 @@ out: kfree_skb_reason(skb, reason);
|
||||
static void __ip_rt_update_pmtu(struct rtable *rt, struct flowi4 *fl4, u32 mtu)
|
||||
{
|
||||
struct dst_entry *dst = &rt->dst;
|
||||
struct net *net = dev_net(dst->dev);
|
||||
struct fib_result res;
|
||||
bool lock = false;
|
||||
struct net *net;
|
||||
u32 old_mtu;
|
||||
|
||||
if (ip_mtu_locked(dst))
|
||||
@@ -1026,6 +1032,8 @@ static void __ip_rt_update_pmtu(struct rtable *rt, struct flowi4 *fl4, u32 mtu)
|
||||
if (old_mtu < mtu)
|
||||
return;
|
||||
|
||||
rcu_read_lock();
|
||||
net = dev_net_rcu(dst->dev);
|
||||
if (mtu < net->ipv4.ip_rt_min_pmtu) {
|
||||
lock = true;
|
||||
mtu = min(old_mtu, net->ipv4.ip_rt_min_pmtu);
|
||||
@@ -1033,17 +1041,29 @@ static void __ip_rt_update_pmtu(struct rtable *rt, struct flowi4 *fl4, u32 mtu)
|
||||
|
||||
if (rt->rt_pmtu == mtu && !lock &&
|
||||
time_before(jiffies, dst->expires - net->ipv4.ip_rt_mtu_expires / 2))
|
||||
return;
|
||||
goto out;
|
||||
|
||||
rcu_read_lock();
|
||||
if (fib_lookup(net, fl4, &res, 0) == 0) {
|
||||
struct fib_nh_common *nhc;
|
||||
|
||||
fib_select_path(net, &res, fl4, NULL);
|
||||
#ifdef CONFIG_IP_ROUTE_MULTIPATH
|
||||
if (fib_info_num_path(res.fi) > 1) {
|
||||
int nhsel;
|
||||
|
||||
for (nhsel = 0; nhsel < fib_info_num_path(res.fi); nhsel++) {
|
||||
nhc = fib_info_nhc(res.fi, nhsel);
|
||||
update_or_create_fnhe(nhc, fl4->daddr, 0, mtu, lock,
|
||||
jiffies + net->ipv4.ip_rt_mtu_expires);
|
||||
}
|
||||
goto out;
|
||||
}
|
||||
#endif /* CONFIG_IP_ROUTE_MULTIPATH */
|
||||
nhc = FIB_RES_NHC(res);
|
||||
update_or_create_fnhe(nhc, fl4->daddr, 0, mtu, lock,
|
||||
jiffies + net->ipv4.ip_rt_mtu_expires);
|
||||
}
|
||||
out:
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
@@ -1306,10 +1326,15 @@ static void set_class_tag(struct rtable *rt, u32 tag)
|
||||
|
||||
static unsigned int ipv4_default_advmss(const struct dst_entry *dst)
|
||||
{
|
||||
struct net *net = dev_net(dst->dev);
|
||||
unsigned int header_size = sizeof(struct tcphdr) + sizeof(struct iphdr);
|
||||
unsigned int advmss = max_t(unsigned int, ipv4_mtu(dst) - header_size,
|
||||
net->ipv4.ip_rt_min_advmss);
|
||||
unsigned int advmss;
|
||||
struct net *net;
|
||||
|
||||
rcu_read_lock();
|
||||
net = dev_net_rcu(dst->dev);
|
||||
advmss = max_t(unsigned int, ipv4_mtu(dst) - header_size,
|
||||
net->ipv4.ip_rt_min_advmss);
|
||||
rcu_read_unlock();
|
||||
|
||||
return min(advmss, IPV4_MAX_PMTU - header_size);
|
||||
}
|
||||
|
||||
@@ -1731,21 +1731,19 @@ static struct sk_buff *mld_newpack(struct inet6_dev *idev, unsigned int mtu)
|
||||
struct net_device *dev = idev->dev;
|
||||
int hlen = LL_RESERVED_SPACE(dev);
|
||||
int tlen = dev->needed_tailroom;
|
||||
struct net *net = dev_net(dev);
|
||||
const struct in6_addr *saddr;
|
||||
struct in6_addr addr_buf;
|
||||
struct mld2_report *pmr;
|
||||
struct sk_buff *skb;
|
||||
unsigned int size;
|
||||
struct sock *sk;
|
||||
int err;
|
||||
struct net *net;
|
||||
|
||||
sk = net->ipv6.igmp_sk;
|
||||
/* we assume size > sizeof(ra) here
|
||||
* Also try to not allocate high-order pages for big MTU
|
||||
*/
|
||||
size = min_t(int, mtu, PAGE_SIZE / 2) + hlen + tlen;
|
||||
skb = sock_alloc_send_skb(sk, size, 1, &err);
|
||||
skb = alloc_skb(size, GFP_KERNEL);
|
||||
if (!skb)
|
||||
return NULL;
|
||||
|
||||
@@ -1753,6 +1751,12 @@ static struct sk_buff *mld_newpack(struct inet6_dev *idev, unsigned int mtu)
|
||||
skb_reserve(skb, hlen);
|
||||
skb_tailroom_reserve(skb, mtu, tlen);
|
||||
|
||||
rcu_read_lock();
|
||||
|
||||
net = dev_net_rcu(dev);
|
||||
sk = net->ipv6.igmp_sk;
|
||||
skb_set_owner_w(skb, sk);
|
||||
|
||||
if (ipv6_get_lladdr(dev, &addr_buf, IFA_F_TENTATIVE)) {
|
||||
/* <draft-ietf-magma-mld-source-05.txt>:
|
||||
* use unspecified address as the source address
|
||||
@@ -1764,6 +1768,8 @@ static struct sk_buff *mld_newpack(struct inet6_dev *idev, unsigned int mtu)
|
||||
|
||||
ip6_mc_hdr(sk, skb, dev, saddr, &mld2_all_mcr, NEXTHDR_HOP, 0);
|
||||
|
||||
rcu_read_unlock();
|
||||
|
||||
skb_put_data(skb, ra, sizeof(ra));
|
||||
|
||||
skb_set_transport_header(skb, skb_tail_pointer(skb) - skb->data);
|
||||
|
||||
@@ -418,15 +418,11 @@ static struct sk_buff *ndisc_alloc_skb(struct net_device *dev,
|
||||
{
|
||||
int hlen = LL_RESERVED_SPACE(dev);
|
||||
int tlen = dev->needed_tailroom;
|
||||
struct sock *sk = dev_net(dev)->ipv6.ndisc_sk;
|
||||
struct sk_buff *skb;
|
||||
|
||||
skb = alloc_skb(hlen + sizeof(struct ipv6hdr) + len + tlen, GFP_ATOMIC);
|
||||
if (!skb) {
|
||||
ND_PRINTK(0, err, "ndisc: %s failed to allocate an skb\n",
|
||||
__func__);
|
||||
if (!skb)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
skb->protocol = htons(ETH_P_IPV6);
|
||||
skb->dev = dev;
|
||||
@@ -437,7 +433,9 @@ static struct sk_buff *ndisc_alloc_skb(struct net_device *dev,
|
||||
/* Manually assign socket ownership as we avoid calling
|
||||
* sock_alloc_send_pskb() to bypass wmem buffer limits
|
||||
*/
|
||||
skb_set_owner_w(skb, sk);
|
||||
rcu_read_lock();
|
||||
skb_set_owner_w(skb, dev_net_rcu(dev)->ipv6.ndisc_sk);
|
||||
rcu_read_unlock();
|
||||
|
||||
return skb;
|
||||
}
|
||||
@@ -473,16 +471,20 @@ static void ip6_nd_hdr(struct sk_buff *skb,
|
||||
void ndisc_send_skb(struct sk_buff *skb, const struct in6_addr *daddr,
|
||||
const struct in6_addr *saddr)
|
||||
{
|
||||
struct dst_entry *dst = skb_dst(skb);
|
||||
struct net *net = dev_net(skb->dev);
|
||||
struct sock *sk = net->ipv6.ndisc_sk;
|
||||
struct inet6_dev *idev;
|
||||
int err;
|
||||
struct icmp6hdr *icmp6h = icmp6_hdr(skb);
|
||||
struct dst_entry *dst = skb_dst(skb);
|
||||
struct inet6_dev *idev;
|
||||
struct net *net;
|
||||
struct sock *sk;
|
||||
int err;
|
||||
u8 type;
|
||||
|
||||
type = icmp6h->icmp6_type;
|
||||
|
||||
rcu_read_lock();
|
||||
|
||||
net = dev_net_rcu(skb->dev);
|
||||
sk = net->ipv6.ndisc_sk;
|
||||
if (!dst) {
|
||||
struct flowi6 fl6;
|
||||
int oif = skb->dev->ifindex;
|
||||
@@ -490,6 +492,7 @@ void ndisc_send_skb(struct sk_buff *skb, const struct in6_addr *daddr,
|
||||
icmpv6_flow_init(sk, &fl6, type, saddr, daddr, oif);
|
||||
dst = icmp6_dst_alloc(skb->dev, &fl6);
|
||||
if (IS_ERR(dst)) {
|
||||
rcu_read_unlock();
|
||||
kfree_skb(skb);
|
||||
return;
|
||||
}
|
||||
@@ -504,7 +507,6 @@ void ndisc_send_skb(struct sk_buff *skb, const struct in6_addr *daddr,
|
||||
|
||||
ip6_nd_hdr(skb, saddr, daddr, inet6_sk(sk)->hop_limit, skb->len);
|
||||
|
||||
rcu_read_lock();
|
||||
idev = __in6_dev_get(dst->dev);
|
||||
IP6_UPD_PO_STATS(net, idev, IPSTATS_MIB_OUT, skb->len);
|
||||
|
||||
|
||||
@@ -3190,13 +3190,18 @@ static unsigned int ip6_default_advmss(const struct dst_entry *dst)
|
||||
{
|
||||
struct net_device *dev = dst->dev;
|
||||
unsigned int mtu = dst_mtu(dst);
|
||||
struct net *net = dev_net(dev);
|
||||
struct net *net;
|
||||
|
||||
mtu -= sizeof(struct ipv6hdr) + sizeof(struct tcphdr);
|
||||
|
||||
rcu_read_lock();
|
||||
|
||||
net = dev_net_rcu(dev);
|
||||
if (mtu < net->ipv6.sysctl.ip6_rt_min_advmss)
|
||||
mtu = net->ipv6.sysctl.ip6_rt_min_advmss;
|
||||
|
||||
rcu_read_unlock();
|
||||
|
||||
/*
|
||||
* Maximal non-jumbo IPv6 payload is IPV6_MAXPLEN and
|
||||
* corresponding MSS is IPV6_MAXPLEN - tcp_header_size.
|
||||
|
||||
@@ -2076,6 +2076,7 @@ static int ovs_vport_cmd_fill_info(struct vport *vport, struct sk_buff *skb,
|
||||
{
|
||||
struct ovs_header *ovs_header;
|
||||
struct ovs_vport_stats vport_stats;
|
||||
struct net *net_vport;
|
||||
int err;
|
||||
|
||||
ovs_header = genlmsg_put(skb, portid, seq, &dp_vport_genl_family,
|
||||
@@ -2092,12 +2093,15 @@ static int ovs_vport_cmd_fill_info(struct vport *vport, struct sk_buff *skb,
|
||||
nla_put_u32(skb, OVS_VPORT_ATTR_IFINDEX, vport->dev->ifindex))
|
||||
goto nla_put_failure;
|
||||
|
||||
if (!net_eq(net, dev_net(vport->dev))) {
|
||||
int id = peernet2id_alloc(net, dev_net(vport->dev), gfp);
|
||||
rcu_read_lock();
|
||||
net_vport = dev_net_rcu(vport->dev);
|
||||
if (!net_eq(net, net_vport)) {
|
||||
int id = peernet2id_alloc(net, net_vport, GFP_ATOMIC);
|
||||
|
||||
if (nla_put_s32(skb, OVS_VPORT_ATTR_NETNSID, id))
|
||||
goto nla_put_failure;
|
||||
goto nla_put_failure_unlock;
|
||||
}
|
||||
rcu_read_unlock();
|
||||
|
||||
ovs_vport_get_stats(vport, &vport_stats);
|
||||
if (nla_put_64bit(skb, OVS_VPORT_ATTR_STATS,
|
||||
@@ -2115,6 +2119,8 @@ static int ovs_vport_cmd_fill_info(struct vport *vport, struct sk_buff *skb,
|
||||
genlmsg_end(skb, ovs_header);
|
||||
return 0;
|
||||
|
||||
nla_put_failure_unlock:
|
||||
rcu_read_unlock();
|
||||
nla_put_failure:
|
||||
err = -EMSGSIZE;
|
||||
error:
|
||||
|
||||
@@ -197,6 +197,12 @@
|
||||
#
|
||||
# - pmtu_ipv6_route_change
|
||||
# Same as above but with IPv6
|
||||
#
|
||||
# - pmtu_ipv4_mp_exceptions
|
||||
# Use the same topology as in pmtu_ipv4, but add routeable addresses
|
||||
# on host A and B on lo reachable via both routers. Host A and B
|
||||
# addresses have multipath routes to each other, b_r1 mtu = 1500.
|
||||
# Check that PMTU exceptions are created for both paths.
|
||||
|
||||
# Kselftest framework requirement - SKIP code is 4.
|
||||
ksft_skip=4
|
||||
@@ -266,7 +272,8 @@ tests="
|
||||
list_flush_ipv4_exception ipv4: list and flush cached exceptions 1
|
||||
list_flush_ipv6_exception ipv6: list and flush cached exceptions 1
|
||||
pmtu_ipv4_route_change ipv4: PMTU exception w/route replace 1
|
||||
pmtu_ipv6_route_change ipv6: PMTU exception w/route replace 1"
|
||||
pmtu_ipv6_route_change ipv6: PMTU exception w/route replace 1
|
||||
pmtu_ipv4_mp_exceptions ipv4: PMTU multipath nh exceptions 1"
|
||||
|
||||
NS_A="ns-A"
|
||||
NS_B="ns-B"
|
||||
@@ -353,6 +360,9 @@ tunnel6_a_addr="fd00:2::a"
|
||||
tunnel6_b_addr="fd00:2::b"
|
||||
tunnel6_mask="64"
|
||||
|
||||
host4_a_addr="192.168.99.99"
|
||||
host4_b_addr="192.168.88.88"
|
||||
|
||||
dummy6_0_prefix="fc00:1000::"
|
||||
dummy6_1_prefix="fc00:1001::"
|
||||
dummy6_mask="64"
|
||||
@@ -907,6 +917,52 @@ setup_ovs_bridge() {
|
||||
run_cmd ip route add ${prefix6}:${b_r1}::1 via ${prefix6}:${a_r1}::2
|
||||
}
|
||||
|
||||
setup_multipath_new() {
|
||||
# Set up host A with multipath routes to host B host4_b_addr
|
||||
run_cmd ${ns_a} ip addr add ${host4_a_addr} dev lo
|
||||
run_cmd ${ns_a} ip nexthop add id 401 via ${prefix4}.${a_r1}.2 dev veth_A-R1
|
||||
run_cmd ${ns_a} ip nexthop add id 402 via ${prefix4}.${a_r2}.2 dev veth_A-R2
|
||||
run_cmd ${ns_a} ip nexthop add id 403 group 401/402
|
||||
run_cmd ${ns_a} ip route add ${host4_b_addr} src ${host4_a_addr} nhid 403
|
||||
|
||||
# Set up host B with multipath routes to host A host4_a_addr
|
||||
run_cmd ${ns_b} ip addr add ${host4_b_addr} dev lo
|
||||
run_cmd ${ns_b} ip nexthop add id 401 via ${prefix4}.${b_r1}.2 dev veth_B-R1
|
||||
run_cmd ${ns_b} ip nexthop add id 402 via ${prefix4}.${b_r2}.2 dev veth_B-R2
|
||||
run_cmd ${ns_b} ip nexthop add id 403 group 401/402
|
||||
run_cmd ${ns_b} ip route add ${host4_a_addr} src ${host4_b_addr} nhid 403
|
||||
}
|
||||
|
||||
setup_multipath_old() {
|
||||
# Set up host A with multipath routes to host B host4_b_addr
|
||||
run_cmd ${ns_a} ip addr add ${host4_a_addr} dev lo
|
||||
run_cmd ${ns_a} ip route add ${host4_b_addr} \
|
||||
src ${host4_a_addr} \
|
||||
nexthop via ${prefix4}.${a_r1}.2 weight 1 \
|
||||
nexthop via ${prefix4}.${a_r2}.2 weight 1
|
||||
|
||||
# Set up host B with multipath routes to host A host4_a_addr
|
||||
run_cmd ${ns_b} ip addr add ${host4_b_addr} dev lo
|
||||
run_cmd ${ns_b} ip route add ${host4_a_addr} \
|
||||
src ${host4_b_addr} \
|
||||
nexthop via ${prefix4}.${b_r1}.2 weight 1 \
|
||||
nexthop via ${prefix4}.${b_r2}.2 weight 1
|
||||
}
|
||||
|
||||
setup_multipath() {
|
||||
if [ "$USE_NH" = "yes" ]; then
|
||||
setup_multipath_new
|
||||
else
|
||||
setup_multipath_old
|
||||
fi
|
||||
|
||||
# Set up routers with routes to dummies
|
||||
run_cmd ${ns_r1} ip route add ${host4_a_addr} via ${prefix4}.${a_r1}.1
|
||||
run_cmd ${ns_r2} ip route add ${host4_a_addr} via ${prefix4}.${a_r2}.1
|
||||
run_cmd ${ns_r1} ip route add ${host4_b_addr} via ${prefix4}.${b_r1}.1
|
||||
run_cmd ${ns_r2} ip route add ${host4_b_addr} via ${prefix4}.${b_r2}.1
|
||||
}
|
||||
|
||||
setup() {
|
||||
[ "$(id -u)" -ne 0 ] && echo " need to run as root" && return $ksft_skip
|
||||
|
||||
@@ -988,23 +1044,15 @@ link_get_mtu() {
|
||||
}
|
||||
|
||||
route_get_dst_exception() {
|
||||
ns_cmd="${1}"
|
||||
dst="${2}"
|
||||
dsfield="${3}"
|
||||
ns_cmd="${1}"; shift
|
||||
|
||||
if [ -z "${dsfield}" ]; then
|
||||
dsfield=0
|
||||
fi
|
||||
|
||||
${ns_cmd} ip route get "${dst}" dsfield "${dsfield}"
|
||||
${ns_cmd} ip route get "$@"
|
||||
}
|
||||
|
||||
route_get_dst_pmtu_from_exception() {
|
||||
ns_cmd="${1}"
|
||||
dst="${2}"
|
||||
dsfield="${3}"
|
||||
ns_cmd="${1}"; shift
|
||||
|
||||
mtu_parse "$(route_get_dst_exception "${ns_cmd}" "${dst}" "${dsfield}")"
|
||||
mtu_parse "$(route_get_dst_exception "${ns_cmd}" "$@")"
|
||||
}
|
||||
|
||||
check_pmtu_value() {
|
||||
@@ -1147,10 +1195,10 @@ test_pmtu_ipv4_dscp_icmp_exception() {
|
||||
run_cmd "${ns_a}" ping -q -M want -Q "${dsfield}" -c 1 -w 1 -s "${len}" "${dst2}"
|
||||
|
||||
# Check that exceptions have been created with the correct PMTU
|
||||
pmtu_1="$(route_get_dst_pmtu_from_exception "${ns_a}" "${dst1}" "${policy_mark}")"
|
||||
pmtu_1="$(route_get_dst_pmtu_from_exception "${ns_a}" "${dst1}" dsfield "${policy_mark}")"
|
||||
check_pmtu_value "1400" "${pmtu_1}" "exceeding MTU" || return 1
|
||||
|
||||
pmtu_2="$(route_get_dst_pmtu_from_exception "${ns_a}" "${dst2}" "${policy_mark}")"
|
||||
pmtu_2="$(route_get_dst_pmtu_from_exception "${ns_a}" "${dst2}" dsfield "${policy_mark}")"
|
||||
check_pmtu_value "1500" "${pmtu_2}" "exceeding MTU" || return 1
|
||||
}
|
||||
|
||||
@@ -1197,9 +1245,9 @@ test_pmtu_ipv4_dscp_udp_exception() {
|
||||
UDP:"${dst2}":50000,tos="${dsfield}"
|
||||
|
||||
# Check that exceptions have been created with the correct PMTU
|
||||
pmtu_1="$(route_get_dst_pmtu_from_exception "${ns_a}" "${dst1}" "${policy_mark}")"
|
||||
pmtu_1="$(route_get_dst_pmtu_from_exception "${ns_a}" "${dst1}" dsfield "${policy_mark}")"
|
||||
check_pmtu_value "1400" "${pmtu_1}" "exceeding MTU" || return 1
|
||||
pmtu_2="$(route_get_dst_pmtu_from_exception "${ns_a}" "${dst2}" "${policy_mark}")"
|
||||
pmtu_2="$(route_get_dst_pmtu_from_exception "${ns_a}" "${dst2}" dsfield "${policy_mark}")"
|
||||
check_pmtu_value "1500" "${pmtu_2}" "exceeding MTU" || return 1
|
||||
}
|
||||
|
||||
@@ -2205,6 +2253,36 @@ test_pmtu_ipv6_route_change() {
|
||||
test_pmtu_ipvX_route_change 6
|
||||
}
|
||||
|
||||
test_pmtu_ipv4_mp_exceptions() {
|
||||
setup namespaces routing multipath || return $ksft_skip
|
||||
|
||||
trace "${ns_a}" veth_A-R1 "${ns_r1}" veth_R1-A \
|
||||
"${ns_r1}" veth_R1-B "${ns_b}" veth_B-R1 \
|
||||
"${ns_a}" veth_A-R2 "${ns_r2}" veth_R2-A \
|
||||
"${ns_r2}" veth_R2-B "${ns_b}" veth_B-R2
|
||||
|
||||
# Set up initial MTU values
|
||||
mtu "${ns_a}" veth_A-R1 2000
|
||||
mtu "${ns_r1}" veth_R1-A 2000
|
||||
mtu "${ns_r1}" veth_R1-B 1500
|
||||
mtu "${ns_b}" veth_B-R1 1500
|
||||
|
||||
mtu "${ns_a}" veth_A-R2 2000
|
||||
mtu "${ns_r2}" veth_R2-A 2000
|
||||
mtu "${ns_r2}" veth_R2-B 1500
|
||||
mtu "${ns_b}" veth_B-R2 1500
|
||||
|
||||
# Ping and expect two nexthop exceptions for two routes
|
||||
run_cmd ${ns_a} ping -q -M want -i 0.1 -c 1 -s 1800 "${host4_b_addr}"
|
||||
|
||||
# Check that exceptions have been created with the correct PMTU
|
||||
pmtu_a_R1="$(route_get_dst_pmtu_from_exception "${ns_a}" "${host4_b_addr}" oif veth_A-R1)"
|
||||
pmtu_a_R2="$(route_get_dst_pmtu_from_exception "${ns_a}" "${host4_b_addr}" oif veth_A-R2)"
|
||||
|
||||
check_pmtu_value "1500" "${pmtu_a_R1}" "exceeding MTU (veth_A-R1)" || return 1
|
||||
check_pmtu_value "1500" "${pmtu_a_R2}" "exceeding MTU (veth_A-R2)" || return 1
|
||||
}
|
||||
|
||||
usage() {
|
||||
echo
|
||||
echo "$0 [OPTIONS] [TEST]..."
|
||||
|
||||
Reference in New Issue
Block a user