Merge tag 'v6.4-rc7' into android-mainline
Linux 6.4-rc7 Change-Id: Ibfa1318e38f56a847e0295f8658ba2200881e40e Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
@@ -233,6 +233,7 @@ Jisheng Zhang <jszhang@kernel.org> <Jisheng.Zhang@synaptics.com>
|
||||
Johan Hovold <johan@kernel.org> <jhovold@gmail.com>
|
||||
Johan Hovold <johan@kernel.org> <johan@hovoldconsulting.com>
|
||||
John Crispin <john@phrozen.org> <blogic@openwrt.org>
|
||||
John Keeping <john@keeping.me.uk> <john@metanate.com>
|
||||
John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de>
|
||||
John Stultz <johnstul@us.ibm.com>
|
||||
<jon.toppins+linux@gmail.com> <jtoppins@cumulusnetworks.com>
|
||||
|
||||
@@ -8,7 +8,7 @@ title: Common Properties for Serial ATA AHCI controllers
|
||||
|
||||
maintainers:
|
||||
- Hans de Goede <hdegoede@redhat.com>
|
||||
- Damien Le Moal <damien.lemoal@opensource.wdc.com>
|
||||
- Damien Le Moal <dlemoal@kernel.org>
|
||||
|
||||
description:
|
||||
This document defines device tree properties for a common AHCI SATA
|
||||
|
||||
@@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
title: Canaan Kendryte K210 Clock
|
||||
|
||||
maintainers:
|
||||
- Damien Le Moal <damien.lemoal@wdc.com>
|
||||
- Damien Le Moal <dlemoal@kernel.org>
|
||||
|
||||
description: |
|
||||
Canaan Kendryte K210 SoC clocks driver bindings. The clock
|
||||
|
||||
@@ -44,7 +44,7 @@ required:
|
||||
- clock-names
|
||||
- clocks
|
||||
|
||||
additionalProperties: true
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
|
||||
@@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
title: Canaan Kendryte K210 System Controller
|
||||
|
||||
maintainers:
|
||||
- Damien Le Moal <damien.lemoal@wdc.com>
|
||||
- Damien Le Moal <dlemoal@kernel.org>
|
||||
|
||||
description:
|
||||
Canaan Inc. Kendryte K210 SoC system controller which provides a
|
||||
|
||||
@@ -11,7 +11,7 @@ maintainers:
|
||||
- Alistair Francis <alistair@alistair23.me>
|
||||
|
||||
description:
|
||||
RTL8723CS/RTL8723CS/RTL8821CS/RTL8822CS is a WiFi + BT chip. WiFi part
|
||||
RTL8723BS/RTL8723CS/RTL8821CS/RTL8822CS is a WiFi + BT chip. WiFi part
|
||||
is connected over SDIO, while BT is connected over serial. It speaks
|
||||
H5 protocol with few extra commands to upload firmware and change
|
||||
module speed.
|
||||
@@ -27,7 +27,7 @@ properties:
|
||||
- items:
|
||||
- enum:
|
||||
- realtek,rtl8821cs-bt
|
||||
- const: realtek,rtl8822cs-bt
|
||||
- const: realtek,rtl8723bs-bt
|
||||
|
||||
device-wake-gpios:
|
||||
maxItems: 1
|
||||
|
||||
@@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
title: Canaan Kendryte K210 FPIOA
|
||||
|
||||
maintainers:
|
||||
- Damien Le Moal <damien.lemoal@wdc.com>
|
||||
- Damien Le Moal <dlemoal@kernel.org>
|
||||
|
||||
description:
|
||||
The Canaan Kendryte K210 SoC Fully Programmable IO Array (FPIOA)
|
||||
|
||||
@@ -144,8 +144,9 @@ $defs:
|
||||
enum: [0, 1, 2, 3, 4, 5, 6, 7]
|
||||
|
||||
qcom,paired:
|
||||
- description:
|
||||
Indicates that the pin should be operating in paired mode.
|
||||
type: boolean
|
||||
description:
|
||||
Indicates that the pin should be operating in paired mode.
|
||||
|
||||
required:
|
||||
- pins
|
||||
|
||||
@@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
title: Canaan Kendryte K210 Reset Controller
|
||||
|
||||
maintainers:
|
||||
- Damien Le Moal <damien.lemoal@wdc.com>
|
||||
- Damien Le Moal <dlemoal@kernel.org>
|
||||
|
||||
description: |
|
||||
Canaan Kendryte K210 reset controller driver which supports the SoC
|
||||
|
||||
@@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
title: Canaan SoC-based boards
|
||||
|
||||
maintainers:
|
||||
- Damien Le Moal <damien.lemoal@wdc.com>
|
||||
- Damien Le Moal <dlemoal@kernel.org>
|
||||
|
||||
description:
|
||||
Canaan Kendryte K210 SoC-based boards
|
||||
|
||||
@@ -415,6 +415,6 @@ When using the DT, this creates problems for of_platform_populate()
|
||||
because it must decide whether to register each node as either a
|
||||
platform_device or an amba_device. This unfortunately complicates the
|
||||
device creation model a little bit, but the solution turns out not to
|
||||
be too invasive. If a node is compatible with "arm,amba-primecell", then
|
||||
be too invasive. If a node is compatible with "arm,primecell", then
|
||||
of_platform_populate() will register it as an amba_device instead of a
|
||||
platform_device.
|
||||
|
||||
@@ -16,6 +16,24 @@ tested code over experimental code. We wish to extend these same
|
||||
principles to the RISC-V-related code that will be accepted for
|
||||
inclusion in the kernel.
|
||||
|
||||
Patchwork
|
||||
---------
|
||||
|
||||
RISC-V has a patchwork instance, where the status of patches can be checked:
|
||||
|
||||
https://patchwork.kernel.org/project/linux-riscv/list/
|
||||
|
||||
If your patch does not appear in the default view, the RISC-V maintainers have
|
||||
likely either requested changes, or expect it to be applied to another tree.
|
||||
|
||||
Automation runs against this patchwork instance, building/testing patches as
|
||||
they arrive. The automation applies patches against the current HEAD of the
|
||||
RISC-V `for-next` and `fixes` branches, depending on whether the patch has been
|
||||
detected as a fix. Failing those, it will use the RISC-V `master` branch.
|
||||
The exact commit to which a series has been applied will be noted on patchwork.
|
||||
Patches for which any of the checks fail are unlikely to be applied and in most
|
||||
cases will need to be resubmitted.
|
||||
|
||||
Submit Checklist Addendum
|
||||
-------------------------
|
||||
We'll only accept patches for new modules or extensions if the
|
||||
|
||||
@@ -325,6 +325,6 @@ Primecell设备。然而,棘手的一点是,AMBA总线上的所有设备并
|
||||
|
||||
当使用DT时,这给of_platform_populate()带来了问题,因为它必须决定是否将
|
||||
每个节点注册为platform_device或amba_device。不幸的是,这使设备创建模型
|
||||
变得有点复杂,但解决方案原来并不是太具有侵略性。如果一个节点与“arm,amba-primecell”
|
||||
变得有点复杂,但解决方案原来并不是太具有侵略性。如果一个节点与“arm,primecell”
|
||||
兼容,那么of_platform_populate()将把它注册为amba_device而不是
|
||||
platform_device。
|
||||
|
||||
@@ -19147,6 +19147,9 @@ SHARED MEMORY COMMUNICATIONS (SMC) SOCKETS
|
||||
M: Karsten Graul <kgraul@linux.ibm.com>
|
||||
M: Wenjia Zhang <wenjia@linux.ibm.com>
|
||||
M: Jan Karcher <jaka@linux.ibm.com>
|
||||
R: D. Wythe <alibuda@linux.alibaba.com>
|
||||
R: Tony Lu <tonylu@linux.alibaba.com>
|
||||
R: Wen Gu <guwen@linux.alibaba.com>
|
||||
L: linux-s390@vger.kernel.org
|
||||
S: Supported
|
||||
F: net/smc/
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
VERSION = 6
|
||||
PATCHLEVEL = 4
|
||||
SUBLEVEL = 0
|
||||
EXTRAVERSION = -rc6
|
||||
EXTRAVERSION = -rc7
|
||||
NAME = Hurr durr I'ma ninja sloth
|
||||
|
||||
# *DOCUMENTATION*
|
||||
|
||||
@@ -1496,7 +1496,7 @@ __BUILD_CSR_OP(tlbidx)
|
||||
#define write_fcsr(dest, val) \
|
||||
do { \
|
||||
__asm__ __volatile__( \
|
||||
" movgr2fcsr %0, "__stringify(dest)" \n" \
|
||||
" movgr2fcsr "__stringify(dest)", %0 \n" \
|
||||
: : "r" (val)); \
|
||||
} while (0)
|
||||
|
||||
|
||||
@@ -22,12 +22,14 @@
|
||||
#define _PAGE_PFN_SHIFT 12
|
||||
#define _PAGE_SWP_EXCLUSIVE_SHIFT 23
|
||||
#define _PAGE_PFN_END_SHIFT 48
|
||||
#define _PAGE_PRESENT_INVALID_SHIFT 60
|
||||
#define _PAGE_NO_READ_SHIFT 61
|
||||
#define _PAGE_NO_EXEC_SHIFT 62
|
||||
#define _PAGE_RPLV_SHIFT 63
|
||||
|
||||
/* Used by software */
|
||||
#define _PAGE_PRESENT (_ULCAST_(1) << _PAGE_PRESENT_SHIFT)
|
||||
#define _PAGE_PRESENT_INVALID (_ULCAST_(1) << _PAGE_PRESENT_INVALID_SHIFT)
|
||||
#define _PAGE_WRITE (_ULCAST_(1) << _PAGE_WRITE_SHIFT)
|
||||
#define _PAGE_ACCESSED (_ULCAST_(1) << _PAGE_ACCESSED_SHIFT)
|
||||
#define _PAGE_MODIFIED (_ULCAST_(1) << _PAGE_MODIFIED_SHIFT)
|
||||
|
||||
@@ -213,7 +213,7 @@ static inline int pmd_bad(pmd_t pmd)
|
||||
static inline int pmd_present(pmd_t pmd)
|
||||
{
|
||||
if (unlikely(pmd_val(pmd) & _PAGE_HUGE))
|
||||
return !!(pmd_val(pmd) & (_PAGE_PRESENT | _PAGE_PROTNONE));
|
||||
return !!(pmd_val(pmd) & (_PAGE_PRESENT | _PAGE_PROTNONE | _PAGE_PRESENT_INVALID));
|
||||
|
||||
return pmd_val(pmd) != (unsigned long)invalid_pte_table;
|
||||
}
|
||||
@@ -558,6 +558,7 @@ static inline pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot)
|
||||
|
||||
static inline pmd_t pmd_mkinvalid(pmd_t pmd)
|
||||
{
|
||||
pmd_val(pmd) |= _PAGE_PRESENT_INVALID;
|
||||
pmd_val(pmd) &= ~(_PAGE_PRESENT | _PAGE_VALID | _PAGE_DIRTY | _PAGE_PROTNONE);
|
||||
|
||||
return pmd;
|
||||
|
||||
@@ -396,6 +396,8 @@ int hw_breakpoint_arch_parse(struct perf_event *bp,
|
||||
|
||||
if (hw->ctrl.type != LOONGARCH_BREAKPOINT_EXECUTE)
|
||||
alignment_mask = 0x7;
|
||||
else
|
||||
alignment_mask = 0x3;
|
||||
offset = hw->address & alignment_mask;
|
||||
|
||||
hw->address &= ~alignment_mask;
|
||||
|
||||
@@ -271,7 +271,7 @@ static void loongarch_pmu_enable_event(struct hw_perf_event *evt, int idx)
|
||||
WARN_ON(idx < 0 || idx >= loongarch_pmu.num_counters);
|
||||
|
||||
/* Make sure interrupt enabled. */
|
||||
cpuc->saved_ctrl[idx] = M_PERFCTL_EVENT(evt->event_base & 0xff) |
|
||||
cpuc->saved_ctrl[idx] = M_PERFCTL_EVENT(evt->event_base) |
|
||||
(evt->config_base & M_PERFCTL_CONFIG_MASK) | CSR_PERFCTRL_IE;
|
||||
|
||||
cpu = (event->cpu >= 0) ? event->cpu : smp_processor_id();
|
||||
@@ -594,7 +594,7 @@ static struct pmu pmu = {
|
||||
|
||||
static unsigned int loongarch_pmu_perf_event_encode(const struct loongarch_perf_event *pev)
|
||||
{
|
||||
return (pev->event_id & 0xff);
|
||||
return M_PERFCTL_EVENT(pev->event_id);
|
||||
}
|
||||
|
||||
static const struct loongarch_perf_event *loongarch_pmu_map_general_event(int idx)
|
||||
@@ -849,7 +849,7 @@ static void resume_local_counters(void)
|
||||
|
||||
static const struct loongarch_perf_event *loongarch_pmu_map_raw_event(u64 config)
|
||||
{
|
||||
raw_event.event_id = config & 0xff;
|
||||
raw_event.event_id = M_PERFCTL_EVENT(config);
|
||||
|
||||
return &raw_event;
|
||||
}
|
||||
|
||||
@@ -485,7 +485,7 @@ static int __init debugfs_unaligned(void)
|
||||
struct dentry *d;
|
||||
|
||||
d = debugfs_create_dir("loongarch", NULL);
|
||||
if (!d)
|
||||
if (IS_ERR_OR_NULL(d))
|
||||
return -ENOMEM;
|
||||
|
||||
debugfs_create_u32("unaligned_instructions_user",
|
||||
|
||||
@@ -97,7 +97,7 @@
|
||||
rx-fifo-depth = <8192>;
|
||||
tx-fifo-depth = <8192>;
|
||||
address-bits = <48>;
|
||||
max-frame-size = <1518>;
|
||||
max-frame-size = <1500>;
|
||||
local-mac-address = [00 00 00 00 00 00];
|
||||
altr,has-supplementary-unicast;
|
||||
altr,enable-sup-addr = <1>;
|
||||
|
||||
@@ -106,7 +106,7 @@
|
||||
interrupt-names = "rx_irq", "tx_irq";
|
||||
rx-fifo-depth = <8192>;
|
||||
tx-fifo-depth = <8192>;
|
||||
max-frame-size = <1518>;
|
||||
max-frame-size = <1500>;
|
||||
local-mac-address = [ 00 00 00 00 00 00 ];
|
||||
phy-mode = "rgmii-id";
|
||||
phy-handle = <&phy0>;
|
||||
|
||||
@@ -90,10 +90,6 @@
|
||||
#include <asm/asmregs.h>
|
||||
#include <asm/psw.h>
|
||||
|
||||
sp = 30
|
||||
gp = 27
|
||||
ipsw = 22
|
||||
|
||||
/*
|
||||
* We provide two versions of each macro to convert from physical
|
||||
* to virtual and vice versa. The "_r1" versions take one argument
|
||||
|
||||
@@ -5,6 +5,11 @@ KCSAN_SANITIZE := n
|
||||
|
||||
targets += trampoline_$(BITS).o purgatory.ro
|
||||
|
||||
# When profile-guided optimization is enabled, llvm emits two different
|
||||
# overlapping text sections, which is not supported by kexec. Remove profile
|
||||
# optimization flags.
|
||||
KBUILD_CFLAGS := $(filter-out -fprofile-sample-use=% -fprofile-use=%,$(KBUILD_CFLAGS))
|
||||
|
||||
LDFLAGS_purgatory.ro := -e purgatory_start -r --no-undefined
|
||||
|
||||
$(obj)/purgatory.ro: $(obj)/trampoline_$(BITS).o FORCE
|
||||
|
||||
@@ -35,6 +35,11 @@ CFLAGS_sha256.o := -D__DISABLE_EXPORTS
|
||||
CFLAGS_string.o := -D__DISABLE_EXPORTS
|
||||
CFLAGS_ctype.o := -D__DISABLE_EXPORTS
|
||||
|
||||
# When profile-guided optimization is enabled, llvm emits two different
|
||||
# overlapping text sections, which is not supported by kexec. Remove profile
|
||||
# optimization flags.
|
||||
KBUILD_CFLAGS := $(filter-out -fprofile-sample-use=% -fprofile-use=%,$(KBUILD_CFLAGS))
|
||||
|
||||
# When linking purgatory.ro with -r unresolved symbols are not checked,
|
||||
# also link a purgatory.chk binary without -r to check for unresolved symbols.
|
||||
PURGATORY_LDFLAGS := -e purgatory_start -z nodefaultlib
|
||||
|
||||
@@ -14,6 +14,11 @@ $(obj)/sha256.o: $(srctree)/lib/crypto/sha256.c FORCE
|
||||
|
||||
CFLAGS_sha256.o := -D__DISABLE_EXPORTS
|
||||
|
||||
# When profile-guided optimization is enabled, llvm emits two different
|
||||
# overlapping text sections, which is not supported by kexec. Remove profile
|
||||
# optimization flags.
|
||||
KBUILD_CFLAGS := $(filter-out -fprofile-sample-use=% -fprofile-use=%,$(KBUILD_CFLAGS))
|
||||
|
||||
# When linking purgatory.ro with -r unresolved symbols are not checked,
|
||||
# also link a purgatory.chk binary without -r to check for unresolved symbols.
|
||||
PURGATORY_LDFLAGS := -e purgatory_start -z nodefaultlib
|
||||
|
||||
+31
-9
@@ -34,6 +34,8 @@
|
||||
#include "blk-ioprio.h"
|
||||
#include "blk-throttle.h"
|
||||
|
||||
static void __blkcg_rstat_flush(struct blkcg *blkcg, int cpu);
|
||||
|
||||
/*
|
||||
* blkcg_pol_mutex protects blkcg_policy[] and policy [de]activation.
|
||||
* blkcg_pol_register_mutex nests outside of it and synchronizes entire
|
||||
@@ -56,6 +58,8 @@ static LIST_HEAD(all_blkcgs); /* protected by blkcg_pol_mutex */
|
||||
|
||||
bool blkcg_debug_stats = false;
|
||||
|
||||
static DEFINE_RAW_SPINLOCK(blkg_stat_lock);
|
||||
|
||||
#define BLKG_DESTROY_BATCH_SIZE 64
|
||||
|
||||
/*
|
||||
@@ -163,10 +167,20 @@ static void blkg_free(struct blkcg_gq *blkg)
|
||||
static void __blkg_release(struct rcu_head *rcu)
|
||||
{
|
||||
struct blkcg_gq *blkg = container_of(rcu, struct blkcg_gq, rcu_head);
|
||||
struct blkcg *blkcg = blkg->blkcg;
|
||||
int cpu;
|
||||
|
||||
#ifdef CONFIG_BLK_CGROUP_PUNT_BIO
|
||||
WARN_ON(!bio_list_empty(&blkg->async_bios));
|
||||
#endif
|
||||
/*
|
||||
* Flush all the non-empty percpu lockless lists before releasing
|
||||
* us, given these stat belongs to us.
|
||||
*
|
||||
* blkg_stat_lock is for serializing blkg stat update
|
||||
*/
|
||||
for_each_possible_cpu(cpu)
|
||||
__blkcg_rstat_flush(blkcg, cpu);
|
||||
|
||||
/* release the blkcg and parent blkg refs this blkg has been holding */
|
||||
css_put(&blkg->blkcg->css);
|
||||
@@ -951,23 +965,26 @@ static void blkcg_iostat_update(struct blkcg_gq *blkg, struct blkg_iostat *cur,
|
||||
u64_stats_update_end_irqrestore(&blkg->iostat.sync, flags);
|
||||
}
|
||||
|
||||
static void blkcg_rstat_flush(struct cgroup_subsys_state *css, int cpu)
|
||||
static void __blkcg_rstat_flush(struct blkcg *blkcg, int cpu)
|
||||
{
|
||||
struct blkcg *blkcg = css_to_blkcg(css);
|
||||
struct llist_head *lhead = per_cpu_ptr(blkcg->lhead, cpu);
|
||||
struct llist_node *lnode;
|
||||
struct blkg_iostat_set *bisc, *next_bisc;
|
||||
|
||||
/* Root-level stats are sourced from system-wide IO stats */
|
||||
if (!cgroup_parent(css->cgroup))
|
||||
return;
|
||||
|
||||
rcu_read_lock();
|
||||
|
||||
lnode = llist_del_all(lhead);
|
||||
if (!lnode)
|
||||
goto out;
|
||||
|
||||
/*
|
||||
* For covering concurrent parent blkg update from blkg_release().
|
||||
*
|
||||
* When flushing from cgroup, cgroup_rstat_lock is always held, so
|
||||
* this lock won't cause contention most of time.
|
||||
*/
|
||||
raw_spin_lock(&blkg_stat_lock);
|
||||
|
||||
/*
|
||||
* Iterate only the iostat_cpu's queued in the lockless list.
|
||||
*/
|
||||
@@ -991,13 +1008,19 @@ static void blkcg_rstat_flush(struct cgroup_subsys_state *css, int cpu)
|
||||
if (parent && parent->parent)
|
||||
blkcg_iostat_update(parent, &blkg->iostat.cur,
|
||||
&blkg->iostat.last);
|
||||
percpu_ref_put(&blkg->refcnt);
|
||||
}
|
||||
|
||||
raw_spin_unlock(&blkg_stat_lock);
|
||||
out:
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
static void blkcg_rstat_flush(struct cgroup_subsys_state *css, int cpu)
|
||||
{
|
||||
/* Root-level stats are sourced from system-wide IO stats */
|
||||
if (cgroup_parent(css->cgroup))
|
||||
__blkcg_rstat_flush(css_to_blkcg(css), cpu);
|
||||
}
|
||||
|
||||
/*
|
||||
* We source root cgroup stats from the system-wide stats to avoid
|
||||
* tracking the same information twice and incurring overhead when no
|
||||
@@ -2075,7 +2098,6 @@ void blk_cgroup_bio_start(struct bio *bio)
|
||||
|
||||
llist_add(&bis->lnode, lhead);
|
||||
WRITE_ONCE(bis->lqueued, true);
|
||||
percpu_ref_get(&bis->blkg->refcnt);
|
||||
}
|
||||
|
||||
u64_stats_update_end_irqrestore(&bis->sync, flags);
|
||||
|
||||
@@ -97,6 +97,7 @@ static int qaic_open(struct drm_device *dev, struct drm_file *file)
|
||||
|
||||
cleanup_usr:
|
||||
cleanup_srcu_struct(&usr->qddev_lock);
|
||||
ida_free(&qaic_usrs, usr->handle);
|
||||
free_usr:
|
||||
kfree(usr);
|
||||
dev_unlock:
|
||||
@@ -224,6 +225,9 @@ static void qaic_destroy_drm_device(struct qaic_device *qdev, s32 partition_id)
|
||||
struct qaic_user *usr;
|
||||
|
||||
qddev = qdev->qddev;
|
||||
qdev->qddev = NULL;
|
||||
if (!qddev)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Existing users get unresolvable errors till they close FDs.
|
||||
|
||||
@@ -5348,7 +5348,7 @@ struct ata_port *ata_port_alloc(struct ata_host *host)
|
||||
|
||||
mutex_init(&ap->scsi_scan_mutex);
|
||||
INIT_DELAYED_WORK(&ap->hotplug_task, ata_scsi_hotplug);
|
||||
INIT_WORK(&ap->scsi_rescan_task, ata_scsi_dev_rescan);
|
||||
INIT_DELAYED_WORK(&ap->scsi_rescan_task, ata_scsi_dev_rescan);
|
||||
INIT_LIST_HEAD(&ap->eh_done_q);
|
||||
init_waitqueue_head(&ap->eh_wait_q);
|
||||
init_completion(&ap->park_req_pending);
|
||||
@@ -5954,6 +5954,7 @@ static void ata_port_detach(struct ata_port *ap)
|
||||
WARN_ON(!(ap->pflags & ATA_PFLAG_UNLOADED));
|
||||
|
||||
cancel_delayed_work_sync(&ap->hotplug_task);
|
||||
cancel_delayed_work_sync(&ap->scsi_rescan_task);
|
||||
|
||||
skip_eh:
|
||||
/* clean up zpodd on port removal */
|
||||
|
||||
@@ -2984,7 +2984,7 @@ static int ata_eh_revalidate_and_attach(struct ata_link *link,
|
||||
ehc->i.flags |= ATA_EHI_SETMODE;
|
||||
|
||||
/* schedule the scsi_rescan_device() here */
|
||||
schedule_work(&(ap->scsi_rescan_task));
|
||||
schedule_delayed_work(&ap->scsi_rescan_task, 0);
|
||||
} else if (dev->class == ATA_DEV_UNKNOWN &&
|
||||
ehc->tries[dev->devno] &&
|
||||
ata_class_enabled(ehc->classes[dev->devno])) {
|
||||
|
||||
@@ -4597,10 +4597,11 @@ int ata_scsi_user_scan(struct Scsi_Host *shost, unsigned int channel,
|
||||
void ata_scsi_dev_rescan(struct work_struct *work)
|
||||
{
|
||||
struct ata_port *ap =
|
||||
container_of(work, struct ata_port, scsi_rescan_task);
|
||||
container_of(work, struct ata_port, scsi_rescan_task.work);
|
||||
struct ata_link *link;
|
||||
struct ata_device *dev;
|
||||
unsigned long flags;
|
||||
bool delay_rescan = false;
|
||||
|
||||
mutex_lock(&ap->scsi_scan_mutex);
|
||||
spin_lock_irqsave(ap->lock, flags);
|
||||
@@ -4614,6 +4615,21 @@ void ata_scsi_dev_rescan(struct work_struct *work)
|
||||
if (scsi_device_get(sdev))
|
||||
continue;
|
||||
|
||||
/*
|
||||
* If the rescan work was scheduled because of a resume
|
||||
* event, the port is already fully resumed, but the
|
||||
* SCSI device may not yet be fully resumed. In such
|
||||
* case, executing scsi_rescan_device() may cause a
|
||||
* deadlock with the PM code on device_lock(). Prevent
|
||||
* this by giving up and retrying rescan after a short
|
||||
* delay.
|
||||
*/
|
||||
delay_rescan = sdev->sdev_gendev.power.is_suspended;
|
||||
if (delay_rescan) {
|
||||
scsi_device_put(sdev);
|
||||
break;
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(ap->lock, flags);
|
||||
scsi_rescan_device(&(sdev->sdev_gendev));
|
||||
scsi_device_put(sdev);
|
||||
@@ -4623,4 +4639,8 @@ void ata_scsi_dev_rescan(struct work_struct *work)
|
||||
|
||||
spin_unlock_irqrestore(ap->lock, flags);
|
||||
mutex_unlock(&ap->scsi_scan_mutex);
|
||||
|
||||
if (delay_rescan)
|
||||
schedule_delayed_work(&ap->scsi_rescan_task,
|
||||
msecs_to_jiffies(5));
|
||||
}
|
||||
|
||||
@@ -284,6 +284,9 @@ static bool regcache_reg_needs_sync(struct regmap *map, unsigned int reg,
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!regmap_writeable(map, reg))
|
||||
return false;
|
||||
|
||||
/* If we don't know the chip just got reset, then sync everything. */
|
||||
if (!map->no_sync_defaults)
|
||||
return true;
|
||||
|
||||
@@ -119,7 +119,10 @@ static int clk_composite_determine_rate(struct clk_hw *hw,
|
||||
if (ret)
|
||||
continue;
|
||||
|
||||
rate_diff = abs(req->rate - tmp_req.rate);
|
||||
if (req->rate >= tmp_req.rate)
|
||||
rate_diff = req->rate - tmp_req.rate;
|
||||
else
|
||||
rate_diff = tmp_req.rate - req->rate;
|
||||
|
||||
if (!rate_diff || !req->best_parent_hw
|
||||
|| best_rate_diff > rate_diff) {
|
||||
|
||||
@@ -40,7 +40,7 @@ static struct clk_hw *loongson2_clk_register(struct device *dev,
|
||||
{
|
||||
int ret;
|
||||
struct clk_hw *hw;
|
||||
struct clk_init_data init;
|
||||
struct clk_init_data init = { };
|
||||
|
||||
hw = devm_kzalloc(dev, sizeof(*hw), GFP_KERNEL);
|
||||
if (!hw)
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
static DEFINE_SPINLOCK(mt8365_clk_lock);
|
||||
|
||||
static const struct mtk_fixed_clk top_fixed_clks[] = {
|
||||
FIXED_CLK(CLK_TOP_CLK_NULL, "clk_null", NULL, 0),
|
||||
FIXED_CLK(CLK_TOP_I2S0_BCK, "i2s0_bck", NULL, 26000000),
|
||||
FIXED_CLK(CLK_TOP_DSI0_LNTC_DSICK, "dsi0_lntc_dsick", "clk26m",
|
||||
75000000),
|
||||
@@ -559,6 +560,14 @@ static const struct mtk_clk_divider top_adj_divs[] = {
|
||||
0x324, 16, 8, CLK_DIVIDER_ROUND_CLOSEST),
|
||||
DIV_ADJ_F(CLK_TOP_APLL12_CK_DIV3, "apll12_ck_div3", "apll_i2s3_sel",
|
||||
0x324, 24, 8, CLK_DIVIDER_ROUND_CLOSEST),
|
||||
DIV_ADJ_F(CLK_TOP_APLL12_CK_DIV4, "apll12_ck_div4", "apll_tdmout_sel",
|
||||
0x328, 0, 8, CLK_DIVIDER_ROUND_CLOSEST),
|
||||
DIV_ADJ_F(CLK_TOP_APLL12_CK_DIV4B, "apll12_ck_div4b", "apll_tdmout_sel",
|
||||
0x328, 8, 8, CLK_DIVIDER_ROUND_CLOSEST),
|
||||
DIV_ADJ_F(CLK_TOP_APLL12_CK_DIV5, "apll12_ck_div5", "apll_tdmin_sel",
|
||||
0x328, 16, 8, CLK_DIVIDER_ROUND_CLOSEST),
|
||||
DIV_ADJ_F(CLK_TOP_APLL12_CK_DIV5B, "apll12_ck_div5b", "apll_tdmin_sel",
|
||||
0x328, 24, 8, CLK_DIVIDER_ROUND_CLOSEST),
|
||||
DIV_ADJ_F(CLK_TOP_APLL12_CK_DIV6, "apll12_ck_div6", "apll_spdif_sel",
|
||||
0x32c, 0, 8, CLK_DIVIDER_ROUND_CLOSEST),
|
||||
};
|
||||
@@ -583,15 +592,15 @@ static const struct mtk_gate_regs top2_cg_regs = {
|
||||
|
||||
#define GATE_TOP0(_id, _name, _parent, _shift) \
|
||||
GATE_MTK(_id, _name, _parent, &top0_cg_regs, \
|
||||
_shift, &mtk_clk_gate_ops_no_setclr_inv)
|
||||
_shift, &mtk_clk_gate_ops_no_setclr)
|
||||
|
||||
#define GATE_TOP1(_id, _name, _parent, _shift) \
|
||||
GATE_MTK(_id, _name, _parent, &top1_cg_regs, \
|
||||
_shift, &mtk_clk_gate_ops_no_setclr)
|
||||
_shift, &mtk_clk_gate_ops_no_setclr_inv)
|
||||
|
||||
#define GATE_TOP2(_id, _name, _parent, _shift) \
|
||||
GATE_MTK(_id, _name, _parent, &top2_cg_regs, \
|
||||
_shift, &mtk_clk_gate_ops_no_setclr)
|
||||
_shift, &mtk_clk_gate_ops_no_setclr_inv)
|
||||
|
||||
static const struct mtk_gate top_clk_gates[] = {
|
||||
GATE_TOP0(CLK_TOP_CONN_32K, "conn_32k", "clk32k", 10),
|
||||
@@ -696,6 +705,7 @@ static const struct mtk_gate ifr_clks[] = {
|
||||
GATE_IFR3(CLK_IFR_GCPU, "ifr_gcpu", "axi_sel", 8),
|
||||
GATE_IFR3(CLK_IFR_TRNG, "ifr_trng", "axi_sel", 9),
|
||||
GATE_IFR3(CLK_IFR_AUXADC, "ifr_auxadc", "clk26m", 10),
|
||||
GATE_IFR3(CLK_IFR_CPUM, "ifr_cpum", "clk26m", 11),
|
||||
GATE_IFR3(CLK_IFR_AUXADC_MD, "ifr_auxadc_md", "clk26m", 14),
|
||||
GATE_IFR3(CLK_IFR_AP_DMA, "ifr_ap_dma", "axi_sel", 18),
|
||||
GATE_IFR3(CLK_IFR_DEBUGSYS, "ifr_debugsys", "axi_sel", 24),
|
||||
@@ -717,6 +727,8 @@ static const struct mtk_gate ifr_clks[] = {
|
||||
GATE_IFR5(CLK_IFR_PWRAP_TMR, "ifr_pwrap_tmr", "clk26m", 12),
|
||||
GATE_IFR5(CLK_IFR_PWRAP_SPI, "ifr_pwrap_spi", "clk26m", 13),
|
||||
GATE_IFR5(CLK_IFR_PWRAP_SYS, "ifr_pwrap_sys", "clk26m", 14),
|
||||
GATE_MTK_FLAGS(CLK_IFR_MCU_PM_BK, "ifr_mcu_pm_bk", NULL, &ifr5_cg_regs,
|
||||
17, &mtk_clk_gate_ops_setclr, CLK_IGNORE_UNUSED),
|
||||
GATE_IFR5(CLK_IFR_IRRX_26M, "ifr_irrx_26m", "clk26m", 22),
|
||||
GATE_IFR5(CLK_IFR_IRRX_32K, "ifr_irrx_32k", "clk32k", 23),
|
||||
GATE_IFR5(CLK_IFR_I2C0_AXI, "ifr_i2c0_axi", "i2c_sel", 24),
|
||||
|
||||
@@ -164,7 +164,7 @@ void pxa3xx_clk_update_accr(u32 disable, u32 enable, u32 xclkcfg, u32 mask)
|
||||
accr &= ~disable;
|
||||
accr |= enable;
|
||||
|
||||
writel(accr, ACCR);
|
||||
writel(accr, clk_regs + ACCR);
|
||||
if (xclkcfg)
|
||||
__asm__("mcr p14, 0, %0, c6, c0, 0\n" : : "r"(xclkcfg));
|
||||
|
||||
|
||||
@@ -2124,6 +2124,7 @@ static int cs_dsp_load_coeff(struct cs_dsp *dsp, const struct firmware *firmware
|
||||
file, blocks, le32_to_cpu(blk->len),
|
||||
type, le32_to_cpu(blk->id));
|
||||
|
||||
region_name = cs_dsp_mem_region_name(type);
|
||||
mem = cs_dsp_find_region(dsp, type);
|
||||
if (!mem) {
|
||||
cs_dsp_err(dsp, "No base for region %x\n", type);
|
||||
@@ -2147,8 +2148,8 @@ static int cs_dsp_load_coeff(struct cs_dsp *dsp, const struct firmware *firmware
|
||||
reg = dsp->ops->region_to_reg(mem, reg);
|
||||
reg += offset;
|
||||
} else {
|
||||
cs_dsp_err(dsp, "No %x for algorithm %x\n",
|
||||
type, le32_to_cpu(blk->id));
|
||||
cs_dsp_err(dsp, "No %s for algorithm %x\n",
|
||||
region_name, le32_to_cpu(blk->id));
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
@@ -1615,6 +1615,7 @@ static const u16 amdgpu_unsupported_pciidlist[] = {
|
||||
0x5874,
|
||||
0x5940,
|
||||
0x5941,
|
||||
0x5b70,
|
||||
0x5b72,
|
||||
0x5b73,
|
||||
0x5b74,
|
||||
|
||||
@@ -140,7 +140,7 @@ void amdgpu_bo_placement_from_domain(struct amdgpu_bo *abo, u32 domain)
|
||||
|
||||
if (flags & AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED)
|
||||
places[c].lpfn = visible_pfn;
|
||||
else if (adev->gmc.real_vram_size != adev->gmc.visible_vram_size)
|
||||
else
|
||||
places[c].flags |= TTM_PL_FLAG_TOPDOWN;
|
||||
|
||||
if (flags & AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS)
|
||||
|
||||
@@ -3548,6 +3548,9 @@ static ssize_t amdgpu_psp_vbflash_read(struct file *filp, struct kobject *kobj,
|
||||
void *fw_pri_cpu_addr;
|
||||
int ret;
|
||||
|
||||
if (adev->psp.vbflash_image_size == 0)
|
||||
return -EINVAL;
|
||||
|
||||
dev_info(adev->dev, "VBIOS flash to PSP started");
|
||||
|
||||
ret = amdgpu_bo_create_kernel(adev, adev->psp.vbflash_image_size,
|
||||
@@ -3599,13 +3602,13 @@ static ssize_t amdgpu_psp_vbflash_status(struct device *dev,
|
||||
}
|
||||
|
||||
static const struct bin_attribute psp_vbflash_bin_attr = {
|
||||
.attr = {.name = "psp_vbflash", .mode = 0664},
|
||||
.attr = {.name = "psp_vbflash", .mode = 0660},
|
||||
.size = 0,
|
||||
.write = amdgpu_psp_vbflash_write,
|
||||
.read = amdgpu_psp_vbflash_read,
|
||||
};
|
||||
|
||||
static DEVICE_ATTR(psp_vbflash_status, 0444, amdgpu_psp_vbflash_status, NULL);
|
||||
static DEVICE_ATTR(psp_vbflash_status, 0440, amdgpu_psp_vbflash_status, NULL);
|
||||
|
||||
int amdgpu_psp_sysfs_init(struct amdgpu_device *adev)
|
||||
{
|
||||
|
||||
@@ -581,3 +581,21 @@ void amdgpu_ring_ib_end(struct amdgpu_ring *ring)
|
||||
if (ring->is_sw_ring)
|
||||
amdgpu_sw_ring_ib_end(ring);
|
||||
}
|
||||
|
||||
void amdgpu_ring_ib_on_emit_cntl(struct amdgpu_ring *ring)
|
||||
{
|
||||
if (ring->is_sw_ring)
|
||||
amdgpu_sw_ring_ib_mark_offset(ring, AMDGPU_MUX_OFFSET_TYPE_CONTROL);
|
||||
}
|
||||
|
||||
void amdgpu_ring_ib_on_emit_ce(struct amdgpu_ring *ring)
|
||||
{
|
||||
if (ring->is_sw_ring)
|
||||
amdgpu_sw_ring_ib_mark_offset(ring, AMDGPU_MUX_OFFSET_TYPE_CE);
|
||||
}
|
||||
|
||||
void amdgpu_ring_ib_on_emit_de(struct amdgpu_ring *ring)
|
||||
{
|
||||
if (ring->is_sw_ring)
|
||||
amdgpu_sw_ring_ib_mark_offset(ring, AMDGPU_MUX_OFFSET_TYPE_DE);
|
||||
}
|
||||
|
||||
@@ -227,6 +227,9 @@ struct amdgpu_ring_funcs {
|
||||
int (*preempt_ib)(struct amdgpu_ring *ring);
|
||||
void (*emit_mem_sync)(struct amdgpu_ring *ring);
|
||||
void (*emit_wave_limit)(struct amdgpu_ring *ring, bool enable);
|
||||
void (*patch_cntl)(struct amdgpu_ring *ring, unsigned offset);
|
||||
void (*patch_ce)(struct amdgpu_ring *ring, unsigned offset);
|
||||
void (*patch_de)(struct amdgpu_ring *ring, unsigned offset);
|
||||
};
|
||||
|
||||
struct amdgpu_ring {
|
||||
@@ -318,10 +321,16 @@ struct amdgpu_ring {
|
||||
#define amdgpu_ring_init_cond_exec(r) (r)->funcs->init_cond_exec((r))
|
||||
#define amdgpu_ring_patch_cond_exec(r,o) (r)->funcs->patch_cond_exec((r),(o))
|
||||
#define amdgpu_ring_preempt_ib(r) (r)->funcs->preempt_ib(r)
|
||||
#define amdgpu_ring_patch_cntl(r, o) ((r)->funcs->patch_cntl((r), (o)))
|
||||
#define amdgpu_ring_patch_ce(r, o) ((r)->funcs->patch_ce((r), (o)))
|
||||
#define amdgpu_ring_patch_de(r, o) ((r)->funcs->patch_de((r), (o)))
|
||||
|
||||
int amdgpu_ring_alloc(struct amdgpu_ring *ring, unsigned ndw);
|
||||
void amdgpu_ring_ib_begin(struct amdgpu_ring *ring);
|
||||
void amdgpu_ring_ib_end(struct amdgpu_ring *ring);
|
||||
void amdgpu_ring_ib_on_emit_cntl(struct amdgpu_ring *ring);
|
||||
void amdgpu_ring_ib_on_emit_ce(struct amdgpu_ring *ring);
|
||||
void amdgpu_ring_ib_on_emit_de(struct amdgpu_ring *ring);
|
||||
|
||||
void amdgpu_ring_insert_nop(struct amdgpu_ring *ring, uint32_t count);
|
||||
void amdgpu_ring_generic_pad_ib(struct amdgpu_ring *ring, struct amdgpu_ib *ib);
|
||||
|
||||
@@ -105,6 +105,16 @@ static void amdgpu_mux_resubmit_chunks(struct amdgpu_ring_mux *mux)
|
||||
amdgpu_fence_update_start_timestamp(e->ring,
|
||||
chunk->sync_seq,
|
||||
ktime_get());
|
||||
if (chunk->sync_seq ==
|
||||
le32_to_cpu(*(e->ring->fence_drv.cpu_addr + 2))) {
|
||||
if (chunk->cntl_offset <= e->ring->buf_mask)
|
||||
amdgpu_ring_patch_cntl(e->ring,
|
||||
chunk->cntl_offset);
|
||||
if (chunk->ce_offset <= e->ring->buf_mask)
|
||||
amdgpu_ring_patch_ce(e->ring, chunk->ce_offset);
|
||||
if (chunk->de_offset <= e->ring->buf_mask)
|
||||
amdgpu_ring_patch_de(e->ring, chunk->de_offset);
|
||||
}
|
||||
amdgpu_ring_mux_copy_pkt_from_sw_ring(mux, e->ring,
|
||||
chunk->start,
|
||||
chunk->end);
|
||||
@@ -407,6 +417,17 @@ void amdgpu_sw_ring_ib_end(struct amdgpu_ring *ring)
|
||||
amdgpu_ring_mux_end_ib(mux, ring);
|
||||
}
|
||||
|
||||
void amdgpu_sw_ring_ib_mark_offset(struct amdgpu_ring *ring, enum amdgpu_ring_mux_offset_type type)
|
||||
{
|
||||
struct amdgpu_device *adev = ring->adev;
|
||||
struct amdgpu_ring_mux *mux = &adev->gfx.muxer;
|
||||
unsigned offset;
|
||||
|
||||
offset = ring->wptr & ring->buf_mask;
|
||||
|
||||
amdgpu_ring_mux_ib_mark_offset(mux, ring, offset, type);
|
||||
}
|
||||
|
||||
void amdgpu_ring_mux_start_ib(struct amdgpu_ring_mux *mux, struct amdgpu_ring *ring)
|
||||
{
|
||||
struct amdgpu_mux_entry *e;
|
||||
@@ -429,6 +450,10 @@ void amdgpu_ring_mux_start_ib(struct amdgpu_ring_mux *mux, struct amdgpu_ring *r
|
||||
}
|
||||
|
||||
chunk->start = ring->wptr;
|
||||
/* the initialized value used to check if they are set by the ib submission*/
|
||||
chunk->cntl_offset = ring->buf_mask + 1;
|
||||
chunk->de_offset = ring->buf_mask + 1;
|
||||
chunk->ce_offset = ring->buf_mask + 1;
|
||||
list_add_tail(&chunk->entry, &e->list);
|
||||
}
|
||||
|
||||
@@ -454,6 +479,41 @@ static void scan_and_remove_signaled_chunk(struct amdgpu_ring_mux *mux, struct a
|
||||
}
|
||||
}
|
||||
|
||||
void amdgpu_ring_mux_ib_mark_offset(struct amdgpu_ring_mux *mux,
|
||||
struct amdgpu_ring *ring, u64 offset,
|
||||
enum amdgpu_ring_mux_offset_type type)
|
||||
{
|
||||
struct amdgpu_mux_entry *e;
|
||||
struct amdgpu_mux_chunk *chunk;
|
||||
|
||||
e = amdgpu_ring_mux_sw_entry(mux, ring);
|
||||
if (!e) {
|
||||
DRM_ERROR("cannot find entry!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
chunk = list_last_entry(&e->list, struct amdgpu_mux_chunk, entry);
|
||||
if (!chunk) {
|
||||
DRM_ERROR("cannot find chunk!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case AMDGPU_MUX_OFFSET_TYPE_CONTROL:
|
||||
chunk->cntl_offset = offset;
|
||||
break;
|
||||
case AMDGPU_MUX_OFFSET_TYPE_DE:
|
||||
chunk->de_offset = offset;
|
||||
break;
|
||||
case AMDGPU_MUX_OFFSET_TYPE_CE:
|
||||
chunk->ce_offset = offset;
|
||||
break;
|
||||
default:
|
||||
DRM_ERROR("invalid type (%d)\n", type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void amdgpu_ring_mux_end_ib(struct amdgpu_ring_mux *mux, struct amdgpu_ring *ring)
|
||||
{
|
||||
struct amdgpu_mux_entry *e;
|
||||
|
||||
@@ -50,6 +50,12 @@ struct amdgpu_mux_entry {
|
||||
struct list_head list;
|
||||
};
|
||||
|
||||
enum amdgpu_ring_mux_offset_type {
|
||||
AMDGPU_MUX_OFFSET_TYPE_CONTROL,
|
||||
AMDGPU_MUX_OFFSET_TYPE_DE,
|
||||
AMDGPU_MUX_OFFSET_TYPE_CE,
|
||||
};
|
||||
|
||||
struct amdgpu_ring_mux {
|
||||
struct amdgpu_ring *real_ring;
|
||||
|
||||
@@ -72,12 +78,18 @@ struct amdgpu_ring_mux {
|
||||
* @sync_seq: the fence seqno related with the saved IB.
|
||||
* @start:- start location on the software ring.
|
||||
* @end:- end location on the software ring.
|
||||
* @control_offset:- the PRE_RESUME bit position used for resubmission.
|
||||
* @de_offset:- the anchor in write_data for de meta of resubmission.
|
||||
* @ce_offset:- the anchor in write_data for ce meta of resubmission.
|
||||
*/
|
||||
struct amdgpu_mux_chunk {
|
||||
struct list_head entry;
|
||||
uint32_t sync_seq;
|
||||
u64 start;
|
||||
u64 end;
|
||||
u64 cntl_offset;
|
||||
u64 de_offset;
|
||||
u64 ce_offset;
|
||||
};
|
||||
|
||||
int amdgpu_ring_mux_init(struct amdgpu_ring_mux *mux, struct amdgpu_ring *ring,
|
||||
@@ -89,6 +101,8 @@ u64 amdgpu_ring_mux_get_wptr(struct amdgpu_ring_mux *mux, struct amdgpu_ring *ri
|
||||
u64 amdgpu_ring_mux_get_rptr(struct amdgpu_ring_mux *mux, struct amdgpu_ring *ring);
|
||||
void amdgpu_ring_mux_start_ib(struct amdgpu_ring_mux *mux, struct amdgpu_ring *ring);
|
||||
void amdgpu_ring_mux_end_ib(struct amdgpu_ring_mux *mux, struct amdgpu_ring *ring);
|
||||
void amdgpu_ring_mux_ib_mark_offset(struct amdgpu_ring_mux *mux, struct amdgpu_ring *ring,
|
||||
u64 offset, enum amdgpu_ring_mux_offset_type type);
|
||||
bool amdgpu_mcbp_handle_trailing_fence_irq(struct amdgpu_ring_mux *mux);
|
||||
|
||||
u64 amdgpu_sw_ring_get_rptr_gfx(struct amdgpu_ring *ring);
|
||||
@@ -97,6 +111,7 @@ void amdgpu_sw_ring_set_wptr_gfx(struct amdgpu_ring *ring);
|
||||
void amdgpu_sw_ring_insert_nop(struct amdgpu_ring *ring, uint32_t count);
|
||||
void amdgpu_sw_ring_ib_begin(struct amdgpu_ring *ring);
|
||||
void amdgpu_sw_ring_ib_end(struct amdgpu_ring *ring);
|
||||
void amdgpu_sw_ring_ib_mark_offset(struct amdgpu_ring *ring, enum amdgpu_ring_mux_offset_type type);
|
||||
const char *amdgpu_sw_ring_name(int idx);
|
||||
unsigned int amdgpu_sw_ring_priority(int idx);
|
||||
|
||||
|
||||
@@ -755,7 +755,7 @@ static void gfx_v9_0_set_rlc_funcs(struct amdgpu_device *adev);
|
||||
static int gfx_v9_0_get_cu_info(struct amdgpu_device *adev,
|
||||
struct amdgpu_cu_info *cu_info);
|
||||
static uint64_t gfx_v9_0_get_gpu_clock_counter(struct amdgpu_device *adev);
|
||||
static void gfx_v9_0_ring_emit_de_meta(struct amdgpu_ring *ring, bool resume);
|
||||
static void gfx_v9_0_ring_emit_de_meta(struct amdgpu_ring *ring, bool resume, bool usegds);
|
||||
static u64 gfx_v9_0_ring_get_rptr_compute(struct amdgpu_ring *ring);
|
||||
static void gfx_v9_0_query_ras_error_count(struct amdgpu_device *adev,
|
||||
void *ras_error_status);
|
||||
@@ -5127,7 +5127,8 @@ static void gfx_v9_0_ring_emit_ib_gfx(struct amdgpu_ring *ring,
|
||||
gfx_v9_0_ring_emit_de_meta(ring,
|
||||
(!amdgpu_sriov_vf(ring->adev) &&
|
||||
flags & AMDGPU_IB_PREEMPTED) ?
|
||||
true : false);
|
||||
true : false,
|
||||
job->gds_size > 0 && job->gds_base != 0);
|
||||
}
|
||||
|
||||
amdgpu_ring_write(ring, header);
|
||||
@@ -5138,9 +5139,83 @@ static void gfx_v9_0_ring_emit_ib_gfx(struct amdgpu_ring *ring,
|
||||
#endif
|
||||
lower_32_bits(ib->gpu_addr));
|
||||
amdgpu_ring_write(ring, upper_32_bits(ib->gpu_addr));
|
||||
amdgpu_ring_ib_on_emit_cntl(ring);
|
||||
amdgpu_ring_write(ring, control);
|
||||
}
|
||||
|
||||
static void gfx_v9_0_ring_patch_cntl(struct amdgpu_ring *ring,
|
||||
unsigned offset)
|
||||
{
|
||||
u32 control = ring->ring[offset];
|
||||
|
||||
control |= INDIRECT_BUFFER_PRE_RESUME(1);
|
||||
ring->ring[offset] = control;
|
||||
}
|
||||
|
||||
static void gfx_v9_0_ring_patch_ce_meta(struct amdgpu_ring *ring,
|
||||
unsigned offset)
|
||||
{
|
||||
struct amdgpu_device *adev = ring->adev;
|
||||
void *ce_payload_cpu_addr;
|
||||
uint64_t payload_offset, payload_size;
|
||||
|
||||
payload_size = sizeof(struct v9_ce_ib_state);
|
||||
|
||||
if (ring->is_mes_queue) {
|
||||
payload_offset = offsetof(struct amdgpu_mes_ctx_meta_data,
|
||||
gfx[0].gfx_meta_data) +
|
||||
offsetof(struct v9_gfx_meta_data, ce_payload);
|
||||
ce_payload_cpu_addr =
|
||||
amdgpu_mes_ctx_get_offs_cpu_addr(ring, payload_offset);
|
||||
} else {
|
||||
payload_offset = offsetof(struct v9_gfx_meta_data, ce_payload);
|
||||
ce_payload_cpu_addr = adev->virt.csa_cpu_addr + payload_offset;
|
||||
}
|
||||
|
||||
if (offset + (payload_size >> 2) <= ring->buf_mask + 1) {
|
||||
memcpy((void *)&ring->ring[offset], ce_payload_cpu_addr, payload_size);
|
||||
} else {
|
||||
memcpy((void *)&ring->ring[offset], ce_payload_cpu_addr,
|
||||
(ring->buf_mask + 1 - offset) << 2);
|
||||
payload_size -= (ring->buf_mask + 1 - offset) << 2;
|
||||
memcpy((void *)&ring->ring[0],
|
||||
ce_payload_cpu_addr + ((ring->buf_mask + 1 - offset) << 2),
|
||||
payload_size);
|
||||
}
|
||||
}
|
||||
|
||||
static void gfx_v9_0_ring_patch_de_meta(struct amdgpu_ring *ring,
|
||||
unsigned offset)
|
||||
{
|
||||
struct amdgpu_device *adev = ring->adev;
|
||||
void *de_payload_cpu_addr;
|
||||
uint64_t payload_offset, payload_size;
|
||||
|
||||
payload_size = sizeof(struct v9_de_ib_state);
|
||||
|
||||
if (ring->is_mes_queue) {
|
||||
payload_offset = offsetof(struct amdgpu_mes_ctx_meta_data,
|
||||
gfx[0].gfx_meta_data) +
|
||||
offsetof(struct v9_gfx_meta_data, de_payload);
|
||||
de_payload_cpu_addr =
|
||||
amdgpu_mes_ctx_get_offs_cpu_addr(ring, payload_offset);
|
||||
} else {
|
||||
payload_offset = offsetof(struct v9_gfx_meta_data, de_payload);
|
||||
de_payload_cpu_addr = adev->virt.csa_cpu_addr + payload_offset;
|
||||
}
|
||||
|
||||
if (offset + (payload_size >> 2) <= ring->buf_mask + 1) {
|
||||
memcpy((void *)&ring->ring[offset], de_payload_cpu_addr, payload_size);
|
||||
} else {
|
||||
memcpy((void *)&ring->ring[offset], de_payload_cpu_addr,
|
||||
(ring->buf_mask + 1 - offset) << 2);
|
||||
payload_size -= (ring->buf_mask + 1 - offset) << 2;
|
||||
memcpy((void *)&ring->ring[0],
|
||||
de_payload_cpu_addr + ((ring->buf_mask + 1 - offset) << 2),
|
||||
payload_size);
|
||||
}
|
||||
}
|
||||
|
||||
static void gfx_v9_0_ring_emit_ib_compute(struct amdgpu_ring *ring,
|
||||
struct amdgpu_job *job,
|
||||
struct amdgpu_ib *ib,
|
||||
@@ -5336,6 +5411,8 @@ static void gfx_v9_0_ring_emit_ce_meta(struct amdgpu_ring *ring, bool resume)
|
||||
amdgpu_ring_write(ring, lower_32_bits(ce_payload_gpu_addr));
|
||||
amdgpu_ring_write(ring, upper_32_bits(ce_payload_gpu_addr));
|
||||
|
||||
amdgpu_ring_ib_on_emit_ce(ring);
|
||||
|
||||
if (resume)
|
||||
amdgpu_ring_write_multiple(ring, ce_payload_cpu_addr,
|
||||
sizeof(ce_payload) >> 2);
|
||||
@@ -5369,10 +5446,6 @@ static int gfx_v9_0_ring_preempt_ib(struct amdgpu_ring *ring)
|
||||
amdgpu_ring_alloc(ring, 13);
|
||||
gfx_v9_0_ring_emit_fence(ring, ring->trail_fence_gpu_addr,
|
||||
ring->trail_seq, AMDGPU_FENCE_FLAG_EXEC | AMDGPU_FENCE_FLAG_INT);
|
||||
/*reset the CP_VMID_PREEMPT after trailing fence*/
|
||||
amdgpu_ring_emit_wreg(ring,
|
||||
SOC15_REG_OFFSET(GC, 0, mmCP_VMID_PREEMPT),
|
||||
0x0);
|
||||
|
||||
/* assert IB preemption, emit the trailing fence */
|
||||
kiq->pmf->kiq_unmap_queues(kiq_ring, ring, PREEMPT_QUEUES_NO_UNMAP,
|
||||
@@ -5395,6 +5468,10 @@ static int gfx_v9_0_ring_preempt_ib(struct amdgpu_ring *ring)
|
||||
DRM_WARN("ring %d timeout to preempt ib\n", ring->idx);
|
||||
}
|
||||
|
||||
/*reset the CP_VMID_PREEMPT after trailing fence*/
|
||||
amdgpu_ring_emit_wreg(ring,
|
||||
SOC15_REG_OFFSET(GC, 0, mmCP_VMID_PREEMPT),
|
||||
0x0);
|
||||
amdgpu_ring_commit(ring);
|
||||
|
||||
/* deassert preemption condition */
|
||||
@@ -5402,7 +5479,7 @@ static int gfx_v9_0_ring_preempt_ib(struct amdgpu_ring *ring)
|
||||
return r;
|
||||
}
|
||||
|
||||
static void gfx_v9_0_ring_emit_de_meta(struct amdgpu_ring *ring, bool resume)
|
||||
static void gfx_v9_0_ring_emit_de_meta(struct amdgpu_ring *ring, bool resume, bool usegds)
|
||||
{
|
||||
struct amdgpu_device *adev = ring->adev;
|
||||
struct v9_de_ib_state de_payload = {0};
|
||||
@@ -5433,8 +5510,10 @@ static void gfx_v9_0_ring_emit_de_meta(struct amdgpu_ring *ring, bool resume)
|
||||
PAGE_SIZE);
|
||||
}
|
||||
|
||||
de_payload.gds_backup_addrlo = lower_32_bits(gds_addr);
|
||||
de_payload.gds_backup_addrhi = upper_32_bits(gds_addr);
|
||||
if (usegds) {
|
||||
de_payload.gds_backup_addrlo = lower_32_bits(gds_addr);
|
||||
de_payload.gds_backup_addrhi = upper_32_bits(gds_addr);
|
||||
}
|
||||
|
||||
cnt = (sizeof(de_payload) >> 2) + 4 - 2;
|
||||
amdgpu_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, cnt));
|
||||
@@ -5445,6 +5524,7 @@ static void gfx_v9_0_ring_emit_de_meta(struct amdgpu_ring *ring, bool resume)
|
||||
amdgpu_ring_write(ring, lower_32_bits(de_payload_gpu_addr));
|
||||
amdgpu_ring_write(ring, upper_32_bits(de_payload_gpu_addr));
|
||||
|
||||
amdgpu_ring_ib_on_emit_de(ring);
|
||||
if (resume)
|
||||
amdgpu_ring_write_multiple(ring, de_payload_cpu_addr,
|
||||
sizeof(de_payload) >> 2);
|
||||
@@ -6855,6 +6935,9 @@ static const struct amdgpu_ring_funcs gfx_v9_0_sw_ring_funcs_gfx = {
|
||||
.emit_reg_write_reg_wait = gfx_v9_0_ring_emit_reg_write_reg_wait,
|
||||
.soft_recovery = gfx_v9_0_ring_soft_recovery,
|
||||
.emit_mem_sync = gfx_v9_0_emit_mem_sync,
|
||||
.patch_cntl = gfx_v9_0_ring_patch_cntl,
|
||||
.patch_de = gfx_v9_0_ring_patch_de_meta,
|
||||
.patch_ce = gfx_v9_0_ring_patch_ce_meta,
|
||||
};
|
||||
|
||||
static const struct amdgpu_ring_funcs gfx_v9_0_ring_funcs_compute = {
|
||||
|
||||
@@ -129,7 +129,11 @@ static int vcn_v4_0_sw_init(void *handle)
|
||||
if (adev->vcn.harvest_config & (1 << i))
|
||||
continue;
|
||||
|
||||
atomic_set(&adev->vcn.inst[i].sched_score, 0);
|
||||
/* Init instance 0 sched_score to 1, so it's scheduled after other instances */
|
||||
if (i == 0)
|
||||
atomic_set(&adev->vcn.inst[i].sched_score, 1);
|
||||
else
|
||||
atomic_set(&adev->vcn.inst[i].sched_score, 0);
|
||||
|
||||
/* VCN UNIFIED TRAP */
|
||||
r = amdgpu_irq_add_id(adev, amdgpu_ih_clientid_vcns[i],
|
||||
|
||||
@@ -7196,7 +7196,13 @@ static int amdgpu_dm_connector_get_modes(struct drm_connector *connector)
|
||||
drm_add_modes_noedid(connector, 1920, 1080);
|
||||
} else {
|
||||
amdgpu_dm_connector_ddc_get_modes(connector, edid);
|
||||
amdgpu_dm_connector_add_common_modes(encoder, connector);
|
||||
/* most eDP supports only timings from its edid,
|
||||
* usually only detailed timings are available
|
||||
* from eDP edid. timings which are not from edid
|
||||
* may damage eDP
|
||||
*/
|
||||
if (connector->connector_type != DRM_MODE_CONNECTOR_eDP)
|
||||
amdgpu_dm_connector_add_common_modes(encoder, connector);
|
||||
amdgpu_dm_connector_add_freesync_modes(connector, edid);
|
||||
}
|
||||
amdgpu_dm_fbc_init(connector);
|
||||
@@ -8198,6 +8204,12 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
|
||||
if (acrtc_state->abm_level != dm_old_crtc_state->abm_level)
|
||||
bundle->stream_update.abm_level = &acrtc_state->abm_level;
|
||||
|
||||
mutex_lock(&dm->dc_lock);
|
||||
if ((acrtc_state->update_type > UPDATE_TYPE_FAST) &&
|
||||
acrtc_state->stream->link->psr_settings.psr_allow_active)
|
||||
amdgpu_dm_psr_disable(acrtc_state->stream);
|
||||
mutex_unlock(&dm->dc_lock);
|
||||
|
||||
/*
|
||||
* If FreeSync state on the stream has changed then we need to
|
||||
* re-adjust the min/max bounds now that DC doesn't handle this
|
||||
@@ -8211,10 +8223,6 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
|
||||
spin_unlock_irqrestore(&pcrtc->dev->event_lock, flags);
|
||||
}
|
||||
mutex_lock(&dm->dc_lock);
|
||||
if ((acrtc_state->update_type > UPDATE_TYPE_FAST) &&
|
||||
acrtc_state->stream->link->psr_settings.psr_allow_active)
|
||||
amdgpu_dm_psr_disable(acrtc_state->stream);
|
||||
|
||||
update_planes_and_stream_adapter(dm->dc,
|
||||
acrtc_state->update_type,
|
||||
planes_count,
|
||||
|
||||
@@ -980,6 +980,11 @@ static bool detect_link_and_local_sink(struct dc_link *link,
|
||||
(link->dpcd_caps.dongle_type !=
|
||||
DISPLAY_DONGLE_DP_HDMI_CONVERTER))
|
||||
converter_disable_audio = true;
|
||||
|
||||
/* limited link rate to HBR3 for DPIA until we implement USB4 V2 */
|
||||
if (link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA &&
|
||||
link->reported_link_cap.link_rate > LINK_RATE_HIGH3)
|
||||
link->reported_link_cap.link_rate = LINK_RATE_HIGH3;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -1696,10 +1696,39 @@ static int smu_v13_0_0_set_power_profile_mode(struct smu_context *smu,
|
||||
}
|
||||
}
|
||||
|
||||
/* conv PP_SMC_POWER_PROFILE* to WORKLOAD_PPLIB_*_BIT */
|
||||
workload_type = smu_cmn_to_asic_specific_index(smu,
|
||||
if (smu->power_profile_mode == PP_SMC_POWER_PROFILE_COMPUTE &&
|
||||
(((smu->adev->pdev->device == 0x744C) && (smu->adev->pdev->revision == 0xC8)) ||
|
||||
((smu->adev->pdev->device == 0x744C) && (smu->adev->pdev->revision == 0xCC)))) {
|
||||
ret = smu_cmn_update_table(smu,
|
||||
SMU_TABLE_ACTIVITY_MONITOR_COEFF,
|
||||
WORKLOAD_PPLIB_COMPUTE_BIT,
|
||||
(void *)(&activity_monitor_external),
|
||||
false);
|
||||
if (ret) {
|
||||
dev_err(smu->adev->dev, "[%s] Failed to get activity monitor!", __func__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = smu_cmn_update_table(smu,
|
||||
SMU_TABLE_ACTIVITY_MONITOR_COEFF,
|
||||
WORKLOAD_PPLIB_CUSTOM_BIT,
|
||||
(void *)(&activity_monitor_external),
|
||||
true);
|
||||
if (ret) {
|
||||
dev_err(smu->adev->dev, "[%s] Failed to set activity monitor!", __func__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
workload_type = smu_cmn_to_asic_specific_index(smu,
|
||||
CMN2ASIC_MAPPING_WORKLOAD,
|
||||
PP_SMC_POWER_PROFILE_CUSTOM);
|
||||
} else {
|
||||
/* conv PP_SMC_POWER_PROFILE* to WORKLOAD_PPLIB_*_BIT */
|
||||
workload_type = smu_cmn_to_asic_specific_index(smu,
|
||||
CMN2ASIC_MAPPING_WORKLOAD,
|
||||
smu->power_profile_mode);
|
||||
}
|
||||
|
||||
if (workload_type < 0)
|
||||
return -EINVAL;
|
||||
|
||||
|
||||
@@ -298,6 +298,10 @@ static void ti_sn_bridge_set_refclk_freq(struct ti_sn65dsi86 *pdata)
|
||||
if (refclk_lut[i] == refclk_rate)
|
||||
break;
|
||||
|
||||
/* avoid buffer overflow and "1" is the default rate in the datasheet. */
|
||||
if (i >= refclk_lut_size)
|
||||
i = 1;
|
||||
|
||||
regmap_update_bits(pdata->regmap, SN_DPPLL_SRC_REG, REFCLK_FREQ_MASK,
|
||||
REFCLK_FREQ(i));
|
||||
|
||||
|
||||
@@ -220,6 +220,9 @@ static void nouveau_dsm_pci_probe(struct pci_dev *pdev, acpi_handle *dhandle_out
|
||||
int optimus_funcs;
|
||||
struct pci_dev *parent_pdev;
|
||||
|
||||
if (pdev->vendor != PCI_VENDOR_ID_NVIDIA)
|
||||
return;
|
||||
|
||||
*has_pr3 = false;
|
||||
parent_pdev = pci_upstream_bridge(pdev);
|
||||
if (parent_pdev) {
|
||||
|
||||
@@ -730,7 +730,8 @@ out:
|
||||
#endif
|
||||
|
||||
nouveau_connector_set_edid(nv_connector, edid);
|
||||
nouveau_connector_set_encoder(connector, nv_encoder);
|
||||
if (nv_encoder)
|
||||
nouveau_connector_set_encoder(connector, nv_encoder);
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -966,7 +967,7 @@ nouveau_connector_get_modes(struct drm_connector *connector)
|
||||
/* Determine display colour depth for everything except LVDS now,
|
||||
* DP requires this before mode_valid() is called.
|
||||
*/
|
||||
if (connector->connector_type != DRM_MODE_CONNECTOR_LVDS)
|
||||
if (connector->connector_type != DRM_MODE_CONNECTOR_LVDS && nv_connector->native_mode)
|
||||
nouveau_connector_detect_depth(connector);
|
||||
|
||||
/* Find the native mode if this is a digital panel, if we didn't
|
||||
@@ -987,7 +988,7 @@ nouveau_connector_get_modes(struct drm_connector *connector)
|
||||
* "native" mode as some VBIOS tables require us to use the
|
||||
* pixel clock as part of the lookup...
|
||||
*/
|
||||
if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS)
|
||||
if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS && nv_connector->native_mode)
|
||||
nouveau_connector_detect_depth(connector);
|
||||
|
||||
if (nv_encoder->dcb->type == DCB_OUTPUT_TV)
|
||||
|
||||
@@ -137,10 +137,16 @@ nouveau_name(struct drm_device *dev)
|
||||
static inline bool
|
||||
nouveau_cli_work_ready(struct dma_fence *fence)
|
||||
{
|
||||
if (!dma_fence_is_signaled(fence))
|
||||
return false;
|
||||
dma_fence_put(fence);
|
||||
return true;
|
||||
bool ret = true;
|
||||
|
||||
spin_lock_irq(fence->lock);
|
||||
if (!dma_fence_is_signaled_locked(fence))
|
||||
ret = false;
|
||||
spin_unlock_irq(fence->lock);
|
||||
|
||||
if (ret == true)
|
||||
dma_fence_put(fence);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -307,6 +307,7 @@ static void radeon_fbdev_client_unregister(struct drm_client_dev *client)
|
||||
|
||||
if (fb_helper->info) {
|
||||
vga_switcheroo_client_fb_set(rdev->pdev, NULL);
|
||||
drm_helper_force_disable_all(dev);
|
||||
drm_fb_helper_unregister_info(fb_helper);
|
||||
} else {
|
||||
drm_client_release(&fb_helper->client);
|
||||
|
||||
@@ -3295,7 +3295,7 @@ static int cma_resolve_iboe_route(struct rdma_id_private *id_priv)
|
||||
route->path_rec->traffic_class = tos;
|
||||
route->path_rec->mtu = iboe_get_mtu(ndev->mtu);
|
||||
route->path_rec->rate_selector = IB_SA_EQ;
|
||||
route->path_rec->rate = iboe_get_rate(ndev);
|
||||
route->path_rec->rate = IB_RATE_PORT_CURRENT;
|
||||
dev_put(ndev);
|
||||
route->path_rec->packet_life_time_selector = IB_SA_EQ;
|
||||
/* In case ACK timeout is set, use this value to calculate
|
||||
@@ -4964,7 +4964,7 @@ static int cma_iboe_join_multicast(struct rdma_id_private *id_priv,
|
||||
if (!ndev)
|
||||
return -ENODEV;
|
||||
|
||||
ib.rec.rate = iboe_get_rate(ndev);
|
||||
ib.rec.rate = IB_RATE_PORT_CURRENT;
|
||||
ib.rec.hop_limit = 1;
|
||||
ib.rec.mtu = iboe_get_mtu(ndev->mtu);
|
||||
|
||||
|
||||
@@ -1850,8 +1850,13 @@ static int modify_qp(struct uverbs_attr_bundle *attrs,
|
||||
attr->path_mtu = cmd->base.path_mtu;
|
||||
if (cmd->base.attr_mask & IB_QP_PATH_MIG_STATE)
|
||||
attr->path_mig_state = cmd->base.path_mig_state;
|
||||
if (cmd->base.attr_mask & IB_QP_QKEY)
|
||||
if (cmd->base.attr_mask & IB_QP_QKEY) {
|
||||
if (cmd->base.qkey & IB_QP_SET_QKEY && !capable(CAP_NET_RAW)) {
|
||||
ret = -EPERM;
|
||||
goto release_qp;
|
||||
}
|
||||
attr->qkey = cmd->base.qkey;
|
||||
}
|
||||
if (cmd->base.attr_mask & IB_QP_RQ_PSN)
|
||||
attr->rq_psn = cmd->base.rq_psn;
|
||||
if (cmd->base.attr_mask & IB_QP_SQ_PSN)
|
||||
|
||||
@@ -222,8 +222,12 @@ static ssize_t ib_uverbs_event_read(struct ib_uverbs_event_queue *ev_queue,
|
||||
spin_lock_irq(&ev_queue->lock);
|
||||
|
||||
while (list_empty(&ev_queue->event_list)) {
|
||||
spin_unlock_irq(&ev_queue->lock);
|
||||
if (ev_queue->is_closed) {
|
||||
spin_unlock_irq(&ev_queue->lock);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
spin_unlock_irq(&ev_queue->lock);
|
||||
if (filp->f_flags & O_NONBLOCK)
|
||||
return -EAGAIN;
|
||||
|
||||
@@ -233,12 +237,6 @@ static ssize_t ib_uverbs_event_read(struct ib_uverbs_event_queue *ev_queue,
|
||||
return -ERESTARTSYS;
|
||||
|
||||
spin_lock_irq(&ev_queue->lock);
|
||||
|
||||
/* If device was disassociated and no event exists set an error */
|
||||
if (list_empty(&ev_queue->event_list) && ev_queue->is_closed) {
|
||||
spin_unlock_irq(&ev_queue->lock);
|
||||
return -EIO;
|
||||
}
|
||||
}
|
||||
|
||||
event = list_entry(ev_queue->event_list.next, struct ib_uverbs_event, list);
|
||||
|
||||
@@ -135,8 +135,6 @@ struct bnxt_re_dev {
|
||||
|
||||
struct delayed_work worker;
|
||||
u8 cur_prio_map;
|
||||
u16 active_speed;
|
||||
u8 active_width;
|
||||
|
||||
/* FP Notification Queue (CQ & SRQ) */
|
||||
struct tasklet_struct nq_task;
|
||||
|
||||
@@ -199,6 +199,7 @@ int bnxt_re_query_port(struct ib_device *ibdev, u32 port_num,
|
||||
{
|
||||
struct bnxt_re_dev *rdev = to_bnxt_re_dev(ibdev, ibdev);
|
||||
struct bnxt_qplib_dev_attr *dev_attr = &rdev->dev_attr;
|
||||
int rc;
|
||||
|
||||
memset(port_attr, 0, sizeof(*port_attr));
|
||||
|
||||
@@ -228,10 +229,10 @@ int bnxt_re_query_port(struct ib_device *ibdev, u32 port_num,
|
||||
port_attr->sm_sl = 0;
|
||||
port_attr->subnet_timeout = 0;
|
||||
port_attr->init_type_reply = 0;
|
||||
port_attr->active_speed = rdev->active_speed;
|
||||
port_attr->active_width = rdev->active_width;
|
||||
rc = ib_get_eth_speed(&rdev->ibdev, port_num, &port_attr->active_speed,
|
||||
&port_attr->active_width);
|
||||
|
||||
return 0;
|
||||
return rc;
|
||||
}
|
||||
|
||||
int bnxt_re_get_port_immutable(struct ib_device *ibdev, u32 port_num,
|
||||
|
||||
@@ -1077,8 +1077,6 @@ static int bnxt_re_ib_init(struct bnxt_re_dev *rdev)
|
||||
return rc;
|
||||
}
|
||||
dev_info(rdev_to_dev(rdev), "Device registered with IB successfully");
|
||||
ib_get_eth_speed(&rdev->ibdev, 1, &rdev->active_speed,
|
||||
&rdev->active_width);
|
||||
set_bit(BNXT_RE_FLAG_ISSUE_ROCE_STATS, &rdev->flags);
|
||||
|
||||
event = netif_running(rdev->netdev) && netif_carrier_ok(rdev->netdev) ?
|
||||
|
||||
@@ -209,7 +209,8 @@ static const struct mlx5_ib_counters *get_counters(struct mlx5_ib_dev *dev,
|
||||
!vport_qcounters_supported(dev)) || !port_num)
|
||||
return &dev->port[0].cnts;
|
||||
|
||||
return &dev->port[port_num - 1].cnts;
|
||||
return is_mdev_switchdev_mode(dev->mdev) ?
|
||||
&dev->port[1].cnts : &dev->port[port_num - 1].cnts;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -262,7 +263,7 @@ static struct rdma_hw_stats *
|
||||
mlx5_ib_alloc_hw_port_stats(struct ib_device *ibdev, u32 port_num)
|
||||
{
|
||||
struct mlx5_ib_dev *dev = to_mdev(ibdev);
|
||||
const struct mlx5_ib_counters *cnts = &dev->port[port_num - 1].cnts;
|
||||
const struct mlx5_ib_counters *cnts = get_counters(dev, port_num);
|
||||
|
||||
return do_alloc_stats(cnts);
|
||||
}
|
||||
@@ -329,6 +330,7 @@ static int mlx5_ib_query_q_counters_vport(struct mlx5_ib_dev *dev,
|
||||
{
|
||||
u32 out[MLX5_ST_SZ_DW(query_q_counter_out)] = {};
|
||||
u32 in[MLX5_ST_SZ_DW(query_q_counter_in)] = {};
|
||||
struct mlx5_core_dev *mdev;
|
||||
__be32 val;
|
||||
int ret, i;
|
||||
|
||||
@@ -336,12 +338,16 @@ static int mlx5_ib_query_q_counters_vport(struct mlx5_ib_dev *dev,
|
||||
dev->port[port_num].rep->vport == MLX5_VPORT_UPLINK)
|
||||
return 0;
|
||||
|
||||
mdev = mlx5_eswitch_get_core_dev(dev->port[port_num].rep->esw);
|
||||
if (!mdev)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
MLX5_SET(query_q_counter_in, in, opcode, MLX5_CMD_OP_QUERY_Q_COUNTER);
|
||||
MLX5_SET(query_q_counter_in, in, other_vport, 1);
|
||||
MLX5_SET(query_q_counter_in, in, vport_number,
|
||||
dev->port[port_num].rep->vport);
|
||||
MLX5_SET(query_q_counter_in, in, aggregate, 1);
|
||||
ret = mlx5_cmd_exec_inout(dev->mdev, query_q_counter, in, out);
|
||||
ret = mlx5_cmd_exec_inout(mdev, query_q_counter, in, out);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@@ -575,43 +581,53 @@ static void mlx5_ib_fill_counters(struct mlx5_ib_dev *dev,
|
||||
bool is_vport = is_mdev_switchdev_mode(dev->mdev) &&
|
||||
port_num != MLX5_VPORT_PF;
|
||||
const struct mlx5_ib_counter *names;
|
||||
int j = 0, i;
|
||||
int j = 0, i, size;
|
||||
|
||||
names = is_vport ? vport_basic_q_cnts : basic_q_cnts;
|
||||
for (i = 0; i < ARRAY_SIZE(basic_q_cnts); i++, j++) {
|
||||
size = is_vport ? ARRAY_SIZE(vport_basic_q_cnts) :
|
||||
ARRAY_SIZE(basic_q_cnts);
|
||||
for (i = 0; i < size; i++, j++) {
|
||||
descs[j].name = names[i].name;
|
||||
offsets[j] = basic_q_cnts[i].offset;
|
||||
offsets[j] = names[i].offset;
|
||||
}
|
||||
|
||||
names = is_vport ? vport_out_of_seq_q_cnts : out_of_seq_q_cnts;
|
||||
size = is_vport ? ARRAY_SIZE(vport_out_of_seq_q_cnts) :
|
||||
ARRAY_SIZE(out_of_seq_q_cnts);
|
||||
if (MLX5_CAP_GEN(dev->mdev, out_of_seq_cnt)) {
|
||||
for (i = 0; i < ARRAY_SIZE(out_of_seq_q_cnts); i++, j++) {
|
||||
for (i = 0; i < size; i++, j++) {
|
||||
descs[j].name = names[i].name;
|
||||
offsets[j] = out_of_seq_q_cnts[i].offset;
|
||||
offsets[j] = names[i].offset;
|
||||
}
|
||||
}
|
||||
|
||||
names = is_vport ? vport_retrans_q_cnts : retrans_q_cnts;
|
||||
size = is_vport ? ARRAY_SIZE(vport_retrans_q_cnts) :
|
||||
ARRAY_SIZE(retrans_q_cnts);
|
||||
if (MLX5_CAP_GEN(dev->mdev, retransmission_q_counters)) {
|
||||
for (i = 0; i < ARRAY_SIZE(retrans_q_cnts); i++, j++) {
|
||||
for (i = 0; i < size; i++, j++) {
|
||||
descs[j].name = names[i].name;
|
||||
offsets[j] = retrans_q_cnts[i].offset;
|
||||
offsets[j] = names[i].offset;
|
||||
}
|
||||
}
|
||||
|
||||
names = is_vport ? vport_extended_err_cnts : extended_err_cnts;
|
||||
size = is_vport ? ARRAY_SIZE(vport_extended_err_cnts) :
|
||||
ARRAY_SIZE(extended_err_cnts);
|
||||
if (MLX5_CAP_GEN(dev->mdev, enhanced_error_q_counters)) {
|
||||
for (i = 0; i < ARRAY_SIZE(extended_err_cnts); i++, j++) {
|
||||
for (i = 0; i < size; i++, j++) {
|
||||
descs[j].name = names[i].name;
|
||||
offsets[j] = extended_err_cnts[i].offset;
|
||||
offsets[j] = names[i].offset;
|
||||
}
|
||||
}
|
||||
|
||||
names = is_vport ? vport_roce_accl_cnts : roce_accl_cnts;
|
||||
size = is_vport ? ARRAY_SIZE(vport_roce_accl_cnts) :
|
||||
ARRAY_SIZE(roce_accl_cnts);
|
||||
if (MLX5_CAP_GEN(dev->mdev, roce_accl)) {
|
||||
for (i = 0; i < ARRAY_SIZE(roce_accl_cnts); i++, j++) {
|
||||
for (i = 0; i < size; i++, j++) {
|
||||
descs[j].name = names[i].name;
|
||||
offsets[j] = roce_accl_cnts[i].offset;
|
||||
offsets[j] = names[i].offset;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -661,25 +677,37 @@ static void mlx5_ib_fill_counters(struct mlx5_ib_dev *dev,
|
||||
static int __mlx5_ib_alloc_counters(struct mlx5_ib_dev *dev,
|
||||
struct mlx5_ib_counters *cnts, u32 port_num)
|
||||
{
|
||||
u32 num_counters, num_op_counters = 0;
|
||||
bool is_vport = is_mdev_switchdev_mode(dev->mdev) &&
|
||||
port_num != MLX5_VPORT_PF;
|
||||
u32 num_counters, num_op_counters = 0, size;
|
||||
|
||||
num_counters = ARRAY_SIZE(basic_q_cnts);
|
||||
size = is_vport ? ARRAY_SIZE(vport_basic_q_cnts) :
|
||||
ARRAY_SIZE(basic_q_cnts);
|
||||
num_counters = size;
|
||||
|
||||
size = is_vport ? ARRAY_SIZE(vport_out_of_seq_q_cnts) :
|
||||
ARRAY_SIZE(out_of_seq_q_cnts);
|
||||
if (MLX5_CAP_GEN(dev->mdev, out_of_seq_cnt))
|
||||
num_counters += ARRAY_SIZE(out_of_seq_q_cnts);
|
||||
num_counters += size;
|
||||
|
||||
size = is_vport ? ARRAY_SIZE(vport_retrans_q_cnts) :
|
||||
ARRAY_SIZE(retrans_q_cnts);
|
||||
if (MLX5_CAP_GEN(dev->mdev, retransmission_q_counters))
|
||||
num_counters += ARRAY_SIZE(retrans_q_cnts);
|
||||
num_counters += size;
|
||||
|
||||
size = is_vport ? ARRAY_SIZE(vport_extended_err_cnts) :
|
||||
ARRAY_SIZE(extended_err_cnts);
|
||||
if (MLX5_CAP_GEN(dev->mdev, enhanced_error_q_counters))
|
||||
num_counters += ARRAY_SIZE(extended_err_cnts);
|
||||
num_counters += size;
|
||||
|
||||
size = is_vport ? ARRAY_SIZE(vport_roce_accl_cnts) :
|
||||
ARRAY_SIZE(roce_accl_cnts);
|
||||
if (MLX5_CAP_GEN(dev->mdev, roce_accl))
|
||||
num_counters += ARRAY_SIZE(roce_accl_cnts);
|
||||
num_counters += size;
|
||||
|
||||
cnts->num_q_counters = num_counters;
|
||||
|
||||
if (is_mdev_switchdev_mode(dev->mdev) && port_num != MLX5_VPORT_PF)
|
||||
if (is_vport)
|
||||
goto skip_non_qcounters;
|
||||
|
||||
if (MLX5_CAP_GEN(dev->mdev, cc_query_allowed)) {
|
||||
@@ -725,11 +753,11 @@ err:
|
||||
static void mlx5_ib_dealloc_counters(struct mlx5_ib_dev *dev)
|
||||
{
|
||||
u32 in[MLX5_ST_SZ_DW(dealloc_q_counter_in)] = {};
|
||||
int num_cnt_ports;
|
||||
int num_cnt_ports = dev->num_ports;
|
||||
int i, j;
|
||||
|
||||
num_cnt_ports = (!is_mdev_switchdev_mode(dev->mdev) ||
|
||||
vport_qcounters_supported(dev)) ? dev->num_ports : 1;
|
||||
if (is_mdev_switchdev_mode(dev->mdev))
|
||||
num_cnt_ports = min(2, num_cnt_ports);
|
||||
|
||||
MLX5_SET(dealloc_q_counter_in, in, opcode,
|
||||
MLX5_CMD_OP_DEALLOC_Q_COUNTER);
|
||||
@@ -761,15 +789,22 @@ static int mlx5_ib_alloc_counters(struct mlx5_ib_dev *dev)
|
||||
{
|
||||
u32 out[MLX5_ST_SZ_DW(alloc_q_counter_out)] = {};
|
||||
u32 in[MLX5_ST_SZ_DW(alloc_q_counter_in)] = {};
|
||||
int num_cnt_ports;
|
||||
int num_cnt_ports = dev->num_ports;
|
||||
int err = 0;
|
||||
int i;
|
||||
bool is_shared;
|
||||
|
||||
MLX5_SET(alloc_q_counter_in, in, opcode, MLX5_CMD_OP_ALLOC_Q_COUNTER);
|
||||
is_shared = MLX5_CAP_GEN(dev->mdev, log_max_uctx) != 0;
|
||||
num_cnt_ports = (!is_mdev_switchdev_mode(dev->mdev) ||
|
||||
vport_qcounters_supported(dev)) ? dev->num_ports : 1;
|
||||
|
||||
/*
|
||||
* In switchdev we need to allocate two ports, one that is used for
|
||||
* the device Q_counters and it is essentially the real Q_counters of
|
||||
* this device, while the other is used as a helper for PF to be able to
|
||||
* query all other vports.
|
||||
*/
|
||||
if (is_mdev_switchdev_mode(dev->mdev))
|
||||
num_cnt_ports = min(2, num_cnt_ports);
|
||||
|
||||
for (i = 0; i < num_cnt_ports; i++) {
|
||||
err = __mlx5_ib_alloc_counters(dev, &dev->port[i].cnts, i);
|
||||
|
||||
@@ -695,8 +695,6 @@ static struct mlx5_ib_flow_prio *_get_prio(struct mlx5_ib_dev *dev,
|
||||
struct mlx5_flow_table_attr ft_attr = {};
|
||||
struct mlx5_flow_table *ft;
|
||||
|
||||
if (mlx5_ib_shared_ft_allowed(&dev->ib_dev))
|
||||
ft_attr.uid = MLX5_SHARED_RESOURCE_UID;
|
||||
ft_attr.prio = priority;
|
||||
ft_attr.max_fte = num_entries;
|
||||
ft_attr.flags = flags;
|
||||
@@ -2025,6 +2023,237 @@ static int flow_matcher_cleanup(struct ib_uobject *uobject,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int steering_anchor_create_ft(struct mlx5_ib_dev *dev,
|
||||
struct mlx5_ib_flow_prio *ft_prio,
|
||||
enum mlx5_flow_namespace_type ns_type)
|
||||
{
|
||||
struct mlx5_flow_table_attr ft_attr = {};
|
||||
struct mlx5_flow_namespace *ns;
|
||||
struct mlx5_flow_table *ft;
|
||||
|
||||
if (ft_prio->anchor.ft)
|
||||
return 0;
|
||||
|
||||
ns = mlx5_get_flow_namespace(dev->mdev, ns_type);
|
||||
if (!ns)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
ft_attr.flags = MLX5_FLOW_TABLE_UNMANAGED;
|
||||
ft_attr.uid = MLX5_SHARED_RESOURCE_UID;
|
||||
ft_attr.prio = 0;
|
||||
ft_attr.max_fte = 2;
|
||||
ft_attr.level = 1;
|
||||
|
||||
ft = mlx5_create_flow_table(ns, &ft_attr);
|
||||
if (IS_ERR(ft))
|
||||
return PTR_ERR(ft);
|
||||
|
||||
ft_prio->anchor.ft = ft;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void steering_anchor_destroy_ft(struct mlx5_ib_flow_prio *ft_prio)
|
||||
{
|
||||
if (ft_prio->anchor.ft) {
|
||||
mlx5_destroy_flow_table(ft_prio->anchor.ft);
|
||||
ft_prio->anchor.ft = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
steering_anchor_create_fg_drop(struct mlx5_ib_flow_prio *ft_prio)
|
||||
{
|
||||
int inlen = MLX5_ST_SZ_BYTES(create_flow_group_in);
|
||||
struct mlx5_flow_group *fg;
|
||||
void *flow_group_in;
|
||||
int err = 0;
|
||||
|
||||
if (ft_prio->anchor.fg_drop)
|
||||
return 0;
|
||||
|
||||
flow_group_in = kvzalloc(inlen, GFP_KERNEL);
|
||||
if (!flow_group_in)
|
||||
return -ENOMEM;
|
||||
|
||||
MLX5_SET(create_flow_group_in, flow_group_in, start_flow_index, 1);
|
||||
MLX5_SET(create_flow_group_in, flow_group_in, end_flow_index, 1);
|
||||
|
||||
fg = mlx5_create_flow_group(ft_prio->anchor.ft, flow_group_in);
|
||||
if (IS_ERR(fg)) {
|
||||
err = PTR_ERR(fg);
|
||||
goto out;
|
||||
}
|
||||
|
||||
ft_prio->anchor.fg_drop = fg;
|
||||
|
||||
out:
|
||||
kvfree(flow_group_in);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static void
|
||||
steering_anchor_destroy_fg_drop(struct mlx5_ib_flow_prio *ft_prio)
|
||||
{
|
||||
if (ft_prio->anchor.fg_drop) {
|
||||
mlx5_destroy_flow_group(ft_prio->anchor.fg_drop);
|
||||
ft_prio->anchor.fg_drop = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
steering_anchor_create_fg_goto_table(struct mlx5_ib_flow_prio *ft_prio)
|
||||
{
|
||||
int inlen = MLX5_ST_SZ_BYTES(create_flow_group_in);
|
||||
struct mlx5_flow_group *fg;
|
||||
void *flow_group_in;
|
||||
int err = 0;
|
||||
|
||||
if (ft_prio->anchor.fg_goto_table)
|
||||
return 0;
|
||||
|
||||
flow_group_in = kvzalloc(inlen, GFP_KERNEL);
|
||||
if (!flow_group_in)
|
||||
return -ENOMEM;
|
||||
|
||||
fg = mlx5_create_flow_group(ft_prio->anchor.ft, flow_group_in);
|
||||
if (IS_ERR(fg)) {
|
||||
err = PTR_ERR(fg);
|
||||
goto out;
|
||||
}
|
||||
ft_prio->anchor.fg_goto_table = fg;
|
||||
|
||||
out:
|
||||
kvfree(flow_group_in);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static void
|
||||
steering_anchor_destroy_fg_goto_table(struct mlx5_ib_flow_prio *ft_prio)
|
||||
{
|
||||
if (ft_prio->anchor.fg_goto_table) {
|
||||
mlx5_destroy_flow_group(ft_prio->anchor.fg_goto_table);
|
||||
ft_prio->anchor.fg_goto_table = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
steering_anchor_create_rule_drop(struct mlx5_ib_flow_prio *ft_prio)
|
||||
{
|
||||
struct mlx5_flow_act flow_act = {};
|
||||
struct mlx5_flow_handle *handle;
|
||||
|
||||
if (ft_prio->anchor.rule_drop)
|
||||
return 0;
|
||||
|
||||
flow_act.fg = ft_prio->anchor.fg_drop;
|
||||
flow_act.action = MLX5_FLOW_CONTEXT_ACTION_DROP;
|
||||
|
||||
handle = mlx5_add_flow_rules(ft_prio->anchor.ft, NULL, &flow_act,
|
||||
NULL, 0);
|
||||
if (IS_ERR(handle))
|
||||
return PTR_ERR(handle);
|
||||
|
||||
ft_prio->anchor.rule_drop = handle;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void steering_anchor_destroy_rule_drop(struct mlx5_ib_flow_prio *ft_prio)
|
||||
{
|
||||
if (ft_prio->anchor.rule_drop) {
|
||||
mlx5_del_flow_rules(ft_prio->anchor.rule_drop);
|
||||
ft_prio->anchor.rule_drop = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
steering_anchor_create_rule_goto_table(struct mlx5_ib_flow_prio *ft_prio)
|
||||
{
|
||||
struct mlx5_flow_destination dest = {};
|
||||
struct mlx5_flow_act flow_act = {};
|
||||
struct mlx5_flow_handle *handle;
|
||||
|
||||
if (ft_prio->anchor.rule_goto_table)
|
||||
return 0;
|
||||
|
||||
flow_act.action = MLX5_FLOW_CONTEXT_ACTION_FWD_DEST;
|
||||
flow_act.flags |= FLOW_ACT_IGNORE_FLOW_LEVEL;
|
||||
flow_act.fg = ft_prio->anchor.fg_goto_table;
|
||||
|
||||
dest.type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
|
||||
dest.ft = ft_prio->flow_table;
|
||||
|
||||
handle = mlx5_add_flow_rules(ft_prio->anchor.ft, NULL, &flow_act,
|
||||
&dest, 1);
|
||||
if (IS_ERR(handle))
|
||||
return PTR_ERR(handle);
|
||||
|
||||
ft_prio->anchor.rule_goto_table = handle;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
steering_anchor_destroy_rule_goto_table(struct mlx5_ib_flow_prio *ft_prio)
|
||||
{
|
||||
if (ft_prio->anchor.rule_goto_table) {
|
||||
mlx5_del_flow_rules(ft_prio->anchor.rule_goto_table);
|
||||
ft_prio->anchor.rule_goto_table = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static int steering_anchor_create_res(struct mlx5_ib_dev *dev,
|
||||
struct mlx5_ib_flow_prio *ft_prio,
|
||||
enum mlx5_flow_namespace_type ns_type)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = steering_anchor_create_ft(dev, ft_prio, ns_type);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = steering_anchor_create_fg_drop(ft_prio);
|
||||
if (err)
|
||||
goto destroy_ft;
|
||||
|
||||
err = steering_anchor_create_fg_goto_table(ft_prio);
|
||||
if (err)
|
||||
goto destroy_fg_drop;
|
||||
|
||||
err = steering_anchor_create_rule_drop(ft_prio);
|
||||
if (err)
|
||||
goto destroy_fg_goto_table;
|
||||
|
||||
err = steering_anchor_create_rule_goto_table(ft_prio);
|
||||
if (err)
|
||||
goto destroy_rule_drop;
|
||||
|
||||
return 0;
|
||||
|
||||
destroy_rule_drop:
|
||||
steering_anchor_destroy_rule_drop(ft_prio);
|
||||
destroy_fg_goto_table:
|
||||
steering_anchor_destroy_fg_goto_table(ft_prio);
|
||||
destroy_fg_drop:
|
||||
steering_anchor_destroy_fg_drop(ft_prio);
|
||||
destroy_ft:
|
||||
steering_anchor_destroy_ft(ft_prio);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static void mlx5_steering_anchor_destroy_res(struct mlx5_ib_flow_prio *ft_prio)
|
||||
{
|
||||
steering_anchor_destroy_rule_goto_table(ft_prio);
|
||||
steering_anchor_destroy_rule_drop(ft_prio);
|
||||
steering_anchor_destroy_fg_goto_table(ft_prio);
|
||||
steering_anchor_destroy_fg_drop(ft_prio);
|
||||
steering_anchor_destroy_ft(ft_prio);
|
||||
}
|
||||
|
||||
static int steering_anchor_cleanup(struct ib_uobject *uobject,
|
||||
enum rdma_remove_reason why,
|
||||
struct uverbs_attr_bundle *attrs)
|
||||
@@ -2035,6 +2264,9 @@ static int steering_anchor_cleanup(struct ib_uobject *uobject,
|
||||
return -EBUSY;
|
||||
|
||||
mutex_lock(&obj->dev->flow_db->lock);
|
||||
if (!--obj->ft_prio->anchor.rule_goto_table_ref)
|
||||
steering_anchor_destroy_rule_goto_table(obj->ft_prio);
|
||||
|
||||
put_flow_table(obj->dev, obj->ft_prio, true);
|
||||
mutex_unlock(&obj->dev->flow_db->lock);
|
||||
|
||||
@@ -2042,6 +2274,24 @@ static int steering_anchor_cleanup(struct ib_uobject *uobject,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void fs_cleanup_anchor(struct mlx5_ib_flow_prio *prio,
|
||||
int count)
|
||||
{
|
||||
while (count--)
|
||||
mlx5_steering_anchor_destroy_res(&prio[count]);
|
||||
}
|
||||
|
||||
void mlx5_ib_fs_cleanup_anchor(struct mlx5_ib_dev *dev)
|
||||
{
|
||||
fs_cleanup_anchor(dev->flow_db->prios, MLX5_IB_NUM_FLOW_FT);
|
||||
fs_cleanup_anchor(dev->flow_db->egress_prios, MLX5_IB_NUM_FLOW_FT);
|
||||
fs_cleanup_anchor(dev->flow_db->sniffer, MLX5_IB_NUM_SNIFFER_FTS);
|
||||
fs_cleanup_anchor(dev->flow_db->egress, MLX5_IB_NUM_EGRESS_FTS);
|
||||
fs_cleanup_anchor(dev->flow_db->fdb, MLX5_IB_NUM_FDB_FTS);
|
||||
fs_cleanup_anchor(dev->flow_db->rdma_rx, MLX5_IB_NUM_FLOW_FT);
|
||||
fs_cleanup_anchor(dev->flow_db->rdma_tx, MLX5_IB_NUM_FLOW_FT);
|
||||
}
|
||||
|
||||
static int mlx5_ib_matcher_ns(struct uverbs_attr_bundle *attrs,
|
||||
struct mlx5_ib_flow_matcher *obj)
|
||||
{
|
||||
@@ -2182,21 +2432,31 @@ static int UVERBS_HANDLER(MLX5_IB_METHOD_STEERING_ANCHOR_CREATE)(
|
||||
return -ENOMEM;
|
||||
|
||||
mutex_lock(&dev->flow_db->lock);
|
||||
|
||||
ft_prio = _get_flow_table(dev, priority, ns_type, 0);
|
||||
if (IS_ERR(ft_prio)) {
|
||||
mutex_unlock(&dev->flow_db->lock);
|
||||
err = PTR_ERR(ft_prio);
|
||||
goto free_obj;
|
||||
}
|
||||
|
||||
ft_prio->refcount++;
|
||||
ft_id = mlx5_flow_table_id(ft_prio->flow_table);
|
||||
mutex_unlock(&dev->flow_db->lock);
|
||||
|
||||
if (!ft_prio->anchor.rule_goto_table_ref) {
|
||||
err = steering_anchor_create_res(dev, ft_prio, ns_type);
|
||||
if (err)
|
||||
goto put_flow_table;
|
||||
}
|
||||
|
||||
ft_prio->anchor.rule_goto_table_ref++;
|
||||
|
||||
ft_id = mlx5_flow_table_id(ft_prio->anchor.ft);
|
||||
|
||||
err = uverbs_copy_to(attrs, MLX5_IB_ATTR_STEERING_ANCHOR_FT_ID,
|
||||
&ft_id, sizeof(ft_id));
|
||||
if (err)
|
||||
goto put_flow_table;
|
||||
goto destroy_res;
|
||||
|
||||
mutex_unlock(&dev->flow_db->lock);
|
||||
|
||||
uobj->object = obj;
|
||||
obj->dev = dev;
|
||||
@@ -2205,8 +2465,10 @@ static int UVERBS_HANDLER(MLX5_IB_METHOD_STEERING_ANCHOR_CREATE)(
|
||||
|
||||
return 0;
|
||||
|
||||
destroy_res:
|
||||
--ft_prio->anchor.rule_goto_table_ref;
|
||||
mlx5_steering_anchor_destroy_res(ft_prio);
|
||||
put_flow_table:
|
||||
mutex_lock(&dev->flow_db->lock);
|
||||
put_flow_table(dev, ft_prio, true);
|
||||
mutex_unlock(&dev->flow_db->lock);
|
||||
free_obj:
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
#if IS_ENABLED(CONFIG_INFINIBAND_USER_ACCESS)
|
||||
int mlx5_ib_fs_init(struct mlx5_ib_dev *dev);
|
||||
void mlx5_ib_fs_cleanup_anchor(struct mlx5_ib_dev *dev);
|
||||
#else
|
||||
static inline int mlx5_ib_fs_init(struct mlx5_ib_dev *dev)
|
||||
{
|
||||
@@ -21,9 +22,24 @@ static inline int mlx5_ib_fs_init(struct mlx5_ib_dev *dev)
|
||||
mutex_init(&dev->flow_db->lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline void mlx5_ib_fs_cleanup_anchor(struct mlx5_ib_dev *dev) {}
|
||||
#endif
|
||||
|
||||
static inline void mlx5_ib_fs_cleanup(struct mlx5_ib_dev *dev)
|
||||
{
|
||||
/* When a steering anchor is created, a special flow table is also
|
||||
* created for the user to reference. Since the user can reference it,
|
||||
* the kernel cannot trust that when the user destroys the steering
|
||||
* anchor, they no longer reference the flow table.
|
||||
*
|
||||
* To address this issue, when a user destroys a steering anchor, only
|
||||
* the flow steering rule in the table is destroyed, but the table
|
||||
* itself is kept to deal with the above scenario. The remaining
|
||||
* resources are only removed when the RDMA device is destroyed, which
|
||||
* is a safe assumption that all references are gone.
|
||||
*/
|
||||
mlx5_ib_fs_cleanup_anchor(dev);
|
||||
kfree(dev->flow_db);
|
||||
}
|
||||
#endif /* _MLX5_IB_FS_H */
|
||||
|
||||
@@ -4275,6 +4275,9 @@ const struct mlx5_ib_profile raw_eth_profile = {
|
||||
STAGE_CREATE(MLX5_IB_STAGE_POST_IB_REG_UMR,
|
||||
mlx5_ib_stage_post_ib_reg_umr_init,
|
||||
NULL),
|
||||
STAGE_CREATE(MLX5_IB_STAGE_DELAY_DROP,
|
||||
mlx5_ib_stage_delay_drop_init,
|
||||
mlx5_ib_stage_delay_drop_cleanup),
|
||||
STAGE_CREATE(MLX5_IB_STAGE_RESTRACK,
|
||||
mlx5_ib_restrack_init,
|
||||
NULL),
|
||||
|
||||
@@ -237,8 +237,19 @@ enum {
|
||||
#define MLX5_IB_NUM_SNIFFER_FTS 2
|
||||
#define MLX5_IB_NUM_EGRESS_FTS 1
|
||||
#define MLX5_IB_NUM_FDB_FTS MLX5_BY_PASS_NUM_REGULAR_PRIOS
|
||||
|
||||
struct mlx5_ib_anchor {
|
||||
struct mlx5_flow_table *ft;
|
||||
struct mlx5_flow_group *fg_goto_table;
|
||||
struct mlx5_flow_group *fg_drop;
|
||||
struct mlx5_flow_handle *rule_goto_table;
|
||||
struct mlx5_flow_handle *rule_drop;
|
||||
unsigned int rule_goto_table_ref;
|
||||
};
|
||||
|
||||
struct mlx5_ib_flow_prio {
|
||||
struct mlx5_flow_table *flow_table;
|
||||
struct mlx5_ib_anchor anchor;
|
||||
unsigned int refcount;
|
||||
};
|
||||
|
||||
@@ -1587,6 +1598,9 @@ static inline bool mlx5_ib_lag_should_assign_affinity(struct mlx5_ib_dev *dev)
|
||||
MLX5_CAP_PORT_SELECTION(dev->mdev, port_select_flow_table_bypass))
|
||||
return 0;
|
||||
|
||||
if (mlx5_lag_is_lacp_owner(dev->mdev) && !dev->lag_active)
|
||||
return 0;
|
||||
|
||||
return dev->lag_active ||
|
||||
(MLX5_CAP_GEN(dev->mdev, num_lag_ports) > 1 &&
|
||||
MLX5_CAP_GEN(dev->mdev, lag_tx_port_affinity));
|
||||
|
||||
@@ -1237,6 +1237,9 @@ static int create_raw_packet_qp_tis(struct mlx5_ib_dev *dev,
|
||||
|
||||
MLX5_SET(create_tis_in, in, uid, to_mpd(pd)->uid);
|
||||
MLX5_SET(tisc, tisc, transport_domain, tdn);
|
||||
if (!mlx5_ib_lag_should_assign_affinity(dev) &&
|
||||
mlx5_lag_is_lacp_owner(dev->mdev))
|
||||
MLX5_SET(tisc, tisc, strict_lag_tx_port_affinity, 1);
|
||||
if (qp->flags & IB_QP_CREATE_SOURCE_QPN)
|
||||
MLX5_SET(tisc, tisc, underlay_qpn, qp->underlay_qpn);
|
||||
|
||||
|
||||
@@ -113,8 +113,6 @@ int rxe_cq_post(struct rxe_cq *cq, struct rxe_cqe *cqe, int solicited)
|
||||
|
||||
queue_advance_producer(cq->queue, QUEUE_TYPE_TO_CLIENT);
|
||||
|
||||
spin_unlock_irqrestore(&cq->cq_lock, flags);
|
||||
|
||||
if ((cq->notify == IB_CQ_NEXT_COMP) ||
|
||||
(cq->notify == IB_CQ_SOLICITED && solicited)) {
|
||||
cq->notify = 0;
|
||||
@@ -122,6 +120,8 @@ int rxe_cq_post(struct rxe_cq *cq, struct rxe_cqe *cqe, int solicited)
|
||||
cq->ibcq.comp_handler(&cq->ibcq, cq->ibcq.cq_context);
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&cq->cq_lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -159,6 +159,9 @@ static int rxe_udp_encap_recv(struct sock *sk, struct sk_buff *skb)
|
||||
pkt->mask = RXE_GRH_MASK;
|
||||
pkt->paylen = be16_to_cpu(udph->len) - sizeof(*udph);
|
||||
|
||||
/* remove udp header */
|
||||
skb_pull(skb, sizeof(struct udphdr));
|
||||
|
||||
rxe_rcv(skb);
|
||||
|
||||
return 0;
|
||||
@@ -401,6 +404,9 @@ static int rxe_loopback(struct sk_buff *skb, struct rxe_pkt_info *pkt)
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
/* remove udp header */
|
||||
skb_pull(skb, sizeof(struct udphdr));
|
||||
|
||||
rxe_rcv(skb);
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -176,6 +176,9 @@ static void rxe_qp_init_misc(struct rxe_dev *rxe, struct rxe_qp *qp,
|
||||
spin_lock_init(&qp->rq.producer_lock);
|
||||
spin_lock_init(&qp->rq.consumer_lock);
|
||||
|
||||
skb_queue_head_init(&qp->req_pkts);
|
||||
skb_queue_head_init(&qp->resp_pkts);
|
||||
|
||||
atomic_set(&qp->ssn, 0);
|
||||
atomic_set(&qp->skb_out, 0);
|
||||
}
|
||||
@@ -234,8 +237,6 @@ static int rxe_qp_init_req(struct rxe_dev *rxe, struct rxe_qp *qp,
|
||||
qp->req.opcode = -1;
|
||||
qp->comp.opcode = -1;
|
||||
|
||||
skb_queue_head_init(&qp->req_pkts);
|
||||
|
||||
rxe_init_task(&qp->req.task, qp, rxe_requester);
|
||||
rxe_init_task(&qp->comp.task, qp, rxe_completer);
|
||||
|
||||
@@ -279,8 +280,6 @@ static int rxe_qp_init_resp(struct rxe_dev *rxe, struct rxe_qp *qp,
|
||||
}
|
||||
}
|
||||
|
||||
skb_queue_head_init(&qp->resp_pkts);
|
||||
|
||||
rxe_init_task(&qp->resp.task, qp, rxe_responder);
|
||||
|
||||
qp->resp.opcode = OPCODE_NONE;
|
||||
|
||||
@@ -489,8 +489,9 @@ static enum resp_states check_rkey(struct rxe_qp *qp,
|
||||
if (mw->access & IB_ZERO_BASED)
|
||||
qp->resp.offset = mw->addr;
|
||||
|
||||
rxe_put(mw);
|
||||
rxe_get(mr);
|
||||
rxe_put(mw);
|
||||
mw = NULL;
|
||||
} else {
|
||||
mr = lookup_mr(qp->pd, access, rkey, RXE_LOOKUP_REMOTE);
|
||||
if (!mr) {
|
||||
|
||||
@@ -657,9 +657,13 @@ static int
|
||||
isert_connect_error(struct rdma_cm_id *cma_id)
|
||||
{
|
||||
struct isert_conn *isert_conn = cma_id->qp->qp_context;
|
||||
struct isert_np *isert_np = cma_id->context;
|
||||
|
||||
ib_drain_qp(isert_conn->qp);
|
||||
|
||||
mutex_lock(&isert_np->mutex);
|
||||
list_del_init(&isert_conn->node);
|
||||
mutex_unlock(&isert_np->mutex);
|
||||
isert_conn->cm_id = NULL;
|
||||
isert_put_conn(isert_conn);
|
||||
|
||||
@@ -2431,6 +2435,7 @@ isert_free_np(struct iscsi_np *np)
|
||||
{
|
||||
struct isert_np *isert_np = np->np_context;
|
||||
struct isert_conn *isert_conn, *n;
|
||||
LIST_HEAD(drop_conn_list);
|
||||
|
||||
if (isert_np->cm_id)
|
||||
rdma_destroy_id(isert_np->cm_id);
|
||||
@@ -2450,7 +2455,7 @@ isert_free_np(struct iscsi_np *np)
|
||||
node) {
|
||||
isert_info("cleaning isert_conn %p state (%d)\n",
|
||||
isert_conn, isert_conn->state);
|
||||
isert_connect_release(isert_conn);
|
||||
list_move_tail(&isert_conn->node, &drop_conn_list);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2461,11 +2466,16 @@ isert_free_np(struct iscsi_np *np)
|
||||
node) {
|
||||
isert_info("cleaning isert_conn %p state (%d)\n",
|
||||
isert_conn, isert_conn->state);
|
||||
isert_connect_release(isert_conn);
|
||||
list_move_tail(&isert_conn->node, &drop_conn_list);
|
||||
}
|
||||
}
|
||||
mutex_unlock(&isert_np->mutex);
|
||||
|
||||
list_for_each_entry_safe(isert_conn, n, &drop_conn_list, node) {
|
||||
list_del_init(&isert_conn->node);
|
||||
isert_connect_release(isert_conn);
|
||||
}
|
||||
|
||||
np->np_context = NULL;
|
||||
kfree(isert_np);
|
||||
}
|
||||
@@ -2560,8 +2570,6 @@ static void isert_wait_conn(struct iscsit_conn *conn)
|
||||
isert_put_unsol_pending_cmds(conn);
|
||||
isert_wait4cmds(conn);
|
||||
isert_wait4logout(isert_conn);
|
||||
|
||||
queue_work(isert_release_wq, &isert_conn->release_work);
|
||||
}
|
||||
|
||||
static void isert_free_conn(struct iscsit_conn *conn)
|
||||
|
||||
@@ -2040,6 +2040,7 @@ static int rtrs_clt_rdma_cm_handler(struct rdma_cm_id *cm_id,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* The caller should do the cleanup in case of error */
|
||||
static int create_cm(struct rtrs_clt_con *con)
|
||||
{
|
||||
struct rtrs_path *s = con->c.path;
|
||||
@@ -2062,14 +2063,14 @@ static int create_cm(struct rtrs_clt_con *con)
|
||||
err = rdma_set_reuseaddr(cm_id, 1);
|
||||
if (err != 0) {
|
||||
rtrs_err(s, "Set address reuse failed, err: %d\n", err);
|
||||
goto destroy_cm;
|
||||
return err;
|
||||
}
|
||||
err = rdma_resolve_addr(cm_id, (struct sockaddr *)&clt_path->s.src_addr,
|
||||
(struct sockaddr *)&clt_path->s.dst_addr,
|
||||
RTRS_CONNECT_TIMEOUT_MS);
|
||||
if (err) {
|
||||
rtrs_err(s, "Failed to resolve address, err: %d\n", err);
|
||||
goto destroy_cm;
|
||||
return err;
|
||||
}
|
||||
/*
|
||||
* Combine connection status and session events. This is needed
|
||||
@@ -2084,29 +2085,15 @@ static int create_cm(struct rtrs_clt_con *con)
|
||||
if (err == 0)
|
||||
err = -ETIMEDOUT;
|
||||
/* Timedout or interrupted */
|
||||
goto errr;
|
||||
return err;
|
||||
}
|
||||
if (con->cm_err < 0) {
|
||||
err = con->cm_err;
|
||||
goto errr;
|
||||
}
|
||||
if (READ_ONCE(clt_path->state) != RTRS_CLT_CONNECTING) {
|
||||
if (con->cm_err < 0)
|
||||
return con->cm_err;
|
||||
if (READ_ONCE(clt_path->state) != RTRS_CLT_CONNECTING)
|
||||
/* Device removal */
|
||||
err = -ECONNABORTED;
|
||||
goto errr;
|
||||
}
|
||||
return -ECONNABORTED;
|
||||
|
||||
return 0;
|
||||
|
||||
errr:
|
||||
stop_cm(con);
|
||||
mutex_lock(&con->con_mutex);
|
||||
destroy_con_cq_qp(con);
|
||||
mutex_unlock(&con->con_mutex);
|
||||
destroy_cm:
|
||||
destroy_cm(con);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static void rtrs_clt_path_up(struct rtrs_clt_path *clt_path)
|
||||
@@ -2334,7 +2321,7 @@ static void rtrs_clt_close_work(struct work_struct *work)
|
||||
static int init_conns(struct rtrs_clt_path *clt_path)
|
||||
{
|
||||
unsigned int cid;
|
||||
int err;
|
||||
int err, i;
|
||||
|
||||
/*
|
||||
* On every new session connections increase reconnect counter
|
||||
@@ -2350,10 +2337,8 @@ static int init_conns(struct rtrs_clt_path *clt_path)
|
||||
goto destroy;
|
||||
|
||||
err = create_cm(to_clt_con(clt_path->s.con[cid]));
|
||||
if (err) {
|
||||
destroy_con(to_clt_con(clt_path->s.con[cid]));
|
||||
if (err)
|
||||
goto destroy;
|
||||
}
|
||||
}
|
||||
err = alloc_path_reqs(clt_path);
|
||||
if (err)
|
||||
@@ -2364,15 +2349,21 @@ static int init_conns(struct rtrs_clt_path *clt_path)
|
||||
return 0;
|
||||
|
||||
destroy:
|
||||
while (cid--) {
|
||||
struct rtrs_clt_con *con = to_clt_con(clt_path->s.con[cid]);
|
||||
/* Make sure we do the cleanup in the order they are created */
|
||||
for (i = 0; i <= cid; i++) {
|
||||
struct rtrs_clt_con *con;
|
||||
|
||||
stop_cm(con);
|
||||
if (!clt_path->s.con[i])
|
||||
break;
|
||||
|
||||
mutex_lock(&con->con_mutex);
|
||||
destroy_con_cq_qp(con);
|
||||
mutex_unlock(&con->con_mutex);
|
||||
destroy_cm(con);
|
||||
con = to_clt_con(clt_path->s.con[i]);
|
||||
if (con->c.cm_id) {
|
||||
stop_cm(con);
|
||||
mutex_lock(&con->con_mutex);
|
||||
destroy_con_cq_qp(con);
|
||||
mutex_unlock(&con->con_mutex);
|
||||
destroy_cm(con);
|
||||
}
|
||||
destroy_con(con);
|
||||
}
|
||||
/*
|
||||
|
||||
@@ -37,8 +37,10 @@ struct rtrs_iu *rtrs_iu_alloc(u32 iu_num, size_t size, gfp_t gfp_mask,
|
||||
goto err;
|
||||
|
||||
iu->dma_addr = ib_dma_map_single(dma_dev, iu->buf, size, dir);
|
||||
if (ib_dma_mapping_error(dma_dev, iu->dma_addr))
|
||||
if (ib_dma_mapping_error(dma_dev, iu->dma_addr)) {
|
||||
kfree(iu->buf);
|
||||
goto err;
|
||||
}
|
||||
|
||||
iu->cqe.done = done;
|
||||
iu->size = size;
|
||||
|
||||
@@ -1168,13 +1168,10 @@ static int do_resume(struct dm_ioctl *param)
|
||||
/* Do we need to load a new map ? */
|
||||
if (new_map) {
|
||||
sector_t old_size, new_size;
|
||||
int srcu_idx;
|
||||
|
||||
/* Suspend if it isn't already suspended */
|
||||
old_map = dm_get_live_table(md, &srcu_idx);
|
||||
if ((param->flags & DM_SKIP_LOCKFS_FLAG) || !old_map)
|
||||
if (param->flags & DM_SKIP_LOCKFS_FLAG)
|
||||
suspend_flags &= ~DM_SUSPEND_LOCKFS_FLAG;
|
||||
dm_put_live_table(md, srcu_idx);
|
||||
if (param->flags & DM_NOFLUSH_FLAG)
|
||||
suspend_flags |= DM_SUSPEND_NOFLUSH_FLAG;
|
||||
if (!dm_suspended_md(md))
|
||||
|
||||
@@ -1756,13 +1756,15 @@ int dm_thin_remove_range(struct dm_thin_device *td,
|
||||
|
||||
int dm_pool_block_is_shared(struct dm_pool_metadata *pmd, dm_block_t b, bool *result)
|
||||
{
|
||||
int r;
|
||||
int r = -EINVAL;
|
||||
uint32_t ref_count;
|
||||
|
||||
down_read(&pmd->root_lock);
|
||||
r = dm_sm_get_count(pmd->data_sm, b, &ref_count);
|
||||
if (!r)
|
||||
*result = (ref_count > 1);
|
||||
if (!pmd->fail_io) {
|
||||
r = dm_sm_get_count(pmd->data_sm, b, &ref_count);
|
||||
if (!r)
|
||||
*result = (ref_count > 1);
|
||||
}
|
||||
up_read(&pmd->root_lock);
|
||||
|
||||
return r;
|
||||
@@ -1770,10 +1772,11 @@ int dm_pool_block_is_shared(struct dm_pool_metadata *pmd, dm_block_t b, bool *re
|
||||
|
||||
int dm_pool_inc_data_range(struct dm_pool_metadata *pmd, dm_block_t b, dm_block_t e)
|
||||
{
|
||||
int r = 0;
|
||||
int r = -EINVAL;
|
||||
|
||||
pmd_write_lock(pmd);
|
||||
r = dm_sm_inc_blocks(pmd->data_sm, b, e);
|
||||
if (!pmd->fail_io)
|
||||
r = dm_sm_inc_blocks(pmd->data_sm, b, e);
|
||||
pmd_write_unlock(pmd);
|
||||
|
||||
return r;
|
||||
@@ -1781,10 +1784,11 @@ int dm_pool_inc_data_range(struct dm_pool_metadata *pmd, dm_block_t b, dm_block_
|
||||
|
||||
int dm_pool_dec_data_range(struct dm_pool_metadata *pmd, dm_block_t b, dm_block_t e)
|
||||
{
|
||||
int r = 0;
|
||||
int r = -EINVAL;
|
||||
|
||||
pmd_write_lock(pmd);
|
||||
r = dm_sm_dec_blocks(pmd->data_sm, b, e);
|
||||
if (!pmd->fail_io)
|
||||
r = dm_sm_dec_blocks(pmd->data_sm, b, e);
|
||||
pmd_write_unlock(pmd);
|
||||
|
||||
return r;
|
||||
|
||||
@@ -401,8 +401,7 @@ static int issue_discard(struct discard_op *op, dm_block_t data_b, dm_block_t da
|
||||
sector_t s = block_to_sectors(tc->pool, data_b);
|
||||
sector_t len = block_to_sectors(tc->pool, data_e - data_b);
|
||||
|
||||
return __blkdev_issue_discard(tc->pool_dev->bdev, s, len, GFP_NOWAIT,
|
||||
&op->bio);
|
||||
return __blkdev_issue_discard(tc->pool_dev->bdev, s, len, GFP_NOIO, &op->bio);
|
||||
}
|
||||
|
||||
static void end_discard(struct discard_op *op, int r)
|
||||
|
||||
+20
-9
@@ -1172,7 +1172,8 @@ static inline sector_t max_io_len_target_boundary(struct dm_target *ti,
|
||||
}
|
||||
|
||||
static sector_t __max_io_len(struct dm_target *ti, sector_t sector,
|
||||
unsigned int max_granularity)
|
||||
unsigned int max_granularity,
|
||||
unsigned int max_sectors)
|
||||
{
|
||||
sector_t target_offset = dm_target_offset(ti, sector);
|
||||
sector_t len = max_io_len_target_boundary(ti, target_offset);
|
||||
@@ -1186,13 +1187,13 @@ static sector_t __max_io_len(struct dm_target *ti, sector_t sector,
|
||||
if (!max_granularity)
|
||||
return len;
|
||||
return min_t(sector_t, len,
|
||||
min(queue_max_sectors(ti->table->md->queue),
|
||||
min(max_sectors ? : queue_max_sectors(ti->table->md->queue),
|
||||
blk_chunk_sectors_left(target_offset, max_granularity)));
|
||||
}
|
||||
|
||||
static inline sector_t max_io_len(struct dm_target *ti, sector_t sector)
|
||||
{
|
||||
return __max_io_len(ti, sector, ti->max_io_len);
|
||||
return __max_io_len(ti, sector, ti->max_io_len, 0);
|
||||
}
|
||||
|
||||
int dm_set_target_max_io_len(struct dm_target *ti, sector_t len)
|
||||
@@ -1581,12 +1582,13 @@ static void __send_empty_flush(struct clone_info *ci)
|
||||
|
||||
static void __send_changing_extent_only(struct clone_info *ci, struct dm_target *ti,
|
||||
unsigned int num_bios,
|
||||
unsigned int max_granularity)
|
||||
unsigned int max_granularity,
|
||||
unsigned int max_sectors)
|
||||
{
|
||||
unsigned int len, bios;
|
||||
|
||||
len = min_t(sector_t, ci->sector_count,
|
||||
__max_io_len(ti, ci->sector, max_granularity));
|
||||
__max_io_len(ti, ci->sector, max_granularity, max_sectors));
|
||||
|
||||
atomic_add(num_bios, &ci->io->io_count);
|
||||
bios = __send_duplicate_bios(ci, ti, num_bios, &len);
|
||||
@@ -1623,23 +1625,27 @@ static blk_status_t __process_abnormal_io(struct clone_info *ci,
|
||||
{
|
||||
unsigned int num_bios = 0;
|
||||
unsigned int max_granularity = 0;
|
||||
unsigned int max_sectors = 0;
|
||||
struct queue_limits *limits = dm_get_queue_limits(ti->table->md);
|
||||
|
||||
switch (bio_op(ci->bio)) {
|
||||
case REQ_OP_DISCARD:
|
||||
num_bios = ti->num_discard_bios;
|
||||
max_sectors = limits->max_discard_sectors;
|
||||
if (ti->max_discard_granularity)
|
||||
max_granularity = limits->max_discard_sectors;
|
||||
max_granularity = max_sectors;
|
||||
break;
|
||||
case REQ_OP_SECURE_ERASE:
|
||||
num_bios = ti->num_secure_erase_bios;
|
||||
max_sectors = limits->max_secure_erase_sectors;
|
||||
if (ti->max_secure_erase_granularity)
|
||||
max_granularity = limits->max_secure_erase_sectors;
|
||||
max_granularity = max_sectors;
|
||||
break;
|
||||
case REQ_OP_WRITE_ZEROES:
|
||||
num_bios = ti->num_write_zeroes_bios;
|
||||
max_sectors = limits->max_write_zeroes_sectors;
|
||||
if (ti->max_write_zeroes_granularity)
|
||||
max_granularity = limits->max_write_zeroes_sectors;
|
||||
max_granularity = max_sectors;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -1654,7 +1660,8 @@ static blk_status_t __process_abnormal_io(struct clone_info *ci,
|
||||
if (unlikely(!num_bios))
|
||||
return BLK_STS_NOTSUPP;
|
||||
|
||||
__send_changing_extent_only(ci, ti, num_bios, max_granularity);
|
||||
__send_changing_extent_only(ci, ti, num_bios,
|
||||
max_granularity, max_sectors);
|
||||
return BLK_STS_OK;
|
||||
}
|
||||
|
||||
@@ -2808,6 +2815,10 @@ retry:
|
||||
}
|
||||
|
||||
map = rcu_dereference_protected(md->map, lockdep_is_held(&md->suspend_lock));
|
||||
if (!map) {
|
||||
/* avoid deadlock with fs/namespace.c:do_mount() */
|
||||
suspend_flags &= ~DM_SUSPEND_LOCKFS_FLAG;
|
||||
}
|
||||
|
||||
r = __dm_suspend(md, map, suspend_flags, TASK_INTERRUPTIBLE, DMF_SUSPENDED);
|
||||
if (r)
|
||||
|
||||
@@ -817,26 +817,15 @@ static void dvb_frontend_stop(struct dvb_frontend *fe)
|
||||
|
||||
dev_dbg(fe->dvb->device, "%s:\n", __func__);
|
||||
|
||||
mutex_lock(&fe->remove_mutex);
|
||||
|
||||
if (fe->exit != DVB_FE_DEVICE_REMOVED)
|
||||
fe->exit = DVB_FE_NORMAL_EXIT;
|
||||
mb();
|
||||
|
||||
if (!fepriv->thread) {
|
||||
mutex_unlock(&fe->remove_mutex);
|
||||
if (!fepriv->thread)
|
||||
return;
|
||||
}
|
||||
|
||||
kthread_stop(fepriv->thread);
|
||||
|
||||
mutex_unlock(&fe->remove_mutex);
|
||||
|
||||
if (fepriv->dvbdev->users < -1) {
|
||||
wait_event(fepriv->dvbdev->wait_queue,
|
||||
fepriv->dvbdev->users == -1);
|
||||
}
|
||||
|
||||
sema_init(&fepriv->sem, 1);
|
||||
fepriv->state = FESTATE_IDLE;
|
||||
|
||||
@@ -2780,13 +2769,9 @@ static int dvb_frontend_open(struct inode *inode, struct file *file)
|
||||
struct dvb_adapter *adapter = fe->dvb;
|
||||
int ret;
|
||||
|
||||
mutex_lock(&fe->remove_mutex);
|
||||
|
||||
dev_dbg(fe->dvb->device, "%s:\n", __func__);
|
||||
if (fe->exit == DVB_FE_DEVICE_REMOVED) {
|
||||
ret = -ENODEV;
|
||||
goto err_remove_mutex;
|
||||
}
|
||||
if (fe->exit == DVB_FE_DEVICE_REMOVED)
|
||||
return -ENODEV;
|
||||
|
||||
if (adapter->mfe_shared == 2) {
|
||||
mutex_lock(&adapter->mfe_lock);
|
||||
@@ -2794,8 +2779,7 @@ static int dvb_frontend_open(struct inode *inode, struct file *file)
|
||||
if (adapter->mfe_dvbdev &&
|
||||
!adapter->mfe_dvbdev->writers) {
|
||||
mutex_unlock(&adapter->mfe_lock);
|
||||
ret = -EBUSY;
|
||||
goto err_remove_mutex;
|
||||
return -EBUSY;
|
||||
}
|
||||
adapter->mfe_dvbdev = dvbdev;
|
||||
}
|
||||
@@ -2818,10 +2802,8 @@ static int dvb_frontend_open(struct inode *inode, struct file *file)
|
||||
while (mferetry-- && (mfedev->users != -1 ||
|
||||
mfepriv->thread)) {
|
||||
if (msleep_interruptible(500)) {
|
||||
if (signal_pending(current)) {
|
||||
ret = -EINTR;
|
||||
goto err_remove_mutex;
|
||||
}
|
||||
if (signal_pending(current))
|
||||
return -EINTR;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2833,8 +2815,7 @@ static int dvb_frontend_open(struct inode *inode, struct file *file)
|
||||
if (mfedev->users != -1 ||
|
||||
mfepriv->thread) {
|
||||
mutex_unlock(&adapter->mfe_lock);
|
||||
ret = -EBUSY;
|
||||
goto err_remove_mutex;
|
||||
return -EBUSY;
|
||||
}
|
||||
adapter->mfe_dvbdev = dvbdev;
|
||||
}
|
||||
@@ -2893,8 +2874,6 @@ static int dvb_frontend_open(struct inode *inode, struct file *file)
|
||||
|
||||
if (adapter->mfe_shared)
|
||||
mutex_unlock(&adapter->mfe_lock);
|
||||
|
||||
mutex_unlock(&fe->remove_mutex);
|
||||
return ret;
|
||||
|
||||
err3:
|
||||
@@ -2916,9 +2895,6 @@ err1:
|
||||
err0:
|
||||
if (adapter->mfe_shared)
|
||||
mutex_unlock(&adapter->mfe_lock);
|
||||
|
||||
err_remove_mutex:
|
||||
mutex_unlock(&fe->remove_mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -2929,8 +2905,6 @@ static int dvb_frontend_release(struct inode *inode, struct file *file)
|
||||
struct dvb_frontend_private *fepriv = fe->frontend_priv;
|
||||
int ret;
|
||||
|
||||
mutex_lock(&fe->remove_mutex);
|
||||
|
||||
dev_dbg(fe->dvb->device, "%s:\n", __func__);
|
||||
|
||||
if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
|
||||
@@ -2952,18 +2926,10 @@ static int dvb_frontend_release(struct inode *inode, struct file *file)
|
||||
}
|
||||
mutex_unlock(&fe->dvb->mdev_lock);
|
||||
#endif
|
||||
if (fe->exit != DVB_FE_NO_EXIT)
|
||||
wake_up(&dvbdev->wait_queue);
|
||||
if (fe->ops.ts_bus_ctrl)
|
||||
fe->ops.ts_bus_ctrl(fe, 0);
|
||||
|
||||
if (fe->exit != DVB_FE_NO_EXIT) {
|
||||
mutex_unlock(&fe->remove_mutex);
|
||||
wake_up(&dvbdev->wait_queue);
|
||||
} else {
|
||||
mutex_unlock(&fe->remove_mutex);
|
||||
}
|
||||
|
||||
} else {
|
||||
mutex_unlock(&fe->remove_mutex);
|
||||
}
|
||||
|
||||
dvb_frontend_put(fe);
|
||||
@@ -3064,7 +3030,6 @@ int dvb_register_frontend(struct dvb_adapter *dvb,
|
||||
fepriv = fe->frontend_priv;
|
||||
|
||||
kref_init(&fe->refcount);
|
||||
mutex_init(&fe->remove_mutex);
|
||||
|
||||
/*
|
||||
* After initialization, there need to be two references: one
|
||||
|
||||
@@ -1263,7 +1263,7 @@ static void vsc9959_tas_guard_bands_update(struct ocelot *ocelot, int port)
|
||||
/* Consider the standard Ethernet overhead of 8 octets preamble+SFD,
|
||||
* 4 octets FCS, 12 octets IFG.
|
||||
*/
|
||||
needed_bit_time_ps = (maxlen + 24) * picos_per_byte;
|
||||
needed_bit_time_ps = (u64)(maxlen + 24) * picos_per_byte;
|
||||
|
||||
dev_dbg(ocelot->dev,
|
||||
"port %d: max frame size %d needs %llu ps at speed %d\n",
|
||||
|
||||
@@ -14294,11 +14294,16 @@ static void bnx2x_io_resume(struct pci_dev *pdev)
|
||||
bp->fw_seq = SHMEM_RD(bp, func_mb[BP_FW_MB_IDX(bp)].drv_mb_header) &
|
||||
DRV_MSG_SEQ_NUMBER_MASK;
|
||||
|
||||
if (netif_running(dev))
|
||||
bnx2x_nic_load(bp, LOAD_NORMAL);
|
||||
if (netif_running(dev)) {
|
||||
if (bnx2x_nic_load(bp, LOAD_NORMAL)) {
|
||||
netdev_err(bp->dev, "Error during driver initialization, try unloading/reloading the driver\n");
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
netif_device_attach(dev);
|
||||
|
||||
done:
|
||||
rtnl_unlock();
|
||||
}
|
||||
|
||||
|
||||
@@ -181,8 +181,8 @@ int enetc_setup_tc_cbs(struct net_device *ndev, void *type_data)
|
||||
int bw_sum = 0;
|
||||
u8 bw;
|
||||
|
||||
prio_top = netdev_get_prio_tc_map(ndev, tc_nums - 1);
|
||||
prio_next = netdev_get_prio_tc_map(ndev, tc_nums - 2);
|
||||
prio_top = tc_nums - 1;
|
||||
prio_next = tc_nums - 2;
|
||||
|
||||
/* Support highest prio and second prio tc in cbs mode */
|
||||
if (tc != prio_top && tc != prio_next)
|
||||
|
||||
@@ -525,7 +525,7 @@ void iavf_set_ethtool_ops(struct net_device *netdev);
|
||||
void iavf_update_stats(struct iavf_adapter *adapter);
|
||||
void iavf_reset_interrupt_capability(struct iavf_adapter *adapter);
|
||||
int iavf_init_interrupt_scheme(struct iavf_adapter *adapter);
|
||||
void iavf_irq_enable_queues(struct iavf_adapter *adapter, u32 mask);
|
||||
void iavf_irq_enable_queues(struct iavf_adapter *adapter);
|
||||
void iavf_free_all_tx_resources(struct iavf_adapter *adapter);
|
||||
void iavf_free_all_rx_resources(struct iavf_adapter *adapter);
|
||||
|
||||
|
||||
@@ -359,21 +359,18 @@ static void iavf_irq_disable(struct iavf_adapter *adapter)
|
||||
}
|
||||
|
||||
/**
|
||||
* iavf_irq_enable_queues - Enable interrupt for specified queues
|
||||
* iavf_irq_enable_queues - Enable interrupt for all queues
|
||||
* @adapter: board private structure
|
||||
* @mask: bitmap of queues to enable
|
||||
**/
|
||||
void iavf_irq_enable_queues(struct iavf_adapter *adapter, u32 mask)
|
||||
void iavf_irq_enable_queues(struct iavf_adapter *adapter)
|
||||
{
|
||||
struct iavf_hw *hw = &adapter->hw;
|
||||
int i;
|
||||
|
||||
for (i = 1; i < adapter->num_msix_vectors; i++) {
|
||||
if (mask & BIT(i - 1)) {
|
||||
wr32(hw, IAVF_VFINT_DYN_CTLN1(i - 1),
|
||||
IAVF_VFINT_DYN_CTLN1_INTENA_MASK |
|
||||
IAVF_VFINT_DYN_CTLN1_ITR_INDX_MASK);
|
||||
}
|
||||
wr32(hw, IAVF_VFINT_DYN_CTLN1(i - 1),
|
||||
IAVF_VFINT_DYN_CTLN1_INTENA_MASK |
|
||||
IAVF_VFINT_DYN_CTLN1_ITR_INDX_MASK);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -387,7 +384,7 @@ void iavf_irq_enable(struct iavf_adapter *adapter, bool flush)
|
||||
struct iavf_hw *hw = &adapter->hw;
|
||||
|
||||
iavf_misc_irq_enable(adapter);
|
||||
iavf_irq_enable_queues(adapter, ~0);
|
||||
iavf_irq_enable_queues(adapter);
|
||||
|
||||
if (flush)
|
||||
iavf_flush(hw);
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
#define IAVF_VFINT_DYN_CTL01_INTENA_MASK IAVF_MASK(0x1, IAVF_VFINT_DYN_CTL01_INTENA_SHIFT)
|
||||
#define IAVF_VFINT_DYN_CTL01_ITR_INDX_SHIFT 3
|
||||
#define IAVF_VFINT_DYN_CTL01_ITR_INDX_MASK IAVF_MASK(0x3, IAVF_VFINT_DYN_CTL01_ITR_INDX_SHIFT)
|
||||
#define IAVF_VFINT_DYN_CTLN1(_INTVF) (0x00003800 + ((_INTVF) * 4)) /* _i=0...15 */ /* Reset: VFR */
|
||||
#define IAVF_VFINT_DYN_CTLN1(_INTVF) (0x00003800 + ((_INTVF) * 4)) /* _i=0...63 */ /* Reset: VFR */
|
||||
#define IAVF_VFINT_DYN_CTLN1_INTENA_SHIFT 0
|
||||
#define IAVF_VFINT_DYN_CTLN1_INTENA_MASK IAVF_MASK(0x1, IAVF_VFINT_DYN_CTLN1_INTENA_SHIFT)
|
||||
#define IAVF_VFINT_DYN_CTLN1_SWINT_TRIG_SHIFT 2
|
||||
|
||||
@@ -96,12 +96,7 @@ static void ice_gnss_read(struct kthread_work *work)
|
||||
int err = 0;
|
||||
|
||||
pf = gnss->back;
|
||||
if (!pf) {
|
||||
err = -EFAULT;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (!test_bit(ICE_FLAG_GNSS, pf->flags))
|
||||
if (!pf || !test_bit(ICE_FLAG_GNSS, pf->flags))
|
||||
return;
|
||||
|
||||
hw = &pf->hw;
|
||||
@@ -159,7 +154,6 @@ free_buf:
|
||||
free_page((unsigned long)buf);
|
||||
requeue:
|
||||
kthread_queue_delayed_work(gnss->kworker, &gnss->read_work, delay);
|
||||
exit:
|
||||
if (err)
|
||||
dev_dbg(ice_pf_to_dev(pf), "GNSS failed to read err=%d\n", err);
|
||||
}
|
||||
|
||||
@@ -4802,9 +4802,13 @@ err_init_pf:
|
||||
static void ice_deinit_dev(struct ice_pf *pf)
|
||||
{
|
||||
ice_free_irq_msix_misc(pf);
|
||||
ice_clear_interrupt_scheme(pf);
|
||||
ice_deinit_pf(pf);
|
||||
ice_deinit_hw(&pf->hw);
|
||||
|
||||
/* Service task is already stopped, so call reset directly. */
|
||||
ice_reset(&pf->hw, ICE_RESET_PFR);
|
||||
pci_wait_for_pending_transaction(pf->pdev);
|
||||
ice_clear_interrupt_scheme(pf);
|
||||
}
|
||||
|
||||
static void ice_init_features(struct ice_pf *pf)
|
||||
@@ -5094,10 +5098,6 @@ int ice_load(struct ice_pf *pf)
|
||||
struct ice_vsi *vsi;
|
||||
int err;
|
||||
|
||||
err = ice_reset(&pf->hw, ICE_RESET_PFR);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = ice_init_dev(pf);
|
||||
if (err)
|
||||
return err;
|
||||
@@ -5354,12 +5354,6 @@ static void ice_remove(struct pci_dev *pdev)
|
||||
ice_setup_mc_magic_wake(pf);
|
||||
ice_set_wake(pf);
|
||||
|
||||
/* Issue a PFR as part of the prescribed driver unload flow. Do not
|
||||
* do it via ice_schedule_reset() since there is no need to rebuild
|
||||
* and the service task is already stopped.
|
||||
*/
|
||||
ice_reset(&pf->hw, ICE_RESET_PFR);
|
||||
pci_wait_for_pending_transaction(pdev);
|
||||
pci_disable_device(pdev);
|
||||
}
|
||||
|
||||
@@ -7056,6 +7050,10 @@ int ice_down(struct ice_vsi *vsi)
|
||||
ice_for_each_txq(vsi, i)
|
||||
ice_clean_tx_ring(vsi->tx_rings[i]);
|
||||
|
||||
if (ice_is_xdp_ena_vsi(vsi))
|
||||
ice_for_each_xdp_txq(vsi, i)
|
||||
ice_clean_tx_ring(vsi->xdp_rings[i]);
|
||||
|
||||
ice_for_each_rxq(vsi, i)
|
||||
ice_clean_rx_ring(vsi->rx_rings[i]);
|
||||
|
||||
|
||||
@@ -822,6 +822,8 @@ static int igb_set_eeprom(struct net_device *netdev,
|
||||
*/
|
||||
ret_val = hw->nvm.ops.read(hw, last_word, 1,
|
||||
&eeprom_buff[last_word - first_word]);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Device's eeprom is always little-endian, word addressable */
|
||||
@@ -841,6 +843,7 @@ static int igb_set_eeprom(struct net_device *netdev,
|
||||
hw->nvm.ops.update(hw);
|
||||
|
||||
igb_set_fw_version(adapter);
|
||||
out:
|
||||
kfree(eeprom_buff);
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
@@ -6947,6 +6947,7 @@ static void igb_extts(struct igb_adapter *adapter, int tsintr_tt)
|
||||
struct e1000_hw *hw = &adapter->hw;
|
||||
struct ptp_clock_event event;
|
||||
struct timespec64 ts;
|
||||
unsigned long flags;
|
||||
|
||||
if (pin < 0 || pin >= IGB_N_SDP)
|
||||
return;
|
||||
@@ -6954,9 +6955,12 @@ static void igb_extts(struct igb_adapter *adapter, int tsintr_tt)
|
||||
if (hw->mac.type == e1000_82580 ||
|
||||
hw->mac.type == e1000_i354 ||
|
||||
hw->mac.type == e1000_i350) {
|
||||
s64 ns = rd32(auxstmpl);
|
||||
u64 ns = rd32(auxstmpl);
|
||||
|
||||
ns += ((s64)(rd32(auxstmph) & 0xFF)) << 32;
|
||||
ns += ((u64)(rd32(auxstmph) & 0xFF)) << 32;
|
||||
spin_lock_irqsave(&adapter->tmreg_lock, flags);
|
||||
ns = timecounter_cyc2time(&adapter->tc, ns);
|
||||
spin_unlock_irqrestore(&adapter->tmreg_lock, flags);
|
||||
ts = ns_to_timespec64(ns);
|
||||
} else {
|
||||
ts.tv_nsec = rd32(auxstmpl);
|
||||
|
||||
@@ -254,6 +254,13 @@ static void igc_clean_tx_ring(struct igc_ring *tx_ring)
|
||||
/* reset BQL for queue */
|
||||
netdev_tx_reset_queue(txring_txq(tx_ring));
|
||||
|
||||
/* Zero out the buffer ring */
|
||||
memset(tx_ring->tx_buffer_info, 0,
|
||||
sizeof(*tx_ring->tx_buffer_info) * tx_ring->count);
|
||||
|
||||
/* Zero out the descriptor ring */
|
||||
memset(tx_ring->desc, 0, tx_ring->size);
|
||||
|
||||
/* reset next_to_use and next_to_clean */
|
||||
tx_ring->next_to_use = 0;
|
||||
tx_ring->next_to_clean = 0;
|
||||
@@ -267,7 +274,7 @@ static void igc_clean_tx_ring(struct igc_ring *tx_ring)
|
||||
*/
|
||||
void igc_free_tx_resources(struct igc_ring *tx_ring)
|
||||
{
|
||||
igc_clean_tx_ring(tx_ring);
|
||||
igc_disable_tx_ring(tx_ring);
|
||||
|
||||
vfree(tx_ring->tx_buffer_info);
|
||||
tx_ring->tx_buffer_info = NULL;
|
||||
@@ -6723,6 +6730,9 @@ static void igc_remove(struct pci_dev *pdev)
|
||||
|
||||
igc_ptp_stop(adapter);
|
||||
|
||||
pci_disable_ptm(pdev);
|
||||
pci_clear_master(pdev);
|
||||
|
||||
set_bit(__IGC_DOWN, &adapter->state);
|
||||
|
||||
del_timer_sync(&adapter->watchdog_timer);
|
||||
|
||||
@@ -981,6 +981,9 @@ int octep_device_setup(struct octep_device *oct)
|
||||
oct->mmio[i].hw_addr =
|
||||
ioremap(pci_resource_start(oct->pdev, i * 2),
|
||||
pci_resource_len(oct->pdev, i * 2));
|
||||
if (!oct->mmio[i].hw_addr)
|
||||
goto unmap_prev;
|
||||
|
||||
oct->mmio[i].mapped = 1;
|
||||
}
|
||||
|
||||
@@ -1015,7 +1018,9 @@ int octep_device_setup(struct octep_device *oct)
|
||||
return 0;
|
||||
|
||||
unsupported_dev:
|
||||
for (i = 0; i < OCTEP_MMIO_REGIONS; i++)
|
||||
i = OCTEP_MMIO_REGIONS;
|
||||
unmap_prev:
|
||||
while (i--)
|
||||
iounmap(oct->mmio[i].hw_addr);
|
||||
|
||||
kfree(oct->conf);
|
||||
|
||||
@@ -1878,7 +1878,8 @@ static int nix_check_txschq_alloc_req(struct rvu *rvu, int lvl, u16 pcifunc,
|
||||
free_cnt = rvu_rsrc_free_count(&txsch->schq);
|
||||
}
|
||||
|
||||
if (free_cnt < req_schq || req_schq > MAX_TXSCHQ_PER_FUNC)
|
||||
if (free_cnt < req_schq || req->schq[lvl] > MAX_TXSCHQ_PER_FUNC ||
|
||||
req->schq_contig[lvl] > MAX_TXSCHQ_PER_FUNC)
|
||||
return NIX_AF_ERR_TLX_ALLOC_FAIL;
|
||||
|
||||
/* If contiguous queues are needed, check for availability */
|
||||
@@ -4080,10 +4081,6 @@ int rvu_mbox_handler_nix_set_rx_cfg(struct rvu *rvu, struct nix_rx_cfg *req,
|
||||
|
||||
static u64 rvu_get_lbk_link_credits(struct rvu *rvu, u16 lbk_max_frs)
|
||||
{
|
||||
/* CN10k supports 72KB FIFO size and max packet size of 64k */
|
||||
if (rvu->hw->lbk_bufsize == 0x12000)
|
||||
return (rvu->hw->lbk_bufsize - lbk_max_frs) / 16;
|
||||
|
||||
return 1600; /* 16 * max LBK datarate = 16 * 100Gbps */
|
||||
}
|
||||
|
||||
|
||||
@@ -1164,10 +1164,8 @@ static u16 __rvu_npc_exact_cmd_rules_cnt_update(struct rvu *rvu, int drop_mcam_i
|
||||
{
|
||||
struct npc_exact_table *table;
|
||||
u16 *cnt, old_cnt;
|
||||
bool promisc;
|
||||
|
||||
table = rvu->hw->table;
|
||||
promisc = table->promisc_mode[drop_mcam_idx];
|
||||
|
||||
cnt = &table->cnt_cmd_rules[drop_mcam_idx];
|
||||
old_cnt = *cnt;
|
||||
@@ -1179,16 +1177,13 @@ static u16 __rvu_npc_exact_cmd_rules_cnt_update(struct rvu *rvu, int drop_mcam_i
|
||||
|
||||
*enable_or_disable_cam = false;
|
||||
|
||||
if (promisc)
|
||||
goto done;
|
||||
|
||||
/* If all rules are deleted and not already in promisc mode; disable cam */
|
||||
/* If all rules are deleted, disable cam */
|
||||
if (!*cnt && val < 0) {
|
||||
*enable_or_disable_cam = true;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* If rule got added and not already in promisc mode; enable cam */
|
||||
/* If rule got added, enable cam */
|
||||
if (!old_cnt && val > 0) {
|
||||
*enable_or_disable_cam = true;
|
||||
goto done;
|
||||
@@ -1443,7 +1438,6 @@ int rvu_npc_exact_promisc_disable(struct rvu *rvu, u16 pcifunc)
|
||||
u32 drop_mcam_idx;
|
||||
bool *promisc;
|
||||
bool rc;
|
||||
u32 cnt;
|
||||
|
||||
table = rvu->hw->table;
|
||||
|
||||
@@ -1466,17 +1460,8 @@ int rvu_npc_exact_promisc_disable(struct rvu *rvu, u16 pcifunc)
|
||||
return LMAC_AF_ERR_INVALID_PARAM;
|
||||
}
|
||||
*promisc = false;
|
||||
cnt = __rvu_npc_exact_cmd_rules_cnt_update(rvu, drop_mcam_idx, 0, NULL);
|
||||
mutex_unlock(&table->lock);
|
||||
|
||||
/* If no dmac filter entries configured, disable drop rule */
|
||||
if (!cnt)
|
||||
rvu_npc_enable_mcam_by_entry_index(rvu, drop_mcam_idx, NIX_INTF_RX, false);
|
||||
else
|
||||
rvu_npc_enable_mcam_by_entry_index(rvu, drop_mcam_idx, NIX_INTF_RX, !*promisc);
|
||||
|
||||
dev_dbg(rvu->dev, "%s: disabled promisc mode (cgx=%d lmac=%d, cnt=%d)\n",
|
||||
__func__, cgx_id, lmac_id, cnt);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1494,7 +1479,6 @@ int rvu_npc_exact_promisc_enable(struct rvu *rvu, u16 pcifunc)
|
||||
u32 drop_mcam_idx;
|
||||
bool *promisc;
|
||||
bool rc;
|
||||
u32 cnt;
|
||||
|
||||
table = rvu->hw->table;
|
||||
|
||||
@@ -1517,17 +1501,8 @@ int rvu_npc_exact_promisc_enable(struct rvu *rvu, u16 pcifunc)
|
||||
return LMAC_AF_ERR_INVALID_PARAM;
|
||||
}
|
||||
*promisc = true;
|
||||
cnt = __rvu_npc_exact_cmd_rules_cnt_update(rvu, drop_mcam_idx, 0, NULL);
|
||||
mutex_unlock(&table->lock);
|
||||
|
||||
/* If no dmac filter entries configured, disable drop rule */
|
||||
if (!cnt)
|
||||
rvu_npc_enable_mcam_by_entry_index(rvu, drop_mcam_idx, NIX_INTF_RX, false);
|
||||
else
|
||||
rvu_npc_enable_mcam_by_entry_index(rvu, drop_mcam_idx, NIX_INTF_RX, !*promisc);
|
||||
|
||||
dev_dbg(rvu->dev, "%s: Enabled promisc mode (cgx=%d lmac=%d cnt=%d)\n",
|
||||
__func__, cgx_id, lmac_id, cnt);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -276,18 +276,6 @@ static inline bool mlx5_sriov_is_enabled(struct mlx5_core_dev *dev)
|
||||
return pci_num_vf(dev->pdev) ? true : false;
|
||||
}
|
||||
|
||||
static inline int mlx5_lag_is_lacp_owner(struct mlx5_core_dev *dev)
|
||||
{
|
||||
/* LACP owner conditions:
|
||||
* 1) Function is physical.
|
||||
* 2) LAG is supported by FW.
|
||||
* 3) LAG is managed by driver (currently the only option).
|
||||
*/
|
||||
return MLX5_CAP_GEN(dev, vport_group_manager) &&
|
||||
(MLX5_CAP_GEN(dev, num_lag_ports) > 1) &&
|
||||
MLX5_CAP_GEN(dev, lag_master);
|
||||
}
|
||||
|
||||
int mlx5_rescan_drivers_locked(struct mlx5_core_dev *dev);
|
||||
static inline int mlx5_rescan_drivers(struct mlx5_core_dev *dev)
|
||||
{
|
||||
|
||||
@@ -347,17 +347,6 @@ out:
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
static int rswitch_gwca_ts_queue_alloc(struct rswitch_private *priv)
|
||||
{
|
||||
struct rswitch_gwca_queue *gq = &priv->gwca.ts_queue;
|
||||
|
||||
gq->ring_size = TS_RING_SIZE;
|
||||
gq->ts_ring = dma_alloc_coherent(&priv->pdev->dev,
|
||||
sizeof(struct rswitch_ts_desc) *
|
||||
(gq->ring_size + 1), &gq->ring_dma, GFP_KERNEL);
|
||||
return !gq->ts_ring ? -ENOMEM : 0;
|
||||
}
|
||||
|
||||
static void rswitch_desc_set_dptr(struct rswitch_desc *desc, dma_addr_t addr)
|
||||
{
|
||||
desc->dptrl = cpu_to_le32(lower_32_bits(addr));
|
||||
@@ -533,6 +522,28 @@ static void rswitch_gwca_linkfix_free(struct rswitch_private *priv)
|
||||
gwca->linkfix_table = NULL;
|
||||
}
|
||||
|
||||
static int rswitch_gwca_ts_queue_alloc(struct rswitch_private *priv)
|
||||
{
|
||||
struct rswitch_gwca_queue *gq = &priv->gwca.ts_queue;
|
||||
struct rswitch_ts_desc *desc;
|
||||
|
||||
gq->ring_size = TS_RING_SIZE;
|
||||
gq->ts_ring = dma_alloc_coherent(&priv->pdev->dev,
|
||||
sizeof(struct rswitch_ts_desc) *
|
||||
(gq->ring_size + 1), &gq->ring_dma, GFP_KERNEL);
|
||||
|
||||
if (!gq->ts_ring)
|
||||
return -ENOMEM;
|
||||
|
||||
rswitch_gwca_ts_queue_fill(priv, 0, TS_RING_SIZE);
|
||||
desc = &gq->ts_ring[gq->ring_size];
|
||||
desc->desc.die_dt = DT_LINKFIX;
|
||||
rswitch_desc_set_dptr(&desc->desc, gq->ring_dma);
|
||||
INIT_LIST_HEAD(&priv->gwca.ts_info_list);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct rswitch_gwca_queue *rswitch_gwca_get(struct rswitch_private *priv)
|
||||
{
|
||||
struct rswitch_gwca_queue *gq;
|
||||
@@ -1780,9 +1791,6 @@ static int rswitch_init(struct rswitch_private *priv)
|
||||
if (err < 0)
|
||||
goto err_ts_queue_alloc;
|
||||
|
||||
rswitch_gwca_ts_queue_fill(priv, 0, TS_RING_SIZE);
|
||||
INIT_LIST_HEAD(&priv->gwca.ts_info_list);
|
||||
|
||||
for (i = 0; i < RSWITCH_NUM_PORTS; i++) {
|
||||
err = rswitch_device_alloc(priv, i);
|
||||
if (err < 0) {
|
||||
|
||||
@@ -301,6 +301,7 @@ int efx_probe_interrupts(struct efx_nic *efx)
|
||||
efx->tx_channel_offset = 0;
|
||||
efx->n_xdp_channels = 0;
|
||||
efx->xdp_channel_offset = efx->n_channels;
|
||||
efx->xdp_txq_queues_mode = EFX_XDP_TX_QUEUES_BORROWED;
|
||||
rc = pci_enable_msi(efx->pci_dev);
|
||||
if (rc == 0) {
|
||||
efx_get_channel(efx, 0)->irq = efx->pci_dev->irq;
|
||||
@@ -322,6 +323,7 @@ int efx_probe_interrupts(struct efx_nic *efx)
|
||||
efx->tx_channel_offset = efx_separate_tx_channels ? 1 : 0;
|
||||
efx->n_xdp_channels = 0;
|
||||
efx->xdp_channel_offset = efx->n_channels;
|
||||
efx->xdp_txq_queues_mode = EFX_XDP_TX_QUEUES_BORROWED;
|
||||
efx->legacy_irq = efx->pci_dev->irq;
|
||||
}
|
||||
|
||||
|
||||
@@ -302,6 +302,7 @@ int efx_siena_probe_interrupts(struct efx_nic *efx)
|
||||
efx->tx_channel_offset = 0;
|
||||
efx->n_xdp_channels = 0;
|
||||
efx->xdp_channel_offset = efx->n_channels;
|
||||
efx->xdp_txq_queues_mode = EFX_XDP_TX_QUEUES_BORROWED;
|
||||
rc = pci_enable_msi(efx->pci_dev);
|
||||
if (rc == 0) {
|
||||
efx_get_channel(efx, 0)->irq = efx->pci_dev->irq;
|
||||
@@ -323,6 +324,7 @@ int efx_siena_probe_interrupts(struct efx_nic *efx)
|
||||
efx->tx_channel_offset = efx_siena_separate_tx_channels ? 1 : 0;
|
||||
efx->n_xdp_channels = 0;
|
||||
efx->xdp_channel_offset = efx->n_channels;
|
||||
efx->xdp_txq_queues_mode = EFX_XDP_TX_QUEUES_BORROWED;
|
||||
efx->legacy_irq = efx->pci_dev->irq;
|
||||
}
|
||||
|
||||
|
||||
@@ -3873,7 +3873,6 @@ irq_error:
|
||||
|
||||
stmmac_hw_teardown(dev);
|
||||
init_error:
|
||||
free_dma_desc_resources(priv, &priv->dma_conf);
|
||||
phylink_disconnect_phy(priv->phylink);
|
||||
init_phy_error:
|
||||
pm_runtime_put(priv->device);
|
||||
@@ -3891,6 +3890,9 @@ static int stmmac_open(struct net_device *dev)
|
||||
return PTR_ERR(dma_conf);
|
||||
|
||||
ret = __stmmac_open(dev, dma_conf);
|
||||
if (ret)
|
||||
free_dma_desc_resources(priv, dma_conf);
|
||||
|
||||
kfree(dma_conf);
|
||||
return ret;
|
||||
}
|
||||
@@ -5633,12 +5635,15 @@ static int stmmac_change_mtu(struct net_device *dev, int new_mtu)
|
||||
stmmac_release(dev);
|
||||
|
||||
ret = __stmmac_open(dev, dma_conf);
|
||||
kfree(dma_conf);
|
||||
if (ret) {
|
||||
free_dma_desc_resources(priv, dma_conf);
|
||||
kfree(dma_conf);
|
||||
netdev_err(priv->dev, "failed reopening the interface after MTU change\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
kfree(dma_conf);
|
||||
|
||||
stmmac_set_rx_mode(dev);
|
||||
}
|
||||
|
||||
|
||||
@@ -2068,7 +2068,7 @@ static int am65_cpsw_nuss_init_slave_ports(struct am65_cpsw_common *common)
|
||||
/* Initialize the Serdes PHY for the port */
|
||||
ret = am65_cpsw_init_serdes_phy(dev, port_np, port);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto of_node_put;
|
||||
|
||||
port->slave.mac_only =
|
||||
of_property_read_bool(port_np, "ti,mac-only");
|
||||
|
||||
@@ -102,6 +102,10 @@ static unsigned int ipvlan_nf_input(void *priv, struct sk_buff *skb,
|
||||
|
||||
skb->dev = addr->master->dev;
|
||||
skb->skb_iif = skb->dev->ifindex;
|
||||
#if IS_ENABLED(CONFIG_IPV6)
|
||||
if (addr->atype == IPVL_IPV6)
|
||||
IP6CB(skb)->iif = skb->dev->ifindex;
|
||||
#endif
|
||||
len = skb->len + ETH_HLEN;
|
||||
ipvlan_count_rx(addr->master, len, true, false);
|
||||
out:
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user