* Re: [PATCH] perf/rapl: restart perf rapl counter after resume
From: Peter Zijlstra @ 2019-06-20 12:50 UTC (permalink / raw)
To: Zhang Rui
Cc: linux-x86, LKML, mingo, acme, alexander.shishkin, jolsa, namhyung,
tglx, Liang, Kan
In-Reply-To: <1560778897.10723.6.camel@intel.com>
On Mon, Jun 17, 2019 at 09:41:37PM +0800, Zhang Rui wrote:
> After S3 suspend/resume, "perf stat -I 1000 -e power/energy-pkg/ -a"
> reports an insane value for the very first sampling period after resume
> as shown below.
>
> 19.278989977 2.16 Joules power/energy-pkg/
> 20.279373569 1.96 Joules power/energy-pkg/
> 21.279765481 2.09 Joules power/energy-pkg/
> 22.280305420 2.10 Joules power/energy-pkg/
> 25.504782277 4,294,966,686.01 Joules power/energy-pkg/
> 26.505114993 3.58 Joules power/energy-pkg/
> 27.505471758 1.66 Joules power/energy-pkg/
>
> Fix this by resetting the counter right after resume.
Cute...
> +#ifdef CONFIG_PM
> +
> +static int perf_rapl_suspend(void)
> +{
> + int i;
> +
> + get_online_cpus();
> + for (i = 0; i < rapl_pmus->maxpkg; i++)
> + rapl_pmu_update_all(rapl_pmus->pmus[i]);
> + put_online_cpus();
> + return 0;
> +}
> +
> +static void perf_rapl_resume(void)
> +{
> + int i;
> +
> + get_online_cpus();
> + for (i = 0; i < rapl_pmus->maxpkg; i++)
> + rapl_pmu_restart_all(rapl_pmus->pmus[i]);
> + put_online_cpus();
> +}
What's the reason for that get/put_online_cpus() here ?
^ permalink raw reply
* [PATCH v2 2/3] kernel/notifier.c: remove notifier_chain_cond_register()
From: Xiaoming Ni @ 2019-06-20 12:48 UTC (permalink / raw)
To: trond.myklebust, anna.schumaker, bfields, jlayton, davem,
semen.protsenko, akpm, gregkh, vvs, tglx
Cc: nixiaoming, dylix.dailei, alex.huangjianhui, adobriyan, mingo,
viresh.kumar, luto, arjan, Nadia.Derbey, torvalds, stern, paulmck,
linux-kernel, linux-nfs, netdev, stable
In-Reply-To: <1561034914-106990-1-git-send-email-nixiaoming@huawei.com>
The only difference between notifier_chain_cond_register() and
notifier_chain_register() is the lack of warning hints for duplicate
registrations.
Consider using notifier_chain_register() instead of
notifier_chain_cond_register() to avoid duplicate code
Signed-off-by: Xiaoming Ni <nixiaoming@huawei.com>
---
kernel/notifier.c | 17 +----------------
1 file changed, 1 insertion(+), 16 deletions(-)
diff --git a/kernel/notifier.c b/kernel/notifier.c
index 30bedb8..e3d221f 100644
--- a/kernel/notifier.c
+++ b/kernel/notifier.c
@@ -36,21 +36,6 @@ static int notifier_chain_register(struct notifier_block **nl,
return 0;
}
-static int notifier_chain_cond_register(struct notifier_block **nl,
- struct notifier_block *n)
-{
- while ((*nl) != NULL) {
- if ((*nl) == n)
- return 0;
- if (n->priority > (*nl)->priority)
- break;
- nl = &((*nl)->next);
- }
- n->next = *nl;
- rcu_assign_pointer(*nl, n);
- return 0;
-}
-
static int notifier_chain_unregister(struct notifier_block **nl,
struct notifier_block *n)
{
@@ -252,7 +237,7 @@ int blocking_notifier_chain_cond_register(struct blocking_notifier_head *nh,
int ret;
down_write(&nh->rwsem);
- ret = notifier_chain_cond_register(&nh->head, n);
+ ret = notifier_chain_register(&nh->head, n);
up_write(&nh->rwsem);
return ret;
}
--
1.8.5.6
^ permalink raw reply related
* [PATCH v2 1/3] kernel/notifier.c: avoid duplicate registration
From: Xiaoming Ni @ 2019-06-20 12:48 UTC (permalink / raw)
To: trond.myklebust, anna.schumaker, bfields, jlayton, davem,
semen.protsenko, akpm, gregkh, vvs, tglx
Cc: nixiaoming, dylix.dailei, alex.huangjianhui, adobriyan, mingo,
viresh.kumar, luto, arjan, Nadia.Derbey, torvalds, stern, paulmck,
linux-kernel, linux-nfs, netdev, stable
Registering the same notifier to a hook repeatedly can cause the hook
list to form a ring or lose other members of the list.
case1: An infinite loop in notifier_chain_register() can cause soft lockup
atomic_notifier_chain_register(&test_notifier_list, &test1);
atomic_notifier_chain_register(&test_notifier_list, &test1);
atomic_notifier_chain_register(&test_notifier_list, &test2);
case2: An infinite loop in notifier_chain_register() can cause soft lockup
atomic_notifier_chain_register(&test_notifier_list, &test1);
atomic_notifier_chain_register(&test_notifier_list, &test1);
atomic_notifier_call_chain(&test_notifier_list, 0, NULL);
case3: lose other hook test2
atomic_notifier_chain_register(&test_notifier_list, &test1);
atomic_notifier_chain_register(&test_notifier_list, &test2);
atomic_notifier_chain_register(&test_notifier_list, &test1);
case4: Unregister returns 0, but the hook is still in the linked list,
and it is not really registered. If you call notifier_call_chain
after ko is unloaded, it will trigger oops.
If the system is configured with softlockup_panic and the same
hook is repeatedly registered on the panic_notifier_list, it
will cause a loop panic.
Add a check in notifier_chain_register() to avoid duplicate registration
Signed-off-by: Xiaoming Ni <nixiaoming@huawei.com>
---
kernel/notifier.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/kernel/notifier.c b/kernel/notifier.c
index d9f5081..30bedb8 100644
--- a/kernel/notifier.c
+++ b/kernel/notifier.c
@@ -23,7 +23,10 @@ static int notifier_chain_register(struct notifier_block **nl,
struct notifier_block *n)
{
while ((*nl) != NULL) {
- WARN_ONCE(((*nl) == n), "double register detected");
+ if (unlikely((*nl) == n)) {
+ WARN(1, "double register detected");
+ return 0;
+ }
if (n->priority > (*nl)->priority)
break;
nl = &((*nl)->next);
--
1.8.5.6
^ permalink raw reply related
* [PATCH v2 3/3] kernel/notifier.c: remove blocking_notifier_chain_cond_register()
From: Xiaoming Ni @ 2019-06-20 12:48 UTC (permalink / raw)
To: trond.myklebust, anna.schumaker, bfields, jlayton, davem,
semen.protsenko, akpm, gregkh, vvs, tglx
Cc: nixiaoming, dylix.dailei, alex.huangjianhui, adobriyan, mingo,
viresh.kumar, luto, arjan, Nadia.Derbey, torvalds, stern, paulmck,
linux-kernel, linux-nfs, netdev, stable
In-Reply-To: <1561034914-106990-1-git-send-email-nixiaoming@huawei.com>
blocking_notifier_chain_cond_register() does not consider
system_booting state, which is the only difference between this
function and blocking_notifier_cain_register(). This can be a bug
and is a piece of duplicate code.
Delete blocking_notifier_chain_cond_register()
Signed-off-by: Xiaoming Ni <nixiaoming@huawei.com>
---
include/linux/notifier.h | 4 ----
kernel/notifier.c | 23 -----------------------
net/sunrpc/rpc_pipe.c | 2 +-
3 files changed, 1 insertion(+), 28 deletions(-)
diff --git a/include/linux/notifier.h b/include/linux/notifier.h
index 0096a05..0189476 100644
--- a/include/linux/notifier.h
+++ b/include/linux/notifier.h
@@ -150,10 +150,6 @@ extern int raw_notifier_chain_register(struct raw_notifier_head *nh,
extern int srcu_notifier_chain_register(struct srcu_notifier_head *nh,
struct notifier_block *nb);
-extern int blocking_notifier_chain_cond_register(
- struct blocking_notifier_head *nh,
- struct notifier_block *nb);
-
extern int atomic_notifier_chain_unregister(struct atomic_notifier_head *nh,
struct notifier_block *nb);
extern int blocking_notifier_chain_unregister(struct blocking_notifier_head *nh,
diff --git a/kernel/notifier.c b/kernel/notifier.c
index e3d221f..63d7501 100644
--- a/kernel/notifier.c
+++ b/kernel/notifier.c
@@ -221,29 +221,6 @@ int blocking_notifier_chain_register(struct blocking_notifier_head *nh,
EXPORT_SYMBOL_GPL(blocking_notifier_chain_register);
/**
- * blocking_notifier_chain_cond_register - Cond add notifier to a blocking notifier chain
- * @nh: Pointer to head of the blocking notifier chain
- * @n: New entry in notifier chain
- *
- * Adds a notifier to a blocking notifier chain, only if not already
- * present in the chain.
- * Must be called in process context.
- *
- * Currently always returns zero.
- */
-int blocking_notifier_chain_cond_register(struct blocking_notifier_head *nh,
- struct notifier_block *n)
-{
- int ret;
-
- down_write(&nh->rwsem);
- ret = notifier_chain_register(&nh->head, n);
- up_write(&nh->rwsem);
- return ret;
-}
-EXPORT_SYMBOL_GPL(blocking_notifier_chain_cond_register);
-
-/**
* blocking_notifier_chain_unregister - Remove notifier from a blocking notifier chain
* @nh: Pointer to head of the blocking notifier chain
* @n: Entry to remove from notifier chain
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c
index 126d314..1287f80 100644
--- a/net/sunrpc/rpc_pipe.c
+++ b/net/sunrpc/rpc_pipe.c
@@ -50,7 +50,7 @@
int rpc_pipefs_notifier_register(struct notifier_block *nb)
{
- return blocking_notifier_chain_cond_register(&rpc_pipefs_notifier_list, nb);
+ return blocking_notifier_chain_register(&rpc_pipefs_notifier_list, nb);
}
EXPORT_SYMBOL_GPL(rpc_pipefs_notifier_register);
--
1.8.5.6
^ permalink raw reply related
* [Qemu-devel] [PATCH v5 2/3] hw/i386: Use edk2_add_host_crypto_policy()
From: Philippe Mathieu-Daudé @ 2019-06-20 12:21 UTC (permalink / raw)
To: qemu-devel, Laszlo Ersek
Cc: Peter Maydell, Andrew Jones, Eduardo Habkost, Michael S. Tsirkin,
Markus Armbruster, qemu-arm, Paolo Bonzini,
Philippe Mathieu-Daudé, Richard Henderson
In-Reply-To: <20190620122132.10075-1-philmd@redhat.com>
Enable the EDK2 Crypto Policy features on the PC machine.
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
---
hw/i386/pc.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 2c5446b095..fe99ebfe3d 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -39,6 +39,7 @@
#include "hw/nvram/fw_cfg.h"
#include "hw/timer/hpet.h"
#include "hw/firmware/smbios.h"
+#include "hw/firmware/uefi_edk2.h"
#include "hw/loader.h"
#include "elf.h"
#include "multiboot.h"
@@ -1049,6 +1050,11 @@ static FWCfgState *bochs_bios_init(AddressSpace *as, PCMachineState *pcms)
return fw_cfg;
}
+static void pc_uefi_setup(PCMachineState *pcms)
+{
+ edk2_add_host_crypto_policy(pcms->fw_cfg);
+}
+
static long get_file_size(FILE *f)
{
long where, size;
@@ -1653,6 +1659,7 @@ void pc_machine_done(Notifier *notifier, void *data)
if (pcms->fw_cfg) {
pc_build_smbios(pcms);
pc_build_feature_control_file(pcms);
+ pc_uefi_setup(pcms);
/* update FW_CFG_NB_CPUS to account for -device added CPUs */
fw_cfg_modify_i16(pcms->fw_cfg, FW_CFG_NB_CPUS, pcms->boot_cpus);
}
--
2.20.1
^ permalink raw reply related
* [Qemu-devel] [PATCH v5 1/3] hw/firmware: Add Edk2Crypto and edk2_add_host_crypto_policy()
From: Philippe Mathieu-Daudé @ 2019-06-20 12:21 UTC (permalink / raw)
To: qemu-devel, Laszlo Ersek
Cc: Peter Maydell, Andrew Jones, Eduardo Habkost, Michael S. Tsirkin,
qemu-arm, Paolo Bonzini, Philippe Mathieu-Daudé
In-Reply-To: <20190620122132.10075-1-philmd@redhat.com>
The Edk2Crypto object is used to hold configuration values specific
to EDK2.
The edk2_add_host_crypto_policy() function loads crypto policies
from the host, and register them as fw_cfg named file items.
So far only the 'https' policy is supported.
A usercase example is the 'HTTPS Boof' feature of OVMF [*].
Usage example:
- via the command line:
$ qemu-system-x86_64 \
--object edk2_crypto,id=https,\
ciphers=/etc/crypto-policies/back-ends/openssl.config,\
cacerts=/etc/pki/ca-trust/extracted/edk2/cacerts.bin
- via QMP:
{
"execute": "object-add",
"arguments": {
"qom-type": "edk2_crypto",
"id": "https",
"props": {
"ciphers": "/etc/crypto-policies/back-ends/openssl.config",
"cacerts": "/etc/pki/ca-trust/extracted/edk2/cacerts.bin"
}
}
}
(On Fedora these files are provided by the ca-certificates and
crypto-policies packages).
[*]: https://github.com/tianocore/edk2/blob/master/OvmfPkg/README
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
---
v3:
- inverted the if() logic
- '-object' -> '--object' in commit description (Eric)
- reworded the 'TODO: g_free' comment
v4:
- do not return pointer to alloc'd data (Markus)
- INTERFACE_CHECK -> OBJECT_CLASS_CHECK (Markus)
- path -> filename (Laszlo)
- dropped the 'TODO: g_free' comment (Markus)
v5:
- only allow 1 singleton using the UserCreatableClass::complete
callback (Markus, Laszlo)
- object own fw_cfg 'file' content, no need for
fw_cfg_add_file_from_host() (Laszlo)
- g_file_get_contents() called when object is instantiated
and report error, the machine 'done' notifier do not have
to manage errors (do not fail).
- add QMP example
-
- do not add docs/interop/firmware.json to MAINTAINERS
---
MAINTAINERS | 2 +
hw/Makefile.objs | 1 +
hw/firmware/Makefile.objs | 1 +
hw/firmware/uefi_edk2_crypto_policies.c | 209 ++++++++++++++++++++++++
include/hw/firmware/uefi_edk2.h | 30 ++++
5 files changed, 243 insertions(+)
create mode 100644 hw/firmware/Makefile.objs
create mode 100644 hw/firmware/uefi_edk2_crypto_policies.c
create mode 100644 include/hw/firmware/uefi_edk2.h
diff --git a/MAINTAINERS b/MAINTAINERS
index d32c5c2313..28de489134 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2262,6 +2262,8 @@ EDK2 Firmware
M: Laszlo Ersek <lersek@redhat.com>
M: Philippe Mathieu-Daudé <philmd@redhat.com>
S: Supported
+F: hw/firmware/uefi_edk2_crypto_policies.c
+F: include/hw/firmware/uefi_edk2.h
F: pc-bios/descriptors/??-edk2-*.json
F: pc-bios/edk2-*
F: roms/Makefile.edk2
diff --git a/hw/Makefile.objs b/hw/Makefile.objs
index d770926ba9..c13b6ee0dd 100644
--- a/hw/Makefile.objs
+++ b/hw/Makefile.objs
@@ -8,6 +8,7 @@ devices-dirs-$(CONFIG_SOFTMMU) += char/
devices-dirs-$(CONFIG_SOFTMMU) += cpu/
devices-dirs-$(CONFIG_SOFTMMU) += display/
devices-dirs-$(CONFIG_SOFTMMU) += dma/
+devices-dirs-$(CONFIG_SOFTMMU) += firmware/
devices-dirs-$(CONFIG_SOFTMMU) += gpio/
devices-dirs-$(CONFIG_HYPERV) += hyperv/
devices-dirs-$(CONFIG_I2C) += i2c/
diff --git a/hw/firmware/Makefile.objs b/hw/firmware/Makefile.objs
new file mode 100644
index 0000000000..ea1f6d44df
--- /dev/null
+++ b/hw/firmware/Makefile.objs
@@ -0,0 +1 @@
+common-obj-y += uefi_edk2_crypto_policies.o
diff --git a/hw/firmware/uefi_edk2_crypto_policies.c b/hw/firmware/uefi_edk2_crypto_policies.c
new file mode 100644
index 0000000000..a0164272ea
--- /dev/null
+++ b/hw/firmware/uefi_edk2_crypto_policies.c
@@ -0,0 +1,209 @@
+/*
+ * UEFI EDK2 Support
+ *
+ * Copyright (c) 2019 Red Hat Inc.
+ *
+ * Author:
+ * Philippe Mathieu-Daudé <philmd@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "qom/object_interfaces.h"
+#include "hw/firmware/uefi_edk2.h"
+
+
+#define TYPE_EDK2_CRYPTO "edk2_crypto"
+
+#define EDK2_CRYPTO_CLASS(klass) \
+ OBJECT_CLASS_CHECK(Edk2CryptoClass, (klass), \
+ TYPE_EDK2_CRYPTO)
+#define EDK2_CRYPTO_GET_CLASS(obj) \
+ OBJECT_GET_CLASS(Edk2CryptoClass, (obj), \
+ TYPE_EDK2_CRYPTO)
+#define EDK2_CRYPTO(obj) \
+ OBJECT_CHECK(Edk2Crypto, (obj), \
+ TYPE_EDK2_CRYPTO)
+
+typedef struct FWCfgHostContent {
+ /*
+ * Path to the acceptable ciphersuites and the preferred order from
+ * the host-side crypto policy.
+ */
+ char *filename;
+ /*
+ * Add a new NAMED fw_cfg item as a raw "blob" of the given size. The data
+ * referenced by the starting pointer is only linked, NOT copied, into the
+ * data structure of the fw_cfg device.
+ */
+ char *contents;
+
+ size_t contents_length;
+} FWCfgHostContent;
+
+typedef struct Edk2Crypto {
+ Object parent_obj;
+
+ /*
+ * Path to the acceptable ciphersuites and the preferred order from
+ * the host-side crypto policy.
+ */
+ FWCfgHostContent ciphers;
+ /* Path to the trusted CA certificates configured on the host side. */
+ FWCfgHostContent cacerts;
+} Edk2Crypto;
+
+typedef struct Edk2CryptoClass {
+ ObjectClass parent_class;
+} Edk2CryptoClass;
+
+static Edk2Crypto *edk2_crypto_by_policy_id(const char *policy_id, Error **errp)
+{
+ Object *obj;
+
+ obj = object_resolve_path_component(object_get_objects_root(), policy_id);
+ if (!obj) {
+ error_setg(errp, "Cannot find EDK2 crypto policy ID %s", policy_id);
+ return NULL;
+ }
+
+ if (!object_dynamic_cast(obj, TYPE_EDK2_CRYPTO)) {
+ error_setg(errp, "Object '%s' is not a EDK2 crypto subclass",
+ policy_id);
+ return NULL;
+ }
+
+ return EDK2_CRYPTO(obj);
+}
+
+static void edk2_crypto_prop_set_ciphers(Object *obj, const char *value,
+ Error **errp G_GNUC_UNUSED)
+{
+ Edk2Crypto *s = EDK2_CRYPTO(obj);
+
+ g_free(s->ciphers.filename);
+ s->ciphers.filename = g_strdup(value);
+}
+
+static char *edk2_crypto_prop_get_ciphers(Object *obj,
+ Error **errp G_GNUC_UNUSED)
+{
+ Edk2Crypto *s = EDK2_CRYPTO(obj);
+
+ return g_strdup(s->ciphers.filename);
+}
+
+static void edk2_crypto_prop_set_cacerts(Object *obj, const char *value,
+ Error **errp G_GNUC_UNUSED)
+{
+ Edk2Crypto *s = EDK2_CRYPTO(obj);
+
+ g_free(s->cacerts.filename);
+ s->cacerts.filename = g_strdup(value);
+}
+
+static char *edk2_crypto_prop_get_cacerts(Object *obj,
+ Error **errp G_GNUC_UNUSED)
+{
+ Edk2Crypto *s = EDK2_CRYPTO(obj);
+
+ return g_strdup(s->cacerts.filename);
+}
+
+static void edk2_crypto_complete(UserCreatable *uc, Error **errp)
+{
+ Edk2Crypto *s = EDK2_CRYPTO(uc);
+ Error *local_err = NULL;
+ GError *gerr = NULL;
+
+ if (s->ciphers.filename) {
+ if (!g_file_get_contents(s->ciphers.filename, &s->ciphers.contents,
+ &s->ciphers.contents_length, &gerr)) {
+ goto report_error;
+ }
+ }
+ if (s->cacerts.filename) {
+ if (!g_file_get_contents(s->cacerts.filename, &s->cacerts.contents,
+ &s->cacerts.contents_length, &gerr)) {
+ goto report_error;
+ }
+ }
+ return;
+
+ report_error:
+ error_setg(&local_err, "%s", gerr->message);
+ g_error_free(gerr);
+ error_propagate_prepend(errp, local_err, "EDK2 crypto policy: ");
+}
+
+static void edk2_crypto_finalize(Object *obj)
+{
+ Edk2Crypto *s = EDK2_CRYPTO(obj);
+
+ g_free(s->ciphers.filename);
+ g_free(s->ciphers.contents);
+ g_free(s->cacerts.filename);
+ g_free(s->cacerts.contents);
+}
+
+static void edk2_crypto_class_init(ObjectClass *oc, void *data)
+{
+ UserCreatableClass *ucc = USER_CREATABLE_CLASS(oc);
+
+ ucc->complete = edk2_crypto_complete;
+
+ object_class_property_add_str(oc, "ciphers",
+ edk2_crypto_prop_get_ciphers,
+ edk2_crypto_prop_set_ciphers,
+ NULL);
+ object_class_property_add_str(oc, "cacerts",
+ edk2_crypto_prop_get_cacerts,
+ edk2_crypto_prop_set_cacerts,
+ NULL);
+}
+
+static const TypeInfo edk2_crypto_info = {
+ .parent = TYPE_OBJECT,
+ .name = TYPE_EDK2_CRYPTO,
+ .instance_size = sizeof(Edk2Crypto),
+ .instance_finalize = edk2_crypto_finalize,
+ .class_size = sizeof(Edk2CryptoClass),
+ .class_init = edk2_crypto_class_init,
+ .interfaces = (InterfaceInfo[]) {
+ { TYPE_USER_CREATABLE },
+ { }
+ }
+};
+
+static void edk2_crypto_register_types(void)
+{
+ type_register_static(&edk2_crypto_info);
+}
+
+type_init(edk2_crypto_register_types);
+
+static void edk2_add_host_crypto_policy_https(FWCfgState *fw_cfg)
+{
+ Edk2Crypto *s;
+
+ s = edk2_crypto_by_policy_id("https", NULL);
+ if (!s) {
+ return;
+ }
+ if (s->ciphers.contents_length) {
+ fw_cfg_add_file(fw_cfg, "etc/edk2/https/ciphers",
+ s->ciphers.contents, s->ciphers.contents_length);
+ }
+ if (s->cacerts.contents_length) {
+ fw_cfg_add_file(fw_cfg, "etc/edk2/https/cacerts",
+ s->cacerts.contents, s->cacerts.contents_length);
+ }
+}
+
+void edk2_add_host_crypto_policy(FWCfgState *fw_cfg)
+{
+ edk2_add_host_crypto_policy_https(fw_cfg);
+}
diff --git a/include/hw/firmware/uefi_edk2.h b/include/hw/firmware/uefi_edk2.h
new file mode 100644
index 0000000000..f8f81c5cb2
--- /dev/null
+++ b/include/hw/firmware/uefi_edk2.h
@@ -0,0 +1,30 @@
+/*
+ * UEFI EDK2 Support
+ *
+ * Copyright (c) 2019 Red Hat Inc.
+ *
+ * Author:
+ * Philippe Mathieu-Daudé <philmd@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef HW_FIRMWARE_UEFI_EDK2_H
+#define HW_FIRMWARE_UEFI_EDK2_H
+
+#include "hw/nvram/fw_cfg.h"
+
+/**
+ * edk2_add_host_crypto_policy:
+ * @fw_cfg: fw_cfg device being modified
+ *
+ * Add a new named file containing the host crypto policy.
+ *
+ * This method is called by the machine_done() Notifier of
+ * some implementations of MachineState, currently the X86
+ * PCMachineState and the ARM VirtMachineState.
+ */
+void edk2_add_host_crypto_policy(FWCfgState *fw_cfg);
+
+#endif /* HW_FIRMWARE_UEFI_EDK2_H */
--
2.20.1
^ permalink raw reply related
* Re: cifs: Fix tracing build error with O=
From: Herbert Xu @ 2019-06-20 12:47 UTC (permalink / raw)
To: Masahiro Yamada
Cc: stfrench, linux-cifs, Linux Kernel Mailing List,
Christoph Hellwig
In-Reply-To: <CAK7LNATbMou4DHN9=POay4RGT6upj1RoUZPwfvaB7oZwqm5rfA@mail.gmail.com>
On Thu, Jun 20, 2019 at 08:56:10PM +0900, Masahiro Yamada wrote:
>
> The similar question, and the answer is here:
> https://lkml.org/lkml/2019/1/17/584
But it doesn't work with O=:
$ rm -rf build-compile/fs/cifs
$ make O=build-compile fs/cifs
make[1]: Entering directory '/home/herbert/src/build/kernel/test/build-compile'
make[1]: Nothing to be done for '../fs/cifs'.
make[1]: Leaving directory '/home/herbert/src/build/kernel/test/build-compile'
$
Cheers,
--
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply
* kernel BUG at ./include/linux/scatterlist.h:LINE!
From: syzbot @ 2019-06-20 12:47 UTC (permalink / raw)
To: ast, aviadye, borisp, bpf, daniel, davejwatson, davem,
john.fastabend, kafai, linux-kernel, netdev, songliubraving,
syzkaller-bugs, vakul.garg, yhs
Hello,
syzbot found the following crash on:
HEAD commit: bed3c0d8 Merge tag 'for-5.2-rc5-tag' of git://git.kernel.o..
git tree: upstream
console output: https://syzkaller.appspot.com/x/log.txt?x=138d485ea00000
kernel config: https://syzkaller.appspot.com/x/.config?x=28ec3437a5394ee0
dashboard link: https://syzkaller.appspot.com/bug?extid=ef0daa6ce95facb233c1
compiler: clang version 9.0.0 (/home/glider/llvm/clang
80fee25776c2fb61e74c1ecb1a523375c2500b69)
syz repro: https://syzkaller.appspot.com/x/repro.syz?x=13175731a00000
C reproducer: https://syzkaller.appspot.com/x/repro.c?x=126947faa00000
The bug was bisected to:
commit f295b3ae9f5927e084bd5decdff82390e3471801
Author: Vakul Garg <vakul.garg@nxp.com>
Date: Wed Mar 20 02:03:36 2019 +0000
net/tls: Add support of AES128-CCM based ciphers
bisection log: https://syzkaller.appspot.com/x/bisect.txt?x=1738b732a00000
final crash: https://syzkaller.appspot.com/x/report.txt?x=14b8b732a00000
console output: https://syzkaller.appspot.com/x/log.txt?x=10b8b732a00000
IMPORTANT: if you fix the bug, please add the following tag to the commit:
Reported-by: syzbot+ef0daa6ce95facb233c1@syzkaller.appspotmail.com
Fixes: f295b3ae9f59 ("net/tls: Add support of AES128-CCM based ciphers")
RAX: ffffffffffffffda RBX: 00007ffd6d3365b0 RCX: 0000000000441ba9
RDX: 0000000000000004 RSI: 0000000000000000 RDI: 0000000000000003
RBP: 0000000000000000 R08: 0000000100000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: ffffffffffffffff
R13: 0000000000000005 R14: 0000000000000000 R15: 0000000000000000
------------[ cut here ]------------
kernel BUG at ./include/linux/scatterlist.h:97!
invalid opcode: 0000 [#1] PREEMPT SMP KASAN
CPU: 1 PID: 8023 Comm: syz-executor694 Not tainted 5.2.0-rc5+ #3
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS
Google 01/01/2011
RIP: 0010:sg_assign_page include/linux/scatterlist.h:97 [inline]
RIP: 0010:sg_set_page include/linux/scatterlist.h:119 [inline]
RIP: 0010:sk_msg_page_add include/linux/skmsg.h:246 [inline]
RIP: 0010:tls_sw_do_sendpage net/tls/tls_sw.c:1170 [inline]
RIP: 0010:tls_sw_sendpage+0x11b5/0x11e0 net/tls/tls_sw.c:1229
Code: c1 38 c1 0f 8c 12 fe ff ff 4c 89 f7 e8 14 bb 27 fb e9 05 fe ff ff e8
0a 92 ee fa 44 8b 7c 24 18 e9 b2 fe ff ff e8 fb 91 ee fa <0f> 0b e8 f4 91
ee fa 0f 0b e8 ed 91 ee fa 4c 89 f7 48 c7 c6 87 e5
RSP: 0018:ffff888094adf7c0 EFLAGS: 00010293
RAX: ffffffff86871ff5 RBX: 0000000000000001 RCX: ffff888095bfc300
RDX: 0000000000000000 RSI: 0000000000000001 RDI: 0000000000000000
RBP: ffff888094adf998 R08: ffffffff8687170c R09: fffff9400045851f
R10: fffff9400045851f R11: 1ffffd400045851e R12: 0000000000000000
R13: 0000000000000080 R14: ffffea00022c28c0 R15: 1ffff110124d0d01
FS: 0000555556a2f880(0000) GS:ffff8880aeb00000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007ffc5c9d1f18 CR3: 00000000a8a2c000 CR4: 00000000001406e0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
Call Trace:
inet_sendpage+0x16d/0x340 net/ipv4/af_inet.c:815
kernel_sendpage net/socket.c:3642 [inline]
sock_sendpage+0xd3/0x120 net/socket.c:940
pipe_to_sendpage+0x23e/0x310 fs/splice.c:449
splice_from_pipe_feed fs/splice.c:500 [inline]
__splice_from_pipe+0x2f7/0x8a0 fs/splice.c:624
splice_from_pipe fs/splice.c:659 [inline]
generic_splice_sendpage+0x172/0x200 fs/splice.c:829
do_splice_from fs/splice.c:848 [inline]
do_splice fs/splice.c:1155 [inline]
__do_sys_splice fs/splice.c:1425 [inline]
__se_sys_splice+0x12ec/0x1db0 fs/splice.c:1405
__x64_sys_splice+0xe5/0x100 fs/splice.c:1405
do_syscall_64+0xfe/0x140 arch/x86/entry/common.c:301
entry_SYSCALL_64_after_hwframe+0x49/0xbe
RIP: 0033:0x441ba9
Code: 18 89 d0 c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 00 48 89 f8 48 89 f7
48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff
ff 0f 83 bb 10 fc ff c3 66 2e 0f 1f 84 00 00 00 00
RSP: 002b:00007ffd6d336548 EFLAGS: 00000246 ORIG_RAX: 0000000000000113
RAX: ffffffffffffffda RBX: 00007ffd6d3365b0 RCX: 0000000000441ba9
RDX: 0000000000000004 RSI: 0000000000000000 RDI: 0000000000000003
RBP: 0000000000000000 R08: 0000000100000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: ffffffffffffffff
R13: 0000000000000005 R14: 0000000000000000 R15: 0000000000000000
Modules linked in:
---[ end trace 3b5328faabff785c ]---
RIP: 0010:sg_assign_page include/linux/scatterlist.h:97 [inline]
RIP: 0010:sg_set_page include/linux/scatterlist.h:119 [inline]
RIP: 0010:sk_msg_page_add include/linux/skmsg.h:246 [inline]
RIP: 0010:tls_sw_do_sendpage net/tls/tls_sw.c:1170 [inline]
RIP: 0010:tls_sw_sendpage+0x11b5/0x11e0 net/tls/tls_sw.c:1229
Code: c1 38 c1 0f 8c 12 fe ff ff 4c 89 f7 e8 14 bb 27 fb e9 05 fe ff ff e8
0a 92 ee fa 44 8b 7c 24 18 e9 b2 fe ff ff e8 fb 91 ee fa <0f> 0b e8 f4 91
ee fa 0f 0b e8 ed 91 ee fa 4c 89 f7 48 c7 c6 87 e5
RSP: 0018:ffff888094adf7c0 EFLAGS: 00010293
RAX: ffffffff86871ff5 RBX: 0000000000000001 RCX: ffff888095bfc300
RDX: 0000000000000000 RSI: 0000000000000001 RDI: 0000000000000000
RBP: ffff888094adf998 R08: ffffffff8687170c R09: fffff9400045851f
R10: fffff9400045851f R11: 1ffffd400045851e R12: 0000000000000000
R13: 0000000000000080 R14: ffffea00022c28c0 R15: 1ffff110124d0d01
FS: 0000555556a2f880(0000) GS:ffff8880aeb00000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007ffc5c9d1f18 CR3: 00000000a8a2c000 CR4: 00000000001406e0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
---
This bug is generated by a bot. It may contain errors.
See https://goo.gl/tpsmEJ for more information about syzbot.
syzbot engineers can be reached at syzkaller@googlegroups.com.
syzbot will keep track of this bug report. See:
https://goo.gl/tpsmEJ#status for how to communicate with syzbot.
For information about bisection process see: https://goo.gl/tpsmEJ#bisection
syzbot can test patches for this bug, for details see:
https://goo.gl/tpsmEJ#testing-patches
^ permalink raw reply
* [PATCH] drm/prime: Update docs
From: Daniel Vetter @ 2019-06-20 12:46 UTC (permalink / raw)
To: DRI Development
Cc: Daniel Vetter, Intel Graphics Development, Emil Velikov,
Gerd Hoffmann, Thomas Zimmermann, Daniel Vetter, Sam Ravnborg,
Emil Velikov
In-Reply-To: <20190618092038.17929-2-daniel.vetter@ffwll.ch>
Yes this is a bit a big patch, but since it's essentially a complete
rewrite of all the prime docs I didn't see how to better split it up.
Changes:
- Consistently point to drm_gem_object_funcs as the preferred hooks,
where applicable.
- Document all the hooks in &drm_driver that lacked kerneldoc.
- Completely new overview section, which now also includes the cleaned
up lifetime/reference counting subchapter. I also mentioned the weak
references in there due to the lookup caches.
- Completely rewritten helper intro section, highlight the
import/export related functionality.
- Polish for all the functions and more cross references.
I also sprinkled a bunch of todos all over.
Most important: 0 code changes in here. The cleanup motivated by
reading and improving all this will follow later on.
v2: Actually update the prime helper docs. Plus add a few FIXMEs that
I won't address right away in subsequent cleanup patches.
v3:
- Split out the function moving. This patch is now exclusively
documentation changes.
- Typos and nits (Sam).
v4: Polish suggestions from Noralf.
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
Acked-by: Emil Velikov <emil.velikov@collabora.com>
Acked-by: Noralf Trønnes <noralf@tronnes.org>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Noralf Trønnes <noralf@tronnes.org>
Cc: Sam Ravnborg <sam@ravnborg.org>
Cc: Eric Anholt <eric@anholt.net>
Cc: Emil Velikov <emil.l.velikov@gmail.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
Documentation/gpu/drm-mm.rst | 40 +------
drivers/gpu/drm/drm_prime.c | 201 +++++++++++++++++++++--------------
include/drm/drm_drv.h | 104 +++++++++++++++---
include/drm/drm_gem.h | 18 ++--
4 files changed, 229 insertions(+), 134 deletions(-)
diff --git a/Documentation/gpu/drm-mm.rst b/Documentation/gpu/drm-mm.rst
index c8ebd4f66a6a..b664f054c259 100644
--- a/Documentation/gpu/drm-mm.rst
+++ b/Documentation/gpu/drm-mm.rst
@@ -433,43 +433,11 @@ PRIME is the cross device buffer sharing framework in drm, originally
created for the OPTIMUS range of multi-gpu platforms. To userspace PRIME
buffers are dma-buf based file descriptors.
-Overview and Driver Interface
------------------------------
+Overview and Lifetime Rules
+---------------------------
-Similar to GEM global names, PRIME file descriptors are also used to
-share buffer objects across processes. They offer additional security:
-as file descriptors must be explicitly sent over UNIX domain sockets to
-be shared between applications, they can't be guessed like the globally
-unique GEM names.
-
-Drivers that support the PRIME API must set the DRIVER_PRIME bit in the
-struct :c:type:`struct drm_driver <drm_driver>`
-driver_features field, and implement the prime_handle_to_fd and
-prime_fd_to_handle operations.
-
-int (\*prime_handle_to_fd)(struct drm_device \*dev, struct drm_file
-\*file_priv, uint32_t handle, uint32_t flags, int \*prime_fd); int
-(\*prime_fd_to_handle)(struct drm_device \*dev, struct drm_file
-\*file_priv, int prime_fd, uint32_t \*handle); Those two operations
-convert a handle to a PRIME file descriptor and vice versa. Drivers must
-use the kernel dma-buf buffer sharing framework to manage the PRIME file
-descriptors. Similar to the mode setting API PRIME is agnostic to the
-underlying buffer object manager, as long as handles are 32bit unsigned
-integers.
-
-While non-GEM drivers must implement the operations themselves, GEM
-drivers must use the :c:func:`drm_gem_prime_handle_to_fd()` and
-:c:func:`drm_gem_prime_fd_to_handle()` helper functions. Those
-helpers rely on the driver gem_prime_export and gem_prime_import
-operations to create a dma-buf instance from a GEM object (dma-buf
-exporter role) and to create a GEM object from a dma-buf instance
-(dma-buf importer role).
-
-struct dma_buf \* (\*gem_prime_export)(struct drm_device \*dev,
-struct drm_gem_object \*obj, int flags); struct drm_gem_object \*
-(\*gem_prime_import)(struct drm_device \*dev, struct dma_buf
-\*dma_buf); These two operations are mandatory for GEM drivers that
-support PRIME.
+.. kernel-doc:: drivers/gpu/drm/drm_prime.c
+ :doc: overview and lifetime rules
PRIME Helper Functions
----------------------
diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c
index 68b4de85370c..c269bc03c42a 100644
--- a/drivers/gpu/drm/drm_prime.c
+++ b/drivers/gpu/drm/drm_prime.c
@@ -38,47 +38,53 @@
#include "drm_internal.h"
-/*
- * DMA-BUF/GEM Object references and lifetime overview:
- *
- * On the export the dma_buf holds a reference to the exporting GEM
- * object. It takes this reference in handle_to_fd_ioctl, when it
- * first calls .prime_export and stores the exporting GEM object in
- * the dma_buf priv. This reference needs to be released when the
- * final reference to the &dma_buf itself is dropped and its
- * &dma_buf_ops.release function is called. For GEM-based drivers,
- * the dma_buf should be exported using drm_gem_dmabuf_export() and
- * then released by drm_gem_dmabuf_release().
- *
- * On the import the importing GEM object holds a reference to the
- * dma_buf (which in turn holds a ref to the exporting GEM object).
- * It takes that reference in the fd_to_handle ioctl.
- * It calls dma_buf_get, creates an attachment to it and stores the
- * attachment in the GEM object. When this attachment is destroyed
- * when the imported object is destroyed, we remove the attachment
- * and drop the reference to the dma_buf.
- *
- * When all the references to the &dma_buf are dropped, i.e. when
- * userspace has closed both handles to the imported GEM object (through the
- * FD_TO_HANDLE IOCTL) and closed the file descriptor of the exported
- * (through the HANDLE_TO_FD IOCTL) dma_buf, and all kernel-internal references
- * are also gone, then the dma_buf gets destroyed. This can also happen as a
- * part of the clean up procedure in the drm_release() function if userspace
- * fails to properly clean up. Note that both the kernel and userspace (by
- * keeeping the PRIME file descriptors open) can hold references onto a
- * &dma_buf.
- *
- * Thus the chain of references always flows in one direction
- * (avoiding loops): importing_gem -> dmabuf -> exporting_gem
- *
- * Self-importing: if userspace is using PRIME as a replacement for flink
- * then it will get a fd->handle request for a GEM object that it created.
- * Drivers should detect this situation and return back the gem object
- * from the dma-buf private. Prime will do this automatically for drivers that
- * use the drm_gem_prime_{import,export} helpers.
- *
- * GEM struct &dma_buf_ops symbols are now exported. They can be resued by
- * drivers which implement GEM interface.
+/**
+ * DOC: overview and lifetime rules
+ *
+ * Similar to GEM global names, PRIME file descriptors are also used to share
+ * buffer objects across processes. They offer additional security: as file
+ * descriptors must be explicitly sent over UNIX domain sockets to be shared
+ * between applications, they can't be guessed like the globally unique GEM
+ * names.
+ *
+ * Drivers that support the PRIME API must set the DRIVER_PRIME bit in the
+ * &drm_driver.driver_features field, and implement the
+ * &drm_driver.prime_handle_to_fd and &drm_driver.prime_fd_to_handle operations.
+ * GEM based drivers must use drm_gem_prime_handle_to_fd() and
+ * drm_gem_prime_fd_to_handle() to implement these. For GEM based drivers the
+ * actual driver interfaces is provided through the &drm_gem_object_funcs.export
+ * and &drm_driver.gem_prime_import hooks.
+ *
+ * &dma_buf_ops implementations for GEM drivers are all individually exported
+ * for drivers which need to overwrite or reimplement some of them.
+ *
+ * Reference Counting for GEM Drivers
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ * On the export the &dma_buf holds a reference to the exported buffer object,
+ * usually a &drm_gem_object. It takes this reference in the PRIME_HANDLE_TO_FD
+ * IOCTL, when it first calls &drm_gem_object_funcs.export
+ * and stores the exporting GEM object in the &dma_buf.priv field. This
+ * reference needs to be released when the final reference to the &dma_buf
+ * itself is dropped and its &dma_buf_ops.release function is called. For
+ * GEM-based drivers, the &dma_buf should be exported using
+ * drm_gem_dmabuf_export() and then released by drm_gem_dmabuf_release().
+ *
+ * Thus the chain of references always flows in one direction, avoiding loops:
+ * importing GEM object -> dma-buf -> exported GEM bo. A further complication
+ * are the lookup caches for import and export. These are required to guarantee
+ * that any given object will always have only one uniqe userspace handle. This
+ * is required to allow userspace to detect duplicated imports, since some GEM
+ * drivers do fail command submissions if a given buffer object is listed more
+ * than once. These import and export caches in &drm_prime_file_private only
+ * retain a weak reference, which is cleaned up when the corresponding object is
+ * released.
+ *
+ * Self-importing: If userspace is using PRIME as a replacement for flink then
+ * it will get a fd->handle request for a GEM object that it created. Drivers
+ * should detect this situation and return back the underlying object from the
+ * dma-buf private. For GEM based drivers this is handled in
+ * drm_gem_prime_import() already.
*/
struct drm_prime_member {
@@ -220,7 +226,7 @@ void drm_prime_destroy_file_private(struct drm_prime_file_private *prime_fpriv)
}
/**
- * drm_gem_dmabuf_export - dma_buf export implementation for GEM
+ * drm_gem_dmabuf_export - &dma_buf export implementation for GEM
* @dev: parent device for the exported dmabuf
* @exp_info: the export information used by dma_buf_export()
*
@@ -248,11 +254,11 @@ struct dma_buf *drm_gem_dmabuf_export(struct drm_device *dev,
EXPORT_SYMBOL(drm_gem_dmabuf_export);
/**
- * drm_gem_dmabuf_release - dma_buf release implementation for GEM
+ * drm_gem_dmabuf_release - &dma_buf release implementation for GEM
* @dma_buf: buffer to be released
*
* Generic release function for dma_bufs exported as PRIME buffers. GEM drivers
- * must use this in their dma_buf ops structure as the release callback.
+ * must use this in their &dma_buf_ops structure as the release callback.
* drm_gem_dmabuf_release() should be used in conjunction with
* drm_gem_dmabuf_export().
*/
@@ -278,7 +284,9 @@ EXPORT_SYMBOL(drm_gem_dmabuf_release);
* This is the PRIME import function which must be used mandatorily by GEM
* drivers to ensure correct lifetime management of the underlying GEM object.
* The actual importing of GEM object from the dma-buf is done through the
- * gem_import_export driver callback.
+ * &drm_driver.gem_prime_import driver callback.
+ *
+ * Returns 0 on success or a negative error code on failure.
*/
int drm_gem_prime_fd_to_handle(struct drm_device *dev,
struct drm_file *file_priv, int prime_fd,
@@ -412,7 +420,7 @@ static struct dma_buf *export_and_register_object(struct drm_device *dev,
* This is the PRIME export function which must be used mandatorily by GEM
* drivers to ensure correct lifetime management of the underlying GEM object.
* The actual exporting from GEM object to a dma-buf is done through the
- * gem_prime_export driver callback.
+ * &drm_driver.gem_prime_export driver callback.
*/
int drm_gem_prime_handle_to_fd(struct drm_device *dev,
struct drm_file *file_priv, uint32_t handle,
@@ -523,23 +531,39 @@ int drm_prime_handle_to_fd_ioctl(struct drm_device *dev, void *data,
/**
* DOC: PRIME Helpers
*
- * Drivers can implement @gem_prime_export and @gem_prime_import in terms of
- * simpler APIs by using the helper functions @drm_gem_prime_export and
- * @drm_gem_prime_import. These functions implement dma-buf support in terms of
- * six lower-level driver callbacks:
+ * Drivers can implement &drm_gem_object_funcs.export and
+ * &drm_driver.gem_prime_import in terms of simpler APIs by using the helper
+ * functions drm_gem_prime_export() and drm_gem_prime_import(). These functions
+ * implement dma-buf support in terms of some lower-level helpers, which are
+ * again exported for drivers to use individually:
+ *
+ * Exporting buffers
+ * ~~~~~~~~~~~~~~~~~
+ *
+ * Optional pinning of buffers is handled at dma-buf attach and detach time in
+ * drm_gem_map_attach() and drm_gem_map_detach(). Backing storage itself is
+ * handled by drm_gem_map_dma_buf() and drm_gem_unmap_dma_buf(), which relies on
+ * &drm_gem_object_funcs.get_sg_table.
+ *
+ * For kernel-internal access there's drm_gem_dmabuf_vmap() and
+ * drm_gem_dmabuf_vunmap(). Userspace mmap support is provided by
+ * drm_gem_dmabuf_mmap().
*
- * Export callbacks:
+ * Note that these export helpers can only be used if the underlying backing
+ * storage is fully coherent and either permanently pinned, or it is safe to pin
+ * it indefinitely.
*
- * * @gem_prime_pin (optional): prepare a GEM object for exporting
- * * @gem_prime_get_sg_table: provide a scatter/gather table of pinned pages
- * * @gem_prime_vmap: vmap a buffer exported by your driver
- * * @gem_prime_vunmap: vunmap a buffer exported by your driver
- * * @gem_prime_mmap (optional): mmap a buffer exported by your driver
+ * FIXME: The underlying helper functions are named rather inconsistently.
*
- * Import callback:
+ * Exporting buffers
+ * ~~~~~~~~~~~~~~~~~
*
- * * @gem_prime_import_sg_table (import): produce a GEM object from another
- * driver's scatter/gather table
+ * Importing dma-bufs using drm_gem_prime_import() relies on
+ * &drm_driver.gem_prime_import_sg_table.
+ *
+ * Note that similarly to the export helpers this permanently pins the
+ * underlying backing storage. Which is ok for scanout, but is not the best
+ * option for sharing lots of buffers for rendering.
*/
/**
@@ -547,8 +571,9 @@ int drm_prime_handle_to_fd_ioctl(struct drm_device *dev, void *data,
* @dma_buf: buffer to attach device to
* @attach: buffer attachment data
*
- * Calls &drm_driver.gem_prime_pin for device specific handling. This can be
- * used as the &dma_buf_ops.attach callback.
+ * Calls &drm_gem_object_funcs.pin for device specific handling. This can be
+ * used as the &dma_buf_ops.attach callback. Must be used together with
+ * drm_gem_map_detach().
*
* Returns 0 on success, negative error code on failure.
*/
@@ -566,8 +591,9 @@ EXPORT_SYMBOL(drm_gem_map_attach);
* @dma_buf: buffer to detach from
* @attach: attachment to be detached
*
- * Cleans up &dma_buf_attachment. This can be used as the &dma_buf_ops.detach
- * callback.
+ * Calls &drm_gem_object_funcs.pin for device specific handling. Cleans up
+ * &dma_buf_attachment from drm_gem_map_attach(). This can be used as the
+ * &dma_buf_ops.detach callback.
*/
void drm_gem_map_detach(struct dma_buf *dma_buf,
struct dma_buf_attachment *attach)
@@ -583,13 +609,13 @@ EXPORT_SYMBOL(drm_gem_map_detach);
* @attach: attachment whose scatterlist is to be returned
* @dir: direction of DMA transfer
*
- * Calls &drm_driver.gem_prime_get_sg_table and then maps the scatterlist. This
- * can be used as the &dma_buf_ops.map_dma_buf callback.
+ * Calls &drm_gem_object_funcs.get_sg_table and then maps the scatterlist. This
+ * can be used as the &dma_buf_ops.map_dma_buf callback. Should be used together
+ * with drm_gem_unmap_dma_buf().
*
- * Returns sg_table containing the scatterlist to be returned; returns ERR_PTR
+ * Returns:sg_table containing the scatterlist to be returned; returns ERR_PTR
* on error. May return -EINTR if it is interrupted by a signal.
*/
-
struct sg_table *drm_gem_map_dma_buf(struct dma_buf_attachment *attach,
enum dma_data_direction dir)
{
@@ -642,9 +668,9 @@ EXPORT_SYMBOL(drm_gem_unmap_dma_buf);
* @dma_buf: buffer to be mapped
*
* Sets up a kernel virtual mapping. This can be used as the &dma_buf_ops.vmap
- * callback.
+ * callback. Calls into &drm_gem_object_funcs.vmap for device specific handling.
*
- * Returns the kernel virtual address.
+ * Returns the kernel virtual address or NULL on failure.
*/
void *drm_gem_dmabuf_vmap(struct dma_buf *dma_buf)
{
@@ -665,7 +691,7 @@ EXPORT_SYMBOL(drm_gem_dmabuf_vmap);
* @vaddr: the virtual address of the buffer
*
* Releases a kernel virtual mapping. This can be used as the
- * &dma_buf_ops.vunmap callback.
+ * &dma_buf_ops.vunmap callback. Calls into &drm_gem_object_funcs.vunmap for device specific handling.
*/
void drm_gem_dmabuf_vunmap(struct dma_buf *dma_buf, void *vaddr)
{
@@ -727,7 +753,11 @@ EXPORT_SYMBOL(drm_gem_prime_mmap);
* @vma: virtual address range
*
* Provides memory mapping for the buffer. This can be used as the
- * &dma_buf_ops.mmap callback.
+ * &dma_buf_ops.mmap callback. It just forwards to &drm_driver.gem_prime_mmap,
+ * which should be set to drm_gem_prime_mmap().
+ *
+ * FIXME: There's really no point to this wrapper, drivers which need anything
+ * else but drm_gem_prime_mmap can roll their own &dma_buf_ops.mmap callback.
*
* Returns 0 on success or a negative error code on failure.
*/
@@ -763,6 +793,8 @@ static const struct dma_buf_ops drm_gem_prime_dmabuf_ops = {
* This helper creates an sg table object from a set of pages
* the driver is responsible for mapping the pages into the
* importers address space for use with dma_buf itself.
+ *
+ * This is useful for implementing &drm_gem_object_funcs.get_sg_table.
*/
struct sg_table *drm_prime_pages_to_sg(struct page **pages, unsigned int nr_pages)
{
@@ -793,8 +825,9 @@ EXPORT_SYMBOL(drm_prime_pages_to_sg);
* @obj: GEM object to export
* @flags: flags like DRM_CLOEXEC and DRM_RDWR
*
- * This is the implementation of the gem_prime_export functions for GEM drivers
- * using the PRIME helpers.
+ * This is the implementation of the &drm_gem_object_funcs.export functions for GEM drivers
+ * using the PRIME helpers. It is used as the default in
+ * drm_gem_prime_handle_to_fd().
*/
struct dma_buf *drm_gem_prime_export(struct drm_device *dev,
struct drm_gem_object *obj,
@@ -823,9 +856,13 @@ EXPORT_SYMBOL(drm_gem_prime_export);
* @dma_buf: dma-buf object to import
* @attach_dev: struct device to dma_buf attach
*
- * This is the core of drm_gem_prime_import. It's designed to be called by
- * drivers who want to use a different device structure than dev->dev for
- * attaching via dma_buf.
+ * This is the core of drm_gem_prime_import(). It's designed to be called by
+ * drivers who want to use a different device structure than &drm_device.dev for
+ * attaching via dma_buf. This function calls
+ * &drm_driver.gem_prime_import_sg_table internally.
+ *
+ * Drivers must arrange to call drm_prime_gem_destroy() from their
+ * &drm_gem_object_funcs.free hook when using this function.
*/
struct drm_gem_object *drm_gem_prime_import_dev(struct drm_device *dev,
struct dma_buf *dma_buf,
@@ -889,7 +926,12 @@ EXPORT_SYMBOL(drm_gem_prime_import_dev);
* @dma_buf: dma-buf object to import
*
* This is the implementation of the gem_prime_import functions for GEM drivers
- * using the PRIME helpers.
+ * using the PRIME helpers. Drivers can use this as their
+ * &drm_driver.gem_prime_import implementation. It is used as the default
+ * implementation in drm_gem_prime_fd_to_handle().
+ *
+ * Drivers must arrange to call drm_prime_gem_destroy() from their
+ * &drm_gem_object_funcs.free hook when using this function.
*/
struct drm_gem_object *drm_gem_prime_import(struct drm_device *dev,
struct dma_buf *dma_buf)
@@ -907,6 +949,9 @@ EXPORT_SYMBOL(drm_gem_prime_import);
*
* Exports an sg table into an array of pages and addresses. This is currently
* required by the TTM driver in order to do correct fault handling.
+ *
+ * Drivers can use this in their &drm_driver.gem_prime_import_sg_table
+ * implementation.
*/
int drm_prime_sg_to_page_addr_arrays(struct sg_table *sgt, struct page **pages,
dma_addr_t *addrs, int max_entries)
@@ -947,7 +992,7 @@ EXPORT_SYMBOL(drm_prime_sg_to_page_addr_arrays);
* @sg: the sg-table which was pinned at import time
*
* This is the cleanup functions which GEM drivers need to call when they use
- * @drm_gem_prime_import to import dma-bufs.
+ * drm_gem_prime_import() or drm_gem_prime_import_dev() to import dma-bufs.
*/
void drm_prime_gem_destroy(struct drm_gem_object *obj, struct sg_table *sg)
{
diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h
index 5c4fc0ddc863..12e3aa7d7a9f 100644
--- a/include/drm/drm_drv.h
+++ b/include/drm/drm_drv.h
@@ -505,21 +505,25 @@ struct drm_driver {
* @gem_free_object: deconstructor for drm_gem_objects
*
* This is deprecated and should not be used by new drivers. Use
- * @gem_free_object_unlocked instead.
+ * &drm_gem_object_funcs.free instead.
*/
void (*gem_free_object) (struct drm_gem_object *obj);
/**
* @gem_free_object_unlocked: deconstructor for drm_gem_objects
*
- * This is for drivers which are not encumbered with &drm_device.struct_mutex
- * legacy locking schemes. Use this hook instead of @gem_free_object.
+ * This is deprecated and should not be used by new drivers. Use
+ * &drm_gem_object_funcs.free instead.
+ * Compared to @gem_free_object this is not encumbered with
+ * &drm_device.struct_mutex legacy locking schemes.
*/
void (*gem_free_object_unlocked) (struct drm_gem_object *obj);
/**
* @gem_open_object:
*
+ * This callback is deprecated in favour of &drm_gem_object_funcs.open.
+ *
* Driver hook called upon gem handle creation
*/
int (*gem_open_object) (struct drm_gem_object *, struct drm_file *);
@@ -527,6 +531,8 @@ struct drm_driver {
/**
* @gem_close_object:
*
+ * This callback is deprecated in favour of &drm_gem_object_funcs.close.
+ *
* Driver hook called upon gem handle release
*/
void (*gem_close_object) (struct drm_gem_object *, struct drm_file *);
@@ -534,6 +540,9 @@ struct drm_driver {
/**
* @gem_print_info:
*
+ * This callback is deprecated in favour of
+ * &drm_gem_object_funcs.print_info.
+ *
* If driver subclasses struct &drm_gem_object, it can implement this
* optional hook for printing additional driver specific info.
*
@@ -548,56 +557,120 @@ struct drm_driver {
/**
* @gem_create_object: constructor for gem objects
*
- * Hook for allocating the GEM object struct, for use by core
- * helpers.
+ * Hook for allocating the GEM object struct, for use by the CMA and
+ * SHMEM GEM helpers.
*/
struct drm_gem_object *(*gem_create_object)(struct drm_device *dev,
size_t size);
-
- /* prime: */
/**
* @prime_handle_to_fd:
*
- * export handle -> fd (see drm_gem_prime_handle_to_fd() helper)
+ * Main PRIME export function. Should be implemented with
+ * drm_gem_prime_handle_to_fd() for GEM based drivers.
+ *
+ * For an in-depth discussion see :ref:`PRIME buffer sharing
+ * documentation <prime_buffer_sharing>`.
*/
int (*prime_handle_to_fd)(struct drm_device *dev, struct drm_file *file_priv,
uint32_t handle, uint32_t flags, int *prime_fd);
/**
* @prime_fd_to_handle:
*
- * import fd -> handle (see drm_gem_prime_fd_to_handle() helper)
+ * Main PRIME import function. Should be implemented with
+ * drm_gem_prime_fd_to_handle() for GEM based drivers.
+ *
+ * For an in-depth discussion see :ref:`PRIME buffer sharing
+ * documentation <prime_buffer_sharing>`.
*/
int (*prime_fd_to_handle)(struct drm_device *dev, struct drm_file *file_priv,
int prime_fd, uint32_t *handle);
/**
* @gem_prime_export:
*
- * export GEM -> dmabuf
- *
- * This defaults to drm_gem_prime_export() if not set.
+ * Export hook for GEM drivers. Deprecated in favour of
+ * &drm_gem_object_funcs.export.
*/
struct dma_buf * (*gem_prime_export)(struct drm_device *dev,
struct drm_gem_object *obj, int flags);
/**
* @gem_prime_import:
*
- * import dmabuf -> GEM
+ * Import hook for GEM drivers.
*
* This defaults to drm_gem_prime_import() if not set.
*/
struct drm_gem_object * (*gem_prime_import)(struct drm_device *dev,
struct dma_buf *dma_buf);
+
+ /**
+ * @gem_prime_pin:
+ *
+ * Deprecated hook in favour of &drm_gem_object_funcs.pin.
+ */
int (*gem_prime_pin)(struct drm_gem_object *obj);
+
+ /**
+ * @gem_prime_unpin:
+ *
+ * Deprecated hook in favour of &drm_gem_object_funcs.unpin.
+ */
void (*gem_prime_unpin)(struct drm_gem_object *obj);
+
+
+ /**
+ * @gem_prime_get_sg_table:
+ *
+ * Deprecated hook in favour of &drm_gem_object_funcs.get_sg_table.
+ */
+ struct sg_table *(*gem_prime_get_sg_table)(struct drm_gem_object *obj);
+
+ /**
+ * @gem_prime_res_obj:
+ *
+ * Optional hook to look up the &reservation_object for an buffer when
+ * exporting it.
+ *
+ * FIXME: This hook is deprecated. Users of this hook should be replaced
+ * by setting &drm_gem_object.resv instead.
+ */
struct reservation_object * (*gem_prime_res_obj)(
struct drm_gem_object *obj);
- struct sg_table *(*gem_prime_get_sg_table)(struct drm_gem_object *obj);
+
+ /**
+ * @gem_prime_import_sg_table:
+ *
+ * Optional hook used by the PRIME helper functions
+ * drm_gem_prime_import() respectively drm_gem_prime_import_dev().
+ */
struct drm_gem_object *(*gem_prime_import_sg_table)(
struct drm_device *dev,
struct dma_buf_attachment *attach,
struct sg_table *sgt);
+ /**
+ * @gem_prime_vmap:
+ *
+ * Deprecated vmap hook for GEM drivers. Please use
+ * &drm_gem_object_funcs.vmap instead.
+ */
void *(*gem_prime_vmap)(struct drm_gem_object *obj);
+
+ /**
+ * @gem_prime_vunmap:
+ *
+ * Deprecated vunmap hook for GEM drivers. Please use
+ * &drm_gem_object_funcs.vunmap instead.
+ */
void (*gem_prime_vunmap)(struct drm_gem_object *obj, void *vaddr);
+
+ /**
+ * @gem_prime_mmap:
+ *
+ * mmap hook for GEM drivers, used to implement dma-buf mmap in the
+ * PRIME helpers.
+ *
+ * FIXME: There's way too much duplication going on here, and also moved
+ * to &drm_gem_object_funcs.
+ */
int (*gem_prime_mmap)(struct drm_gem_object *obj,
struct vm_area_struct *vma);
@@ -665,6 +738,9 @@ struct drm_driver {
/**
* @gem_vm_ops: Driver private ops for this object
+ *
+ * For GEM drivers this is deprecated in favour of
+ * &drm_gem_object_funcs.vm_ops.
*/
const struct vm_operations_struct *gem_vm_ops;
diff --git a/include/drm/drm_gem.h b/include/drm/drm_gem.h
index a9121fe66ea2..ae693c0666cd 100644
--- a/include/drm/drm_gem.h
+++ b/include/drm/drm_gem.h
@@ -101,7 +101,7 @@ struct drm_gem_object_funcs {
/**
* @pin:
*
- * Pin backing buffer in memory.
+ * Pin backing buffer in memory. Used by the drm_gem_map_attach() helper.
*
* This callback is optional.
*/
@@ -110,7 +110,7 @@ struct drm_gem_object_funcs {
/**
* @unpin:
*
- * Unpin backing buffer.
+ * Unpin backing buffer. Used by the drm_gem_map_detach() helper.
*
* This callback is optional.
*/
@@ -120,16 +120,21 @@ struct drm_gem_object_funcs {
* @get_sg_table:
*
* Returns a Scatter-Gather table representation of the buffer.
- * Used when exporting a buffer.
+ * Used when exporting a buffer by the drm_gem_map_dma_buf() helper.
+ * Releasing is done by calling dma_unmap_sg_attrs() and sg_free_table()
+ * in drm_gem_unmap_buf(), therefore these helpers and this callback
+ * here cannot be used for sg tables pointing at driver private memory
+ * ranges.
*
- * This callback is mandatory if buffer export is supported.
+ * See also drm_prime_pages_to_sg().
*/
struct sg_table *(*get_sg_table)(struct drm_gem_object *obj);
/**
* @vmap:
*
- * Returns a virtual address for the buffer.
+ * Returns a virtual address for the buffer. Used by the
+ * drm_gem_dmabuf_vmap() helper.
*
* This callback is optional.
*/
@@ -138,7 +143,8 @@ struct drm_gem_object_funcs {
/**
* @vunmap:
*
- * Releases the the address previously returned by @vmap.
+ * Releases the the address previously returned by @vmap. Used by the
+ * drm_gem_dmabuf_vunmap() helper.
*
* This callback is optional.
*/
--
2.20.1
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply related
* Re: [dpdk-dev] [PATCH v2] ipsec: support multi-segment packets
From: Akhil Goyal @ 2019-06-20 12:46 UTC (permalink / raw)
To: Konstantin Ananyev, dev@dpdk.org
In-Reply-To: <20190531000006.13918-1-konstantin.ananyev@intel.com>
Hi Konstantin,
>
> Add support for packets that consist of multiple segments.
> Take into account that trailer bytes (padding, ESP tail, ICV)
> can spawn across multiple segments.
>
> Signed-off-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
> ---
Which all action types does this patch work well with?
Will it work for lookaside none and inline crypto case both?
For the other 2, ipsec lib is not used.
Also how can the SG support be tested?
>
> v1 -> v2:
> merge with latest mainline
> fix build problem for RTE_BUILD_SHARED_LIB=y
> update programmer's guide
>
> doc/guides/prog_guide/ipsec_lib.rst | 1 -
> lib/librte_ipsec/Makefile | 3 +-
> lib/librte_ipsec/esp_inb.c | 148 +++++++++++++++++++++-------
> lib/librte_ipsec/misc.h | 61 ++++++++++++
> 4 files changed, 175 insertions(+), 38 deletions(-)
>
> diff --git a/doc/guides/prog_guide/ipsec_lib.rst
> b/doc/guides/prog_guide/ipsec_lib.rst
> index 6fc08886f..63b75b652 100644
> --- a/doc/guides/prog_guide/ipsec_lib.rst
> +++ b/doc/guides/prog_guide/ipsec_lib.rst
> @@ -162,7 +162,6 @@ Limitations
> The following features are not properly supported in the current version:
>
> * ESP transport mode for IPv6 packets with extension headers.
> -* Multi-segment packets.
> * Updates of the fields in inner IP header for tunnel mode
> (as described in RFC 4301, section 5.1.2).
> * Hard/soft limit for SA lifetime (time interval/byte count).
> diff --git a/lib/librte_ipsec/Makefile b/lib/librte_ipsec/Makefile
> index e80926baa..22f29d98a 100644
> --- a/lib/librte_ipsec/Makefile
> +++ b/lib/librte_ipsec/Makefile
> @@ -9,7 +9,8 @@ LIB = librte_ipsec.a
> CFLAGS += -O3
> CFLAGS += $(WERROR_FLAGS) -I$(SRCDIR)
> CFLAGS += -DALLOW_EXPERIMENTAL_API
> -LDLIBS += -lrte_eal -lrte_mbuf -lrte_net -lrte_cryptodev -lrte_security
> +LDLIBS += -lrte_eal -lrte_mempool -lrte_mbuf -lrte_net
> +LDLIBS += -lrte_cryptodev -lrte_security
>
I believe this build dependency should also be updated in meson.build file as well.
> EXPORT_MAP := rte_ipsec_version.map
>
> diff --git a/lib/librte_ipsec/esp_inb.c b/lib/librte_ipsec/esp_inb.c
> index 3e12ca103..819d2bf25 100644
> --- a/lib/librte_ipsec/esp_inb.c
> +++ b/lib/librte_ipsec/esp_inb.c
> @@ -104,6 +104,34 @@ inb_cop_prepare(struct rte_crypto_op *cop,
> }
> }
>
^ permalink raw reply
* [Qemu-arm] [PATCH v5 1/3] hw/firmware: Add Edk2Crypto and edk2_add_host_crypto_policy()
From: Philippe Mathieu-Daudé @ 2019-06-20 12:21 UTC (permalink / raw)
To: qemu-devel, Laszlo Ersek
Cc: Peter Maydell, Andrew Jones, Eduardo Habkost, Michael S. Tsirkin,
qemu-arm, Paolo Bonzini, Philippe Mathieu-Daudé
In-Reply-To: <20190620122132.10075-1-philmd@redhat.com>
The Edk2Crypto object is used to hold configuration values specific
to EDK2.
The edk2_add_host_crypto_policy() function loads crypto policies
from the host, and register them as fw_cfg named file items.
So far only the 'https' policy is supported.
A usercase example is the 'HTTPS Boof' feature of OVMF [*].
Usage example:
- via the command line:
$ qemu-system-x86_64 \
--object edk2_crypto,id=https,\
ciphers=/etc/crypto-policies/back-ends/openssl.config,\
cacerts=/etc/pki/ca-trust/extracted/edk2/cacerts.bin
- via QMP:
{
"execute": "object-add",
"arguments": {
"qom-type": "edk2_crypto",
"id": "https",
"props": {
"ciphers": "/etc/crypto-policies/back-ends/openssl.config",
"cacerts": "/etc/pki/ca-trust/extracted/edk2/cacerts.bin"
}
}
}
(On Fedora these files are provided by the ca-certificates and
crypto-policies packages).
[*]: https://github.com/tianocore/edk2/blob/master/OvmfPkg/README
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
---
v3:
- inverted the if() logic
- '-object' -> '--object' in commit description (Eric)
- reworded the 'TODO: g_free' comment
v4:
- do not return pointer to alloc'd data (Markus)
- INTERFACE_CHECK -> OBJECT_CLASS_CHECK (Markus)
- path -> filename (Laszlo)
- dropped the 'TODO: g_free' comment (Markus)
v5:
- only allow 1 singleton using the UserCreatableClass::complete
callback (Markus, Laszlo)
- object own fw_cfg 'file' content, no need for
fw_cfg_add_file_from_host() (Laszlo)
- g_file_get_contents() called when object is instantiated
and report error, the machine 'done' notifier do not have
to manage errors (do not fail).
- add QMP example
-
- do not add docs/interop/firmware.json to MAINTAINERS
---
MAINTAINERS | 2 +
hw/Makefile.objs | 1 +
hw/firmware/Makefile.objs | 1 +
hw/firmware/uefi_edk2_crypto_policies.c | 209 ++++++++++++++++++++++++
include/hw/firmware/uefi_edk2.h | 30 ++++
5 files changed, 243 insertions(+)
create mode 100644 hw/firmware/Makefile.objs
create mode 100644 hw/firmware/uefi_edk2_crypto_policies.c
create mode 100644 include/hw/firmware/uefi_edk2.h
diff --git a/MAINTAINERS b/MAINTAINERS
index d32c5c2313..28de489134 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2262,6 +2262,8 @@ EDK2 Firmware
M: Laszlo Ersek <lersek@redhat.com>
M: Philippe Mathieu-Daudé <philmd@redhat.com>
S: Supported
+F: hw/firmware/uefi_edk2_crypto_policies.c
+F: include/hw/firmware/uefi_edk2.h
F: pc-bios/descriptors/??-edk2-*.json
F: pc-bios/edk2-*
F: roms/Makefile.edk2
diff --git a/hw/Makefile.objs b/hw/Makefile.objs
index d770926ba9..c13b6ee0dd 100644
--- a/hw/Makefile.objs
+++ b/hw/Makefile.objs
@@ -8,6 +8,7 @@ devices-dirs-$(CONFIG_SOFTMMU) += char/
devices-dirs-$(CONFIG_SOFTMMU) += cpu/
devices-dirs-$(CONFIG_SOFTMMU) += display/
devices-dirs-$(CONFIG_SOFTMMU) += dma/
+devices-dirs-$(CONFIG_SOFTMMU) += firmware/
devices-dirs-$(CONFIG_SOFTMMU) += gpio/
devices-dirs-$(CONFIG_HYPERV) += hyperv/
devices-dirs-$(CONFIG_I2C) += i2c/
diff --git a/hw/firmware/Makefile.objs b/hw/firmware/Makefile.objs
new file mode 100644
index 0000000000..ea1f6d44df
--- /dev/null
+++ b/hw/firmware/Makefile.objs
@@ -0,0 +1 @@
+common-obj-y += uefi_edk2_crypto_policies.o
diff --git a/hw/firmware/uefi_edk2_crypto_policies.c b/hw/firmware/uefi_edk2_crypto_policies.c
new file mode 100644
index 0000000000..a0164272ea
--- /dev/null
+++ b/hw/firmware/uefi_edk2_crypto_policies.c
@@ -0,0 +1,209 @@
+/*
+ * UEFI EDK2 Support
+ *
+ * Copyright (c) 2019 Red Hat Inc.
+ *
+ * Author:
+ * Philippe Mathieu-Daudé <philmd@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "qom/object_interfaces.h"
+#include "hw/firmware/uefi_edk2.h"
+
+
+#define TYPE_EDK2_CRYPTO "edk2_crypto"
+
+#define EDK2_CRYPTO_CLASS(klass) \
+ OBJECT_CLASS_CHECK(Edk2CryptoClass, (klass), \
+ TYPE_EDK2_CRYPTO)
+#define EDK2_CRYPTO_GET_CLASS(obj) \
+ OBJECT_GET_CLASS(Edk2CryptoClass, (obj), \
+ TYPE_EDK2_CRYPTO)
+#define EDK2_CRYPTO(obj) \
+ OBJECT_CHECK(Edk2Crypto, (obj), \
+ TYPE_EDK2_CRYPTO)
+
+typedef struct FWCfgHostContent {
+ /*
+ * Path to the acceptable ciphersuites and the preferred order from
+ * the host-side crypto policy.
+ */
+ char *filename;
+ /*
+ * Add a new NAMED fw_cfg item as a raw "blob" of the given size. The data
+ * referenced by the starting pointer is only linked, NOT copied, into the
+ * data structure of the fw_cfg device.
+ */
+ char *contents;
+
+ size_t contents_length;
+} FWCfgHostContent;
+
+typedef struct Edk2Crypto {
+ Object parent_obj;
+
+ /*
+ * Path to the acceptable ciphersuites and the preferred order from
+ * the host-side crypto policy.
+ */
+ FWCfgHostContent ciphers;
+ /* Path to the trusted CA certificates configured on the host side. */
+ FWCfgHostContent cacerts;
+} Edk2Crypto;
+
+typedef struct Edk2CryptoClass {
+ ObjectClass parent_class;
+} Edk2CryptoClass;
+
+static Edk2Crypto *edk2_crypto_by_policy_id(const char *policy_id, Error **errp)
+{
+ Object *obj;
+
+ obj = object_resolve_path_component(object_get_objects_root(), policy_id);
+ if (!obj) {
+ error_setg(errp, "Cannot find EDK2 crypto policy ID %s", policy_id);
+ return NULL;
+ }
+
+ if (!object_dynamic_cast(obj, TYPE_EDK2_CRYPTO)) {
+ error_setg(errp, "Object '%s' is not a EDK2 crypto subclass",
+ policy_id);
+ return NULL;
+ }
+
+ return EDK2_CRYPTO(obj);
+}
+
+static void edk2_crypto_prop_set_ciphers(Object *obj, const char *value,
+ Error **errp G_GNUC_UNUSED)
+{
+ Edk2Crypto *s = EDK2_CRYPTO(obj);
+
+ g_free(s->ciphers.filename);
+ s->ciphers.filename = g_strdup(value);
+}
+
+static char *edk2_crypto_prop_get_ciphers(Object *obj,
+ Error **errp G_GNUC_UNUSED)
+{
+ Edk2Crypto *s = EDK2_CRYPTO(obj);
+
+ return g_strdup(s->ciphers.filename);
+}
+
+static void edk2_crypto_prop_set_cacerts(Object *obj, const char *value,
+ Error **errp G_GNUC_UNUSED)
+{
+ Edk2Crypto *s = EDK2_CRYPTO(obj);
+
+ g_free(s->cacerts.filename);
+ s->cacerts.filename = g_strdup(value);
+}
+
+static char *edk2_crypto_prop_get_cacerts(Object *obj,
+ Error **errp G_GNUC_UNUSED)
+{
+ Edk2Crypto *s = EDK2_CRYPTO(obj);
+
+ return g_strdup(s->cacerts.filename);
+}
+
+static void edk2_crypto_complete(UserCreatable *uc, Error **errp)
+{
+ Edk2Crypto *s = EDK2_CRYPTO(uc);
+ Error *local_err = NULL;
+ GError *gerr = NULL;
+
+ if (s->ciphers.filename) {
+ if (!g_file_get_contents(s->ciphers.filename, &s->ciphers.contents,
+ &s->ciphers.contents_length, &gerr)) {
+ goto report_error;
+ }
+ }
+ if (s->cacerts.filename) {
+ if (!g_file_get_contents(s->cacerts.filename, &s->cacerts.contents,
+ &s->cacerts.contents_length, &gerr)) {
+ goto report_error;
+ }
+ }
+ return;
+
+ report_error:
+ error_setg(&local_err, "%s", gerr->message);
+ g_error_free(gerr);
+ error_propagate_prepend(errp, local_err, "EDK2 crypto policy: ");
+}
+
+static void edk2_crypto_finalize(Object *obj)
+{
+ Edk2Crypto *s = EDK2_CRYPTO(obj);
+
+ g_free(s->ciphers.filename);
+ g_free(s->ciphers.contents);
+ g_free(s->cacerts.filename);
+ g_free(s->cacerts.contents);
+}
+
+static void edk2_crypto_class_init(ObjectClass *oc, void *data)
+{
+ UserCreatableClass *ucc = USER_CREATABLE_CLASS(oc);
+
+ ucc->complete = edk2_crypto_complete;
+
+ object_class_property_add_str(oc, "ciphers",
+ edk2_crypto_prop_get_ciphers,
+ edk2_crypto_prop_set_ciphers,
+ NULL);
+ object_class_property_add_str(oc, "cacerts",
+ edk2_crypto_prop_get_cacerts,
+ edk2_crypto_prop_set_cacerts,
+ NULL);
+}
+
+static const TypeInfo edk2_crypto_info = {
+ .parent = TYPE_OBJECT,
+ .name = TYPE_EDK2_CRYPTO,
+ .instance_size = sizeof(Edk2Crypto),
+ .instance_finalize = edk2_crypto_finalize,
+ .class_size = sizeof(Edk2CryptoClass),
+ .class_init = edk2_crypto_class_init,
+ .interfaces = (InterfaceInfo[]) {
+ { TYPE_USER_CREATABLE },
+ { }
+ }
+};
+
+static void edk2_crypto_register_types(void)
+{
+ type_register_static(&edk2_crypto_info);
+}
+
+type_init(edk2_crypto_register_types);
+
+static void edk2_add_host_crypto_policy_https(FWCfgState *fw_cfg)
+{
+ Edk2Crypto *s;
+
+ s = edk2_crypto_by_policy_id("https", NULL);
+ if (!s) {
+ return;
+ }
+ if (s->ciphers.contents_length) {
+ fw_cfg_add_file(fw_cfg, "etc/edk2/https/ciphers",
+ s->ciphers.contents, s->ciphers.contents_length);
+ }
+ if (s->cacerts.contents_length) {
+ fw_cfg_add_file(fw_cfg, "etc/edk2/https/cacerts",
+ s->cacerts.contents, s->cacerts.contents_length);
+ }
+}
+
+void edk2_add_host_crypto_policy(FWCfgState *fw_cfg)
+{
+ edk2_add_host_crypto_policy_https(fw_cfg);
+}
diff --git a/include/hw/firmware/uefi_edk2.h b/include/hw/firmware/uefi_edk2.h
new file mode 100644
index 0000000000..f8f81c5cb2
--- /dev/null
+++ b/include/hw/firmware/uefi_edk2.h
@@ -0,0 +1,30 @@
+/*
+ * UEFI EDK2 Support
+ *
+ * Copyright (c) 2019 Red Hat Inc.
+ *
+ * Author:
+ * Philippe Mathieu-Daudé <philmd@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef HW_FIRMWARE_UEFI_EDK2_H
+#define HW_FIRMWARE_UEFI_EDK2_H
+
+#include "hw/nvram/fw_cfg.h"
+
+/**
+ * edk2_add_host_crypto_policy:
+ * @fw_cfg: fw_cfg device being modified
+ *
+ * Add a new named file containing the host crypto policy.
+ *
+ * This method is called by the machine_done() Notifier of
+ * some implementations of MachineState, currently the X86
+ * PCMachineState and the ARM VirtMachineState.
+ */
+void edk2_add_host_crypto_policy(FWCfgState *fw_cfg);
+
+#endif /* HW_FIRMWARE_UEFI_EDK2_H */
--
2.20.1
^ permalink raw reply related
* Re: [Qemu-devel] [PATCH v3 0/4] target/mips: Misc fixes and maintenance for 4.1
From: no-reply @ 2019-06-20 11:48 UTC (permalink / raw)
To: aleksandar.markovic; +Cc: arikalo, qemu-devel, amarkovic
In-Reply-To: <1561024929-26004-1-git-send-email-aleksandar.markovic@rt-rk.com>
Patchew URL: https://patchew.org/QEMU/1561024929-26004-1-git-send-email-aleksandar.markovic@rt-rk.com/
Hi,
This series seems to have some coding style problems. See output below for
more information:
Subject: [Qemu-devel] [PATCH v3 0/4] target/mips: Misc fixes and maintenance for 4.1
Type: series
Message-id: 1561024929-26004-1-git-send-email-aleksandar.markovic@rt-rk.com
=== TEST SCRIPT BEGIN ===
#!/bin/bash
git rev-parse base > /dev/null || exit 0
git config --local diff.renamelimit 0
git config --local diff.renames True
git config --local diff.algorithm histogram
./scripts/checkpatch.pl --mailback base..
=== TEST SCRIPT END ===
From https://github.com/patchew-project/qemu
* [new tag] patchew/1561024929-26004-1-git-send-email-aleksandar.markovic@rt-rk.com -> patchew/1561024929-26004-1-git-send-email-aleksandar.markovic@rt-rk.com
Switched to a new branch 'test'
317f44916c target/mips: Fix if-else-switch-case arms checkpatch errors in translate.c
62d84de603 target/mips: Fix some space checkpatch errors in translate.c
5f90ea06d5 MAINTAINERS: Consolidate MIPS disassembler-related items
fb2a72d4cf MAINTAINERS: Update file items for MIPS Malta board
=== OUTPUT BEGIN ===
1/4 Checking commit fb2a72d4cffd (MAINTAINERS: Update file items for MIPS Malta board)
2/4 Checking commit 5f90ea06d5da (MAINTAINERS: Consolidate MIPS disassembler-related items)
3/4 Checking commit 62d84de603dd (target/mips: Fix some space checkpatch errors in translate.c)
4/4 Checking commit 317f44916c47 (target/mips: Fix if-else-switch-case arms checkpatch errors in translate.c)
ERROR: space prohibited after that open parenthesis '('
#139: FILE: target/mips/translate.c:3138:
+ if (unlikely( (ctx->CP0_Config5 & (1 << CP0C5_NMS)) &&
ERROR: space prohibited before that close parenthesis ')'
#140: FILE: target/mips/translate.c:3139:
+ !(ctx->CP0_Config1 & (1 << CP0C1_DL )) &&
ERROR: space prohibited before that close parenthesis ')'
#141: FILE: target/mips/translate.c:3140:
+ !(ctx->CP0_Config1 & (1 << CP0C1_IL )) &&
ERROR: space prohibited before that close parenthesis ')'
#142: FILE: target/mips/translate.c:3141:
+ !(ctx->CP0_Config2 & (1 << CP0C2_SL )) &&
ERROR: space prohibited before that close parenthesis ')'
#143: FILE: target/mips/translate.c:3142:
+ !(ctx->CP0_Config2 & (1 << CP0C2_TL )) &&
ERROR: space prohibited before that close parenthesis ')'
#144: FILE: target/mips/translate.c:3143:
+ !(ctx->CP0_Config5 & (1 << CP0C5_L2C)) ) ) {
total: 6 errors, 0 warnings, 432 lines checked
Patch 4/4 has style problems, please review. If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
=== OUTPUT END ===
Test command exited with code: 1
The full log is available at
http://patchew.org/logs/1561024929-26004-1-git-send-email-aleksandar.markovic@rt-rk.com/testing.checkpatch/?type=message.
---
Email generated automatically by Patchew [https://patchew.org/].
Please send your feedback to patchew-devel@redhat.com
^ permalink raw reply
* RE: [PATCH] mfd: da9063: occupy second I2C address, too
From: Steve Twiss @ 2019-06-20 12:44 UTC (permalink / raw)
To: Lee Jones, wsa+renesas@sang-engineering.com
Cc: bgolaszewski@baylibre.com,
kieran.bingham+renesas@ideasonboard.com,
linux-kernel@vger.kernel.org, linux-renesas-soc@vger.kernel.org,
peda@axentia.se, Support Opensource
In-Reply-To: <20190620122853.GD4699@dell>
On 20 June 2019 13:29, Lee Jones wrote:
> Subject: Re: [PATCH] mfd: da9063: occupy second I2C address, too
>
> Why isn't this reply attached (threaded) to the patch.
My apologies. It wasn't my intention to split Wolfram's original e-mail thread.
I don't usually reply using the mailto: link from lore when creating e-mails.
Outlook mustn't support the In-Reply-To header.
I'll figure out a different way to reply in future.
> Is your mailer broken?
It's Windows
^ permalink raw reply
* Re: [PATCH] staging: rtl8723bs: HalBtc8723b1Ant: fix Using comparison to true is error prone
From: Greg Kroah-Hartman @ 2019-06-20 12:44 UTC (permalink / raw)
To: Hariprasad Kelam; +Cc: devel, linux-kernel
In-Reply-To: <20190619180439.GA7217@hari-Inspiron-1545>
On Wed, Jun 19, 2019 at 11:34:39PM +0530, Hariprasad Kelam wrote:
> This patch fixes below issue reported by checkpatch
>
> CHECK: Using comparison to true is error prone
> CHECK: Using comparison to false is error prone
>
> Signed-off-by: Hariprasad Kelam <hariprasad.kelam@gmail.com>
> ---
> drivers/staging/rtl8723bs/hal/HalBtc8723b1Ant.c | 8 ++++----
> 1 file changed, 4 insertions(+), 4 deletions(-)
Does not apply to my tree :(
^ permalink raw reply
* Re: [PATCH 2/2] drm/prime: Update docs
From: Daniel Vetter @ 2019-06-20 12:44 UTC (permalink / raw)
To: Noralf Trønnes
Cc: Daniel Vetter, Intel Graphics Development, DRI Development,
Daniel Vetter, Sam Ravnborg
In-Reply-To: <ca761903-0cfb-5d39-4e73-5c4098483a00@tronnes.org>
On Wed, Jun 19, 2019 at 02:43:20PM +0200, Noralf Trønnes wrote:
>
>
> Den 18.06.2019 11.20, skrev Daniel Vetter:
> > Yes this is a bit a big patch, but since it's essentially a complete
> > rewrite of all the prime docs I didn't see how to better split it up.
> >
> > Changes:
> > - Consistently point to drm_gem_object_funcs as the preferred hooks,
> > where applicable.
> >
> > - Document all the hooks in &drm_driver that lacked kerneldoc.
> >
> > - Completely new overview section, which now also includes the cleaned
> > up lifetime/reference counting subchapter. I also mentioned the weak
> > references in there due to the lookup caches.
> >
> > - Completely rewritten helper intro section, highlight the
> > import/export related functionality.
> >
> > - Polish for all the functions and more cross references.
> >
> > I also sprinkled a bunch of todos all over.
> >
> > Most important: 0 code changes in here. The cleanup motivated by
> > reading and improving all this will follow later on.
> >
> > v2: Actually update the prime helper docs. Plus add a few FIXMEs that
> > I won't address right away in subsequent cleanup patches.
> >
> > v3:
> > - Split out the function moving. This patch is now exclusively
> > documentation changes.
> > - Typos and nits (Sam).
> >
> > Cc: Sam Ravnborg <sam@ravnborg.org>
> > Cc: Eric Anholt <eric@anholt.net>
> > Cc: Emil Velikov <emil.l.velikov@gmail.com>
> > Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> > ---
> > Documentation/gpu/drm-mm.rst | 40 +------
> > drivers/gpu/drm/drm_prime.c | 197 +++++++++++++++++++++--------------
> > include/drm/drm_drv.h | 104 +++++++++++++++---
> > include/drm/drm_gem.h | 18 ++--
> > 4 files changed, 226 insertions(+), 133 deletions(-)
> >
>
> <snip>
>
> > diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c
> > index 68b4de85370c..2234206288fa 100644
> > --- a/drivers/gpu/drm/drm_prime.c
> > +++ b/drivers/gpu/drm/drm_prime.c
> > @@ -38,47 +38,53 @@
> >
> > #include "drm_internal.h"
> >
> > -/*
> > - * DMA-BUF/GEM Object references and lifetime overview:
> > - *
> > - * On the export the dma_buf holds a reference to the exporting GEM
> > - * object. It takes this reference in handle_to_fd_ioctl, when it
> > - * first calls .prime_export and stores the exporting GEM object in
> > - * the dma_buf priv. This reference needs to be released when the
> > - * final reference to the &dma_buf itself is dropped and its
> > - * &dma_buf_ops.release function is called. For GEM-based drivers,
> > - * the dma_buf should be exported using drm_gem_dmabuf_export() and
> > - * then released by drm_gem_dmabuf_release().
> > - *
> > - * On the import the importing GEM object holds a reference to the
> > - * dma_buf (which in turn holds a ref to the exporting GEM object).
> > - * It takes that reference in the fd_to_handle ioctl.
> > - * It calls dma_buf_get, creates an attachment to it and stores the
> > - * attachment in the GEM object. When this attachment is destroyed
> > - * when the imported object is destroyed, we remove the attachment
> > - * and drop the reference to the dma_buf.
> > - *
> > - * When all the references to the &dma_buf are dropped, i.e. when
> > - * userspace has closed both handles to the imported GEM object (through the
> > - * FD_TO_HANDLE IOCTL) and closed the file descriptor of the exported
> > - * (through the HANDLE_TO_FD IOCTL) dma_buf, and all kernel-internal references
> > - * are also gone, then the dma_buf gets destroyed. This can also happen as a
> > - * part of the clean up procedure in the drm_release() function if userspace
> > - * fails to properly clean up. Note that both the kernel and userspace (by
> > - * keeeping the PRIME file descriptors open) can hold references onto a
> > - * &dma_buf.
> > - *
> > - * Thus the chain of references always flows in one direction
> > - * (avoiding loops): importing_gem -> dmabuf -> exporting_gem
> > - *
> > - * Self-importing: if userspace is using PRIME as a replacement for flink
> > - * then it will get a fd->handle request for a GEM object that it created.
> > - * Drivers should detect this situation and return back the gem object
> > - * from the dma-buf private. Prime will do this automatically for drivers that
> > - * use the drm_gem_prime_{import,export} helpers.
> > - *
> > - * GEM struct &dma_buf_ops symbols are now exported. They can be resued by
> > - * drivers which implement GEM interface.
> > +/**
> > + * DOC: overview and lifetime rules
> > + *
> > + * Similar to GEM global names, PRIME file descriptors are also used to share
> > + * buffer objects across processes. They offer additional security: as file
> > + * descriptors must be explicitly sent over UNIX domain sockets to be shared
> > + * between applications, they can't be guessed like the globally unique GEM
> > + * names.
> > + *
> > + * Drivers that support the PRIME API must set the DRIVER_PRIME bit in the
> > + * &drm_driver.driver_features field, and implement the
> > + * &drm_driver.prime_handle_to_fd and &drm_driver.prime_fd_to_handle operations.
> > + * GEM based drivers must use drm_gem_prime_handle_to_fd() and
> > + * drm_gem_prime_fd_to_handle() to implement these. For GEM based drivers the
> > + * actual driver interfaces is provided through the &drm_gem_object_funcs.export
> > + * and &drm_driver.gem_prime_import hooks.
> > + *
> > + * &dma_buf_ops implementations for GEM drivers are all individually exported
> > + * for drivers which need to overwrite or reimplement some of them.
> > + *
> > + * Reference Counting for GEM Drivers
> > + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> > + *
> > + * On the export the &dma_buf holds a reference to the exported buffer object,
> > + * usually a &drm_gem_object. It takes this reference in the PRIME_HANDLE_TO_FD
> > + * IOCTL, when it first calls &drm_gem_object_funcs.export
> > + * and stores the exporting GEM object in the &dma_buf.priv field. This
> > + * reference needs to be released when the final reference to the &dma_buf
> > + * itself is dropped and its &dma_buf_ops.release function is called. For
> > + * GEM-based drivers, the &dma_buf should be exported using
> > + * drm_gem_dmabuf_export() and then released by drm_gem_dmabuf_release().
> > + *
> > + * Thus the chain of references always flows in one direction, avoiding loops:
> > + * importing GEM object -> dma-buf -> exported GEM bo. A further complication
> > + * are the lookup caches for import and export. These are required to guarantee
> > + * that any given object will always have only one uniqe userspace handle. This
> > + * is required to allow userspace to detect duplicated imports, since some GEM
> > + * drivers do fail command submissions if a given buffer object is listed more
> > + * than once. These import and export caches in &drm_prime_file_private only
> > + * retain a weak reference, which is cleaned up when the corresponding object is
> > + * released.
> > + *
> > + * Self-importing: If userspace is using PRIME as a replacement for flink then
> > + * it will get a fd->handle request for a GEM object that it created. Drivers
> > + * should detect this situation and return back the underlying object from the
> > + * dma-buf private. For GEM based drivers this is handled in
> > + * drm_gem_prime_import() already.
> > */
> >
> > struct drm_prime_member {
> > @@ -220,7 +226,7 @@ void drm_prime_destroy_file_private(struct drm_prime_file_private *prime_fpriv)
> > }
> >
> > /**
> > - * drm_gem_dmabuf_export - dma_buf export implementation for GEM
> > + * drm_gem_dmabuf_export - &dma_buf export implementation for GEM
> > * @dev: parent device for the exported dmabuf
> > * @exp_info: the export information used by dma_buf_export()
> > *
> > @@ -248,11 +254,11 @@ struct dma_buf *drm_gem_dmabuf_export(struct drm_device *dev,
> > EXPORT_SYMBOL(drm_gem_dmabuf_export);
> >
> > /**
> > - * drm_gem_dmabuf_release - dma_buf release implementation for GEM
> > + * drm_gem_dmabuf_release - &dma_buf release implementation for GEM
> > * @dma_buf: buffer to be released
> > *
> > * Generic release function for dma_bufs exported as PRIME buffers. GEM drivers
> > - * must use this in their dma_buf ops structure as the release callback.
> > + * must use this in their &dma_buf_ops structure as the release callback.
> > * drm_gem_dmabuf_release() should be used in conjunction with
> > * drm_gem_dmabuf_export().
> > */
> > @@ -278,7 +284,9 @@ EXPORT_SYMBOL(drm_gem_dmabuf_release);
> > * This is the PRIME import function which must be used mandatorily by GEM
> > * drivers to ensure correct lifetime management of the underlying GEM object.
> > * The actual importing of GEM object from the dma-buf is done through the
> > - * gem_import_export driver callback.
> > + * &drm_driver.gem_import_export driver callback.
>
> s/gem_import_export/gem_prime_import/
>
> > + *
> > + * Returns 0 on success or a negative error code on failure.
> > */
> > int drm_gem_prime_fd_to_handle(struct drm_device *dev,
> > struct drm_file *file_priv, int prime_fd,
> > @@ -412,7 +420,7 @@ static struct dma_buf *export_and_register_object(struct drm_device *dev,
> > * This is the PRIME export function which must be used mandatorily by GEM
> > * drivers to ensure correct lifetime management of the underlying GEM object.
> > * The actual exporting from GEM object to a dma-buf is done through the
> > - * gem_prime_export driver callback.
> > + * &drm_driver.gem_prime_export driver callback.
> > */
> > int drm_gem_prime_handle_to_fd(struct drm_device *dev,
> > struct drm_file *file_priv, uint32_t handle,
> > @@ -523,23 +531,39 @@ int drm_prime_handle_to_fd_ioctl(struct drm_device *dev, void *data,
> > /**
> > * DOC: PRIME Helpers
> > *
> > - * Drivers can implement @gem_prime_export and @gem_prime_import in terms of
> > - * simpler APIs by using the helper functions @drm_gem_prime_export and
> > - * @drm_gem_prime_import. These functions implement dma-buf support in terms of
> > - * six lower-level driver callbacks:
> > + * Drivers can implement &drm_gem_object_funcs.export and
> > + * &drm_driver.gem_prime_import in terms of simpler APIs by using the helper
> > + * functions drm_gem_prime_export() and drm_gem_prime_import(). These functions
>
> Maybe you want to mention that these functions are the default so
> drivers don't have to set them.
It's already mentioned in the kerneldoc for the callback structures in
headers, but worth repeating. To not upset the flow too much I put that
into the individual function comments - here I couldn't come up with a
good way to integrate that bit of information.
I'll take all your other feedback and resend, thanks a lot for taking a
look.
-Daniel
>
> Double space before: These functions
>
> > + * implement dma-buf support in terms of some lower-level helpers, which are
> > + * again exported for drivers to use individually:
> > + *
> > + * Exporting buffers
> > + * ~~~~~~~~~~~~~~~~~
> > + *
> > + * Optional pinning of buffers is handled at dma-buf attach and detach time in
> > + * drm_gem_map_attach() and drm_gem_map_detach(). Backing storage itself is
> > + * handled by drm_gem_map_dma_buf() and drm_gem_unmap_dma_buf(), which relies on
> > + * &drm_gem_object_funcs.get_sg_table.
> > + *
> > + * For kernel-internal access there's drm_gem_dmabuf_vmap() and
> > + * drm_gem_dmabuf_vunmap(). Userspace mmap support is provided by
> > + * drm_gem_dmabuf_mmap().
> > + *
> > + * Note that these export helpers can only be used if the underlying backing
> > + * storage is fully coherent and either permanently pinned, or it is safe to pin
> > + * it indefinitely.
> > *
> > - * Export callbacks:
> > + * FIXME: The underlying helper functions are named rather inconsistently.
> > *
> > - * * @gem_prime_pin (optional): prepare a GEM object for exporting
> > - * * @gem_prime_get_sg_table: provide a scatter/gather table of pinned pages
> > - * * @gem_prime_vmap: vmap a buffer exported by your driver
> > - * * @gem_prime_vunmap: vunmap a buffer exported by your driver
> > - * * @gem_prime_mmap (optional): mmap a buffer exported by your driver
> > + * Exporting buffers
> > + * ~~~~~~~~~~~~~~~~~
> > *
> > - * Import callback:
> > + * Importing dma-bufs using drm_gem_prime_import() relies on
> > + * &drm_driver.gem_prime_import_sg_table.
> > *
> > - * * @gem_prime_import_sg_table (import): produce a GEM object from another
> > - * driver's scatter/gather table
> > + * Note that similarly to the export helpers this permanently pins the
> > + * underlying backing storage. Which is ok for scanout, but is not the best
> > + * option for sharing lots of buffers for rendering.
> > */
> >
> > /**
> > @@ -547,8 +571,9 @@ int drm_prime_handle_to_fd_ioctl(struct drm_device *dev, void *data,
> > * @dma_buf: buffer to attach device to
> > * @attach: buffer attachment data
> > *
> > - * Calls &drm_driver.gem_prime_pin for device specific handling. This can be
> > - * used as the &dma_buf_ops.attach callback.
> > + * Calls &drm_gem_object_funcs.pin for device specific handling. This can be
> > + * used as the &dma_buf_ops.attach callback. Must be used together with
> > + * drm_gem_map_detach().
> > *
> > * Returns 0 on success, negative error code on failure.
> > */
> > @@ -566,8 +591,9 @@ EXPORT_SYMBOL(drm_gem_map_attach);
> > * @dma_buf: buffer to detach from
> > * @attach: attachment to be detached
> > *
> > - * Cleans up &dma_buf_attachment. This can be used as the &dma_buf_ops.detach
> > - * callback.
> > + * Calls &drm_gem_object_funcs.pin for device specific handling. Cleans up
> > + * &dma_buf_attachment from drm_gem_map_attach(). This can be used as the
> > + * &dma_buf_ops.detach callback.
> > */
> > void drm_gem_map_detach(struct dma_buf *dma_buf,
> > struct dma_buf_attachment *attach)
> > @@ -583,13 +609,13 @@ EXPORT_SYMBOL(drm_gem_map_detach);
> > * @attach: attachment whose scatterlist is to be returned
> > * @dir: direction of DMA transfer
> > *
> > - * Calls &drm_driver.gem_prime_get_sg_table and then maps the scatterlist. This
> > - * can be used as the &dma_buf_ops.map_dma_buf callback.
> > + * Calls &drm_gem_object_funcs.get_sg_table and then maps the scatterlist. This
> > + * can be used as the &dma_buf_ops.map_dma_buf callback. Should be used together
> > + * with drm_gem_unmap_dma_buf().
> > *
> > - * Returns sg_table containing the scatterlist to be returned; returns ERR_PTR
> > + * Returns:sg_table containing the scatterlist to be returned; returns ERR_PTR
> > * on error. May return -EINTR if it is interrupted by a signal.
> > */
> > -
> > struct sg_table *drm_gem_map_dma_buf(struct dma_buf_attachment *attach,
> > enum dma_data_direction dir)
> > {
> > @@ -642,9 +668,9 @@ EXPORT_SYMBOL(drm_gem_unmap_dma_buf);
> > * @dma_buf: buffer to be mapped
> > *
> > * Sets up a kernel virtual mapping. This can be used as the &dma_buf_ops.vmap
> > - * callback.
> > + * callback. Calls into &drm_gem_object_funcs.vmap for device specific handling.
> > *
> > - * Returns the kernel virtual address.
> > + * Returns the kernel virtual address or NULL on failure.
> > */
> > void *drm_gem_dmabuf_vmap(struct dma_buf *dma_buf)
> > {
> > @@ -665,7 +691,7 @@ EXPORT_SYMBOL(drm_gem_dmabuf_vmap);
> > * @vaddr: the virtual address of the buffer
> > *
> > * Releases a kernel virtual mapping. This can be used as the
> > - * &dma_buf_ops.vunmap callback.
> > + * &dma_buf_ops.vunmap callback. Calls into &drm_gem_object_funcs.vunmap for device specific handling.
> > */
> > void drm_gem_dmabuf_vunmap(struct dma_buf *dma_buf, void *vaddr)
> > {
> > @@ -727,7 +753,11 @@ EXPORT_SYMBOL(drm_gem_prime_mmap);
> > * @vma: virtual address range
> > *
> > * Provides memory mapping for the buffer. This can be used as the
> > - * &dma_buf_ops.mmap callback.
> > + * &dma_buf_ops.mmap callback. It just forwards to &drm_driver.gem_prime_mmap,
> > + * which should be set to drm_gem_prime_mmap().
> > + *
> > + * FIXME: There's really no point to this wrapper, drivers which need anything
> > + * else but drm_gem_prime_mmap can roll their own &dma_buf_ops.mmap callback.
> > *
> > * Returns 0 on success or a negative error code on failure.
> > */
> > @@ -763,6 +793,8 @@ static const struct dma_buf_ops drm_gem_prime_dmabuf_ops = {
> > * This helper creates an sg table object from a set of pages
> > * the driver is responsible for mapping the pages into the
> > * importers address space for use with dma_buf itself.
> > + *
> > + * This is useful for implementing &drm_gem_object_funcs.get_sg_table.
> > */
> > struct sg_table *drm_prime_pages_to_sg(struct page **pages, unsigned int nr_pages)
> > {
> > @@ -793,7 +825,7 @@ EXPORT_SYMBOL(drm_prime_pages_to_sg);
> > * @obj: GEM object to export
> > * @flags: flags like DRM_CLOEXEC and DRM_RDWR
> > *
> > - * This is the implementation of the gem_prime_export functions for GEM drivers
> > + * This is the implementation of the &drm_gem_object_funcs.export functions for GEM drivers
> > * using the PRIME helpers.
> > */
> > struct dma_buf *drm_gem_prime_export(struct drm_device *dev,
> > @@ -823,9 +855,13 @@ EXPORT_SYMBOL(drm_gem_prime_export);
> > * @dma_buf: dma-buf object to import
> > * @attach_dev: struct device to dma_buf attach
> > *
> > - * This is the core of drm_gem_prime_import. It's designed to be called by
> > - * drivers who want to use a different device structure than dev->dev for
> > - * attaching via dma_buf.
> > + * This is the core of drm_gem_prime_import(). It's designed to be called by
> > + * drivers who want to use a different device structure than &drm_device.dev for
> > + * attaching via dma_buf. This function calls
> > + * &drm_driver.gem_prime_import_sg_table internally.
> > + *
> > + * Drivers must arrange to call drm_prime_gem_destroy() from their
> > + * &drm_gem_object_funcs.free hook when using this function.
> > */
> > struct drm_gem_object *drm_gem_prime_import_dev(struct drm_device *dev,
> > struct dma_buf *dma_buf,
> > @@ -889,7 +925,11 @@ EXPORT_SYMBOL(drm_gem_prime_import_dev);
> > * @dma_buf: dma-buf object to import
> > *
> > * This is the implementation of the gem_prime_import functions for GEM drivers
> > - * using the PRIME helpers.
> > + * using the PRIME helpers. Drivers can use this as their
> > + * &drm_driver.gem_prime_import implementation.
> > + *
> > + * Drivers must arrange to call drm_prime_gem_destroy() from their
> > + * &drm_gem_object_funcs.free hook when using this function.
> > */
> > struct drm_gem_object *drm_gem_prime_import(struct drm_device *dev,
> > struct dma_buf *dma_buf)
> > @@ -907,6 +947,9 @@ EXPORT_SYMBOL(drm_gem_prime_import);
> > *
> > * Exports an sg table into an array of pages and addresses. This is currently
> > * required by the TTM driver in order to do correct fault handling.
> > + *
> > + * Drivers can use this in their &drm_driver.gem_prime_import_sg_table
> > + * implementation.
> > */
> > int drm_prime_sg_to_page_addr_arrays(struct sg_table *sgt, struct page **pages,
> > dma_addr_t *addrs, int max_entries)
> > @@ -947,7 +990,7 @@ EXPORT_SYMBOL(drm_prime_sg_to_page_addr_arrays);
> > * @sg: the sg-table which was pinned at import time
> > *
> > * This is the cleanup functions which GEM drivers need to call when they use
> > - * @drm_gem_prime_import to import dma-bufs.
> > + * drm_gem_prime_import() or drm_gem_prime_import_dev() to import dma-bufs.
> > */
> > void drm_prime_gem_destroy(struct drm_gem_object *obj, struct sg_table *sg)
> > {
> > diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h
> > index 5c4fc0ddc863..bbb3a6ff4418 100644
> > --- a/include/drm/drm_drv.h
> > +++ b/include/drm/drm_drv.h
> > @@ -505,21 +505,25 @@ struct drm_driver {
> > * @gem_free_object: deconstructor for drm_gem_objects
> > *
> > * This is deprecated and should not be used by new drivers. Use
> > - * @gem_free_object_unlocked instead.
> > + * &drm_gem_object_funcs.free instead.
> > */
> > void (*gem_free_object) (struct drm_gem_object *obj);
> >
> > /**
> > * @gem_free_object_unlocked: deconstructor for drm_gem_objects
> > *
> > - * This is for drivers which are not encumbered with &drm_device.struct_mutex
> > - * legacy locking schemes. Use this hook instead of @gem_free_object.
> > + * This is deprecated and should not be used by new drivers. Use
> > + * &drm_gem_object_funcs.free instead.
> > + * Compared to @gem_free_object this is not encumbered with
> > + * &drm_device.struct_mutex legacy locking schemes.
> > */
> > void (*gem_free_object_unlocked) (struct drm_gem_object *obj);
> >
> > /**
> > * @gem_open_object:
> > *
> > + * This callback is deprecated in favour of &drm_gem_object_funcs.open.
> > + *
> > * Driver hook called upon gem handle creation
> > */
> > int (*gem_open_object) (struct drm_gem_object *, struct drm_file *);
> > @@ -527,6 +531,8 @@ struct drm_driver {
> > /**
> > * @gem_close_object:
> > *
> > + * This callback is deprecated in favour of &drm_gem_object_funcs.close.
> > + *
> > * Driver hook called upon gem handle release
> > */
> > void (*gem_close_object) (struct drm_gem_object *, struct drm_file *);
> > @@ -534,6 +540,9 @@ struct drm_driver {
> > /**
> > * @gem_print_info:
> > *
> > + * This callback is deprecated in favour of
> > + * &drm_gem_object_funcs.print_info.
> > + *
> > * If driver subclasses struct &drm_gem_object, it can implement this
> > * optional hook for printing additional driver specific info.
> > *
> > @@ -548,56 +557,120 @@ struct drm_driver {
> > /**
> > * @gem_create_object: constructor for gem objects
> > *
> > - * Hook for allocating the GEM object struct, for use by core
> > - * helpers.
> > + * Hook for allocating the GEM object struct, for use by the CMA and
> > + * SHMEM GEM helpers.
> > */
> > struct drm_gem_object *(*gem_create_object)(struct drm_device *dev,
> > size_t size);
> > -
> > - /* prime: */
> > /**
> > * @prime_handle_to_fd:
> > *
> > - * export handle -> fd (see drm_gem_prime_handle_to_fd() helper)
> > + * Main PRIME export function. Should be implemented with
> > + * drm_gem_prime_handle_to_fd() for GEM based drivers.
> > + *
> > + * For an in-depth discussion see :ref:`PRIME buffer sharing
> > + * documentation <prime_buffer_sharing>`.
> > */
> > int (*prime_handle_to_fd)(struct drm_device *dev, struct drm_file *file_priv,
> > uint32_t handle, uint32_t flags, int *prime_fd);
> > /**
> > * @prime_fd_to_handle:
> > *
> > - * import fd -> handle (see drm_gem_prime_fd_to_handle() helper)
> > + * Main PRIME import function. Should be implemented with
> > + * drm_gem_prime_fd_to_handle() for GEM based drivers.
> > + *
> > + * For an in-depth discussion see :ref:`PRIME buffer sharing
> > + * documentation <prime_buffer_sharing>`.
> > */
> > int (*prime_fd_to_handle)(struct drm_device *dev, struct drm_file *file_priv,
> > int prime_fd, uint32_t *handle);
> > /**
> > * @gem_prime_export:
> > *
> > - * export GEM -> dmabuf
> > - *
> > - * This defaults to drm_gem_prime_export() if not set.
> > + * Export hook for GEM drivers. Deprecated in favour of
> > + * &drm_gem_object_funcs.export.
> > */
> > struct dma_buf * (*gem_prime_export)(struct drm_device *dev,
> > struct drm_gem_object *obj, int flags);
> > /**
> > * @gem_prime_import:
> > *
> > - * import dmabuf -> GEM
> > + * Import hook for GEM drivers.
> > *
> > * This defaults to drm_gem_prime_import() if not set.
> > */
> > struct drm_gem_object * (*gem_prime_import)(struct drm_device *dev,
> > struct dma_buf *dma_buf);
> > +
> > + /**
> > + * @gem_prime_pin:
> > + *
> > + * Deprecated hook in favour of &drm_gem_object_funcs.pin.
> > + */
> > int (*gem_prime_pin)(struct drm_gem_object *obj);
> > +
> > + /**
> > + * @gem_prime_unpin:
> > + *
> > + * Deprecated hook in favour of &drm_gem_object_funcs.unpin.
> > + */
> > void (*gem_prime_unpin)(struct drm_gem_object *obj);
> > +
> > +
> > + /**
> > + * @gem_prime_get_sg_table:
> > + *
> > + * Deprecated hook in favour of &drm_gem_object_funcs.get_sg_table.
> > + */
> > + struct sg_table *(*gem_prime_get_sg_table)(struct drm_gem_object *obj);
> > +
> > + /**
> > + * @gem_prime_res_obj:
> > + *
> > + * Optional hook to look up the &reservation_object for an buffer when
> > + * exporting it.
> > + *
> > + * FIXME: This hook is deprecated. Users of this hook should be replaced
> > + * by setting &drm_gem_object.resv instead.
> > + */
> > struct reservation_object * (*gem_prime_res_obj)(
> > struct drm_gem_object *obj);
> > - struct sg_table *(*gem_prime_get_sg_table)(struct drm_gem_object *obj);
> > +
> > + /**
> > + * @gem_prime_import_sg_table:
> > + *
> > + * Optional hook used by the PRIME helper functions
> > + * drm_gem_prime_import() respectively drm_gem_prime_import_dev().
> > + */
> > struct drm_gem_object *(*gem_prime_import_sg_table)(
> > struct drm_device *dev,
> > struct dma_buf_attachment *attach,
> > struct sg_table *sgt);
> > + /**
> > + * @gem_prime_vmap:
> > + *
> > + * Deprecated vmap hook for GEM drivers. Please use
> > + * &drm_gem_object_funcs.vmap instead.
> > + */
> > void *(*gem_prime_vmap)(struct drm_gem_object *obj);
> > +
> > + /**
> > + * @gem_prime_vunmap:
> > + *
> > + * Deprecated vunmap hook for GEM drivers. Please use
> > + * &drm_gem_object_funcs.vunmap instead.
> > + */
> > void (*gem_prime_vunmap)(struct drm_gem_object *obj, void *vaddr);
> > +
> > + /**
> > + * @gem_prime_mmap:
> > + *
> > + * mmap hook for GEM drivers, used to implement dma-buf mmap in the
> > + * PRIME helpers.
> > + *
> > + * FIXME: There's way too much duplication going on here, and also moved
> > + * to &drm_gem_object_funcs.
> > + */
> > int (*gem_prime_mmap)(struct drm_gem_object *obj,
> > struct vm_area_struct *vma);
> >
> > @@ -665,6 +738,9 @@ struct drm_driver {
> >
> > /**
> > * @gem_vm_ops: Driver private ops for this object
> > + *
> > + * For GEM driver this is deprecated in favour of
>
> s/driver/drivers/
>
> > + * &drm_gem_object_funcs.vm_ops.
> > */
> > const struct vm_operations_struct *gem_vm_ops;
> >
> > diff --git a/include/drm/drm_gem.h b/include/drm/drm_gem.h
> > index a9121fe66ea2..9af88238ee5c 100644
> > --- a/include/drm/drm_gem.h
> > +++ b/include/drm/drm_gem.h
> > @@ -101,7 +101,7 @@ struct drm_gem_object_funcs {
> > /**
> > * @pin:
> > *
> > - * Pin backing buffer in memory.
> > + * Pin backing buffer in memory. Used by the drm_gem_map_attach helper.
>
> s/drm_gem_map_attach/drm_gem_map_attach()/
>
> Looks sane:
>
> Acked-by: Noralf Trønnes <noralf@tronnes.org>
>
> > *
> > * This callback is optional.
> > */
> > @@ -110,7 +110,7 @@ struct drm_gem_object_funcs {
> > /**
> > * @unpin:
> > *
> > - * Unpin backing buffer.
> > + * Unpin backing buffer. Used by the drm_gem_map_detach() helper.
> > *
> > * This callback is optional.
> > */
> > @@ -120,16 +120,21 @@ struct drm_gem_object_funcs {
> > * @get_sg_table:
> > *
> > * Returns a Scatter-Gather table representation of the buffer.
> > - * Used when exporting a buffer.
> > + * Used when exporting a buffer by the drm_gem_map_dma_buf() helper.
> > + * Releasing is done by calling dma_unmap_sg_attrs() and sg_free_table()
> > + * in drm_gem_unmap_buf(), therefore these helpers and this callback
> > + * here cannot be used for sg tables pointing at driver private memory
> > + * ranges.
> > *
> > - * This callback is mandatory if buffer export is supported.
> > + * See also drm_prime_pages_to_sg().
> > */
> > struct sg_table *(*get_sg_table)(struct drm_gem_object *obj);
> >
> > /**
> > * @vmap:
> > *
> > - * Returns a virtual address for the buffer.
> > + * Returns a virtual address for the buffer. Used by the
> > + * drm_gem_dmabuf_vmap() helper.
> > *
> > * This callback is optional.
> > */
> > @@ -138,7 +143,8 @@ struct drm_gem_object_funcs {
> > /**
> > * @vunmap:
> > *
> > - * Releases the the address previously returned by @vmap.
> > + * Releases the the address previously returned by @vmap. Used by the
> > + * drm_gem_dmabuf_vunmap() helper.
> > *
> > * This callback is optional.
> > */
> >
--
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply
* [PATCH] scripts/sphinx-pre-install: fix out-of-tree build
From: Mike Rapoport @ 2019-06-20 12:43 UTC (permalink / raw)
To: Jonathan Corbet; +Cc: Mauro Carvalho Chehab, linux-doc, Mike Rapoport
Build of htmldocs fails for out-of-tree builds:
$ make V=1 O=~/build/kernel/ htmldocs
make -C /home/rppt/build/kernel -f /home/rppt/git/linux-docs/Makefile htmldocs
make[1]: Entering directory '/home/rppt/build/kernel'
make -f /home/rppt/git/linux-docs/scripts/Makefile.build obj=scripts/basic
rm -f .tmp_quiet_recordmcount
make -f /home/rppt/git/linux-docs/scripts/Makefile.build obj=Documentation htmldocs
Can't open Documentation/conf.py at /home/rppt/git/linux-docs/scripts/sphinx-pre-install line 230.
/home/rppt/git/linux-docs/Documentation/Makefile:80: recipe for target 'htmldocs' failed
make[2]: *** [htmldocs] Error 2
The scripts/sphinx-pre-install is trying to open files in the current
directory which is $KBUILD_OUTPUT rather than in $srctree.
Fix it.
Signed-off-by: Mike Rapoport <rppt@linux.ibm.com>
---
scripts/sphinx-pre-install | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/scripts/sphinx-pre-install b/scripts/sphinx-pre-install
index 0b44d51..f710bbd 100755
--- a/scripts/sphinx-pre-install
+++ b/scripts/sphinx-pre-install
@@ -5,8 +5,9 @@ use strict;
# Copyright (c) 2017-2019 Mauro Carvalho Chehab <mchehab@kernel.org>
#
-my $conf = "Documentation/conf.py";
-my $requirement_file = "Documentation/sphinx/requirements.txt";
+my $prefix = "$ENV{'srctree'}/";
+my $conf = $prefix . "Documentation/conf.py";
+my $requirement_file = $prefix . "Documentation/sphinx/requirements.txt";
my $virtenv_prefix = "sphinx_";
#
--
2.7.4
^ permalink raw reply related
* Re: [PATCH v17 05/10] acpi: add build_append_ghes_generic_status() helper for Generic Error Status Block
From: Igor Mammedov @ 2019-06-20 12:42 UTC (permalink / raw)
To: Dongjiu Geng
Cc: pbonzini, mst, shannon.zhaosl, peter.maydell, lersek, james.morse,
mtosatti, rth, ehabkost, zhengxiang9, jonathan.cameron, xuwei5,
kvm, qemu-devel, qemu-arm, linuxarm
In-Reply-To: <1557832703-42620-6-git-send-email-gengdongjiu@huawei.com>
On Tue, 14 May 2019 04:18:18 -0700
Dongjiu Geng <gengdongjiu@huawei.com> wrote:
> It will help to add Generic Error Status Block to ACPI tables
> without using packed C structures and avoid endianness
> issues as API doesn't need explicit conversion.
>
> Signed-off-by: Dongjiu Geng <gengdongjiu@huawei.com>
> ---
> hw/acpi/aml-build.c | 14 ++++++++++++++
> include/hw/acpi/aml-build.h | 6 ++++++
> 2 files changed, 20 insertions(+)
>
> diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
> index 102a288..ce90970 100644
> --- a/hw/acpi/aml-build.c
> +++ b/hw/acpi/aml-build.c
> @@ -296,6 +296,20 @@ void build_append_ghes_notify(GArray *table, const uint8_t type,
> build_append_int_noprefix(table, error_threshold_window, 4);
> }
>
> +/* Generic Error Status Block
> + * ACPI 4.0: 17.3.2.6.1 Generic Error Data
> + */
> +void build_append_ghes_generic_status(GArray *table, uint32_t block_status,
maybe ..._generic_error_status???
> + uint32_t raw_data_offset, uint32_t raw_data_length,
> + uint32_t data_length, uint32_t error_severity)
see CODING_STYLE, 1.1 Multiline Indent
> +{
when describing filds from spec try to add 'verbatim' copy of the name from spec
so it would be esy to grep for it. Like:
/* Block Status */
> + build_append_int_noprefix(table, block_status, 4);
/* Raw Data Offset */
note applies all other places where you compose ACPI tables
> + build_append_int_noprefix(table, raw_data_offset, 4);
> + build_append_int_noprefix(table, raw_data_length, 4);
> + build_append_int_noprefix(table, data_length, 4);
> + build_append_int_noprefix(table, error_severity, 4);
> +}
> +
> /* Generic Error Data Entry
> * ACPI 4.0: 17.3.2.6.1 Generic Error Data
> */
> diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h
> index a71db2f..1ec7e1b 100644
> --- a/include/hw/acpi/aml-build.h
> +++ b/include/hw/acpi/aml-build.h
> @@ -425,6 +425,12 @@ void build_append_ghes_generic_data(GArray *table, const char *section_type,
> uint32_t error_data_length, uint8_t *fru_id,
> uint8_t *fru_text, uint64_t time_stamp);
>
> +void
> +build_append_ghes_generic_status(GArray *table, uint32_t block_status,
> + uint32_t raw_data_offset,
> + uint32_t raw_data_length,
> + uint32_t data_length, uint32_t error_severity);
this and previous patch, it might be better to to move declaration
to its own header, for example to include/hw/acpi/acpi_ghes.h
that you are adding later in the series.
And maybe move helpers to hw/acpi/acpi_ghes.c
They are not really independent ACPI primitives that are shared
with other tables, aren't they?
.
> +
> void build_srat_memory(AcpiSratMemoryAffinity *numamem, uint64_t base,
> uint64_t len, int node, MemoryAffinityFlags flags);
>
^ permalink raw reply
* [igt-dev] [PATCH i-g-t v3] Add Arm drivers as supported drivers by igt.
From: Liviu Dudau @ 2019-06-20 12:42 UTC (permalink / raw)
To: IGT GPU Tool; +Cc: Petri Latvala
In-Reply-To: <20190620080024.GA22949@platvala-desk.ger.corp.intel.com>
Add the drivers maintained by Arm developers to the igt.
v3: Update the mali-dp driver's name to match kernel driver code.
v2: Order the modules array entries alphabetically, as per
Petri Latvala's suggestion.
Signed-off-by: Liviu Dudau <liviu.dudau@arm.com>
---
lib/drmtest.c | 3 +++
lib/drmtest.h | 4 ++++
2 files changed, 7 insertions(+)
diff --git a/lib/drmtest.c b/lib/drmtest.c
index 25f203530..8243247a3 100644
--- a/lib/drmtest.c
+++ b/lib/drmtest.c
@@ -205,7 +205,10 @@ static const struct module {
void (*modprobe)(const char *name);
} modules[] = {
{ DRIVER_AMDGPU, "amdgpu" },
+ { DRIVER_HDLCD, "hdlcd" },
{ DRIVER_INTEL, "i915", modprobe_i915 },
+ { DRIVER_KOMEDA, "komeda" },
+ { DRIVER_MALIDP, "mali-dp" },
{ DRIVER_PANFROST, "panfrost" },
{ DRIVER_V3D, "v3d" },
{ DRIVER_VC4, "vc4" },
diff --git a/lib/drmtest.h b/lib/drmtest.h
index 6c4c3899c..952f0c4b6 100644
--- a/lib/drmtest.h
+++ b/lib/drmtest.h
@@ -45,6 +45,10 @@
#define DRIVER_AMDGPU (1 << 4)
#define DRIVER_V3D (1 << 5)
#define DRIVER_PANFROST (1 << 6)
+#define DRIVER_HDLCD (1 << 7)
+#define DRIVER_MALIDP (1 << 8)
+#define DRIVER_KOMEDA (1 << 9)
+
/*
* Exclude DRVER_VGEM from DRIVER_ANY since if you run on a system
* with vgem as well as a supported driver, you can end up with a
--
2.22.0
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev
^ permalink raw reply related
* Re: [tip:perf/core 23/33] arch/x86/events/intel/rapl.c:781:23: error: 'INTEL_FAM6_ICELAKE_DESKTOP' undeclared here (not in a function); did you mean 'INTEL_FAM6_SKYLAKE_DESKTOP'?
From: Peter Zijlstra @ 2019-06-20 12:43 UTC (permalink / raw)
To: kbuild test robot
Cc: Kan Liang, kbuild-all, linux-kernel, tipbuild, Ingo Molnar
In-Reply-To: <201906200702.n7RdDWBw%lkp@intel.com>
On Thu, Jun 20, 2019 at 07:38:07AM +0800, kbuild test robot wrote:
> tree: https://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git perf/core
> head: 3ce5aceb5dee298b082adfa2baa0df5a447c1b0b
> commit: 2a538fda82824a7722e296be656bb5d11d91a9cb [23/33] perf/x86/intel: Add Icelake desktop CPUID
> config: x86_64-rhel-7.6 (attached as .config)
> compiler: gcc-7 (Debian 7.3.0-1) 7.3.0
> reproduce:
> git checkout 2a538fda82824a7722e296be656bb5d11d91a9cb
> # save the attached .config to linux build tree
> make ARCH=x86_64
>
> If you fix the issue, kindly add following tag
> Reported-by: kbuild test robot <lkp@intel.com>
>
> All errors (new ones prefixed by >>):
>
> >> arch/x86/events/intel/rapl.c:781:23: error: 'INTEL_FAM6_ICELAKE_DESKTOP' undeclared here (not in a function); did you mean 'INTEL_FAM6_SKYLAKE_DESKTOP'?
> X86_RAPL_MODEL_MATCH(INTEL_FAM6_ICELAKE_DESKTOP, skl_rapl_init),
> ^
Ingo, I know you're busy, but I think this is a merge fail, these
defines are in tip/x86/cpu and/or tip/x86/urgent.
^ permalink raw reply
* [Buildroot] [PATCH 3/4] package: remove non-conventional prefix/suffix from github-fetched packages
From: Victor Huesca @ 2019-06-20 12:42 UTC (permalink / raw)
To: buildroot
In-Reply-To: <f5b97179-ad16-36fc-d1fc-401c81e695e8@mind.be>
On 19/06/2019 23:30, Arnout Vandecappelle wrote:
>
>
> On 12/06/2019 08:42, Victor Huesca wrote:
>> On Github, a large number of projects name their tag
>> <some-prefix>-0.3-<some-suffix> (i.e release-3.0, poco-0.1-release,
>> etc.). In fact majority of the cased adressed in this commit concerns
>> prefixes.
>>
>> In most packages, we encode those prefix/suffix in the <pkg>_VERSION
>> variable.
>>
>> The problem with this approach is that when used in conjunction with
>> release-monitoring.org, it doesn't work very well, because
>> release-monitoring.org has the concept of "version prefix/suffix" and
>> using that they drop the prefix/suffix to really get the version. For
>> example on https://release-monitoring.org/project/5418/ the latest
>> release of "poco" is "1.8.1", not "poco-1.8.1-release".
>>
>> Therefore, a number of packages in Buildroot have a version that
>> doesn't match with release-monitoring.org.
>>
>> Since really the version number of 1.8.1, is makes sense to update our
>> packages to drop these prefixes/suffixes.
>>
>> This commit addreses the case of github-fetched packages with
>> non-conventional prefixes/suffixes.
>>
>> Note that these changes modify the name of the files stored in DL_DIR,
>> which means that this will force a re-download of those package source
>> code for all users, and requires a change to their .hash file.
>
> Hah, here you do have the paragraph I asked for in my review of the previous
> patch! Excellent!
>
>>
>> Signed-off-by: Victor Huesca <victor.huesca@bootlin.com>
>> ---
>> package/emlog/emlog.hash | 2 +-
>> package/emlog/emlog.mk | 4 ++--
>> package/gtest/gtest.hash | 2 +-
>> package/gtest/gtest.mk | 4 ++--
>> package/intel-microcode/intel-microcode.hash | 2 +-
>> package/intel-microcode/intel-microcode.mk | 4 ++--
>> package/iputils/iputils.hash | 2 +-
>> package/iputils/iputils.mk | 4 ++--
>> package/jasper/jasper.hash | 2 +-
>> package/jasper/jasper.mk | 4 ++--
>> package/libnfs/libnfs.hash | 2 +-
>> package/libnfs/libnfs.mk | 4 ++--
>> package/libusbgx/libusbgx.hash | 2 +-
>> package/libusbgx/libusbgx.mk | 4 ++--
>> package/lua-cqueues/lua-cqueues.hash | 2 +-
>> package/lua-cqueues/lua-cqueues.mk | 4 ++--
>> package/motion/motion.hash | 2 +-
>> package/motion/motion.mk | 4 ++--
>> package/openjdk/openjdk.hash | 2 +-
>> package/openjdk/openjdk.mk | 4 ++--
>> package/poco/poco.hash | 2 +-
>> package/poco/poco.mk | 4 ++--
>> package/ptpd2/ptpd2.hash | 2 +-
>> package/ptpd2/ptpd2.mk | 4 ++--
>> package/python-web2py/python-web2py.hash | 2 +-
>> package/python-web2py/python-web2py.mk | 4 ++--
>> package/python-webpy/python-webpy.hash | 2 +-
>> package/python-webpy/python-webpy.mk | 4 ++--
>> package/xinetd/xinetd.hash | 2 +-
>> package/xinetd/xinetd.mk | 4 ++--
>> 30 files changed, 45 insertions(+), 45 deletions(-)
>>
>> diff --git a/package/emlog/emlog.hash b/package/emlog/emlog.hash
>> index 9d81d47ec2..ba0a201acb 100644
>> --- a/package/emlog/emlog.hash
>> +++ b/package/emlog/emlog.hash
>> @@ -1,2 +1,2 @@
>> # Locally calculated
>> -sha256 9f791a00c86215306597b761ef5c5ad267efee5f01efbe23cfcc04e583aa402d emlog-emlog-0.60.tar.gz
>> +sha256 9f791a00c86215306597b761ef5c5ad267efee5f01efbe23cfcc04e583aa402d emlog-0.60.tar.gz
>> diff --git a/package/emlog/emlog.mk b/package/emlog/emlog.mk
>> index e0926e6cbd..42e3c9dd7b 100644
>> --- a/package/emlog/emlog.mk
>> +++ b/package/emlog/emlog.mk
>> @@ -4,8 +4,8 @@
>> #
>> ################################################################################
>>
>> -EMLOG_VERSION = emlog-0.60
>
> This is an example of a risky one, because there are some packages on
> release-monitoring that do have such a prefix. But emlog doesn't, so OK.
I am the one that added the entry on release-monitoring. But as Thomas
mentioned, release-monitoring has an option to remove constant prefix
the from version and this is what most packages with do.
Here, emlog is the package name, so this prefix is clearly not relevant
and should not be included as part of the version, that's why did not
include this suffix in release-monitoring.
>> -EMLOG_SITE = $(call github,nicupavel,emlog,$(EMLOG_VERSION))
>> +EMLOG_VERSION = 0.60
>> +EMLOG_SITE = $(call github,nicupavel,emlog,emlog-$(EMLOG_VERSION))
>> EMLOG_LICENSE = GPL-2.0
>> EMLOG_LICENSE_FILES = COPYING
>>
>> diff --git a/package/gtest/gtest.hash b/package/gtest/gtest.hash
>> index 0a8d8ba096..aa42570eb2 100644
>> --- a/package/gtest/gtest.hash
>> +++ b/package/gtest/gtest.hash
>> @@ -1,3 +1,3 @@
>> # Locally computed:
>> -sha256 58a6f4277ca2bc8565222b3bbd58a177609e9c488e8a72649359ba51450db7d8 gtest-release-1.8.0.tar.gz
>> +sha256 58a6f4277ca2bc8565222b3bbd58a177609e9c488e8a72649359ba51450db7d8 gtest-1.8.0.tar.gz
>> sha256 9702de7e4117a8e2b20dafab11ffda58c198aede066406496bef670d40a22138 googletest/LICENSE
>> diff --git a/package/gtest/gtest.mk b/package/gtest/gtest.mk
>> index b62ceb3270..f26098bad7 100644
>> --- a/package/gtest/gtest.mk
>> +++ b/package/gtest/gtest.mk
>> @@ -4,8 +4,8 @@
>> #
>> ################################################################################
>>
>> -GTEST_VERSION = release-1.8.0
>> -GTEST_SITE = $(call github,google,googletest,$(GTEST_VERSION))
>> +GTEST_VERSION = 1.8.0
>> +GTEST_SITE = $(call github,google,googletest,release-$(GTEST_VERSION))
>
> gtest doesn't appear on release-monitoring, but that's because a mapping gtest
> -> googletest is missing. Could you add it?
Done.
>> GTEST_INSTALL_STAGING = YES
>> GTEST_INSTALL_TARGET = NO
>> GTEST_LICENSE = BSD-3-Clause
>> diff --git a/package/intel-microcode/intel-microcode.hash b/package/intel-microcode/intel-microcode.hash
>> index 257cc85c41..bb474ad2bb 100644
>> --- a/package/intel-microcode/intel-microcode.hash
>> +++ b/package/intel-microcode/intel-microcode.hash
>> @@ -1,3 +1,3 @@
>> # Locally computed
>> -sha256 9e67903a5b62b51f5e031b59a8046d3dff226834d79899799943803481a55d20 intel-microcode-microcode-20190514a.tar.gz
>> +sha256 9e67903a5b62b51f5e031b59a8046d3dff226834d79899799943803481a55d20 intel-microcode-20190514a.tar.gz
>> sha256 1f8bf63fc2b1b486c507b98ff7d283c7eb58c7945746b94188a310d6787cbee5 license
>> diff --git a/package/intel-microcode/intel-microcode.mk b/package/intel-microcode/intel-microcode.mk
>> index dacb619a14..1279a1d364 100644
>> --- a/package/intel-microcode/intel-microcode.mk
>> +++ b/package/intel-microcode/intel-microcode.mk
>> @@ -4,8 +4,8 @@
>> #
>> ################################################################################
>>
>> -INTEL_MICROCODE_VERSION = microcode-20190514a
>> -INTEL_MICROCODE_SITE = $(call github,intel,Intel-Linux-Processor-Microcode-Data-Files,$(INTEL_MICROCODE_VERSION))
>> +INTEL_MICROCODE_VERSION = 20190514a
>> +INTEL_MICROCODE_SITE = $(call github,intel,Intel-Linux-Processor-Microcode-Data-Files,microcode-$(INTEL_MICROCODE_VERSION))
>
> This might be a nice one to add to release-monitoring.
Idem
>> INTEL_MICROCODE_LICENSE = PROPRIETARY
>> INTEL_MICROCODE_LICENSE_FILES = license
>> INTEL_MICROCODE_REDISTRIBUTE = NO
> [snip]
>
>> diff --git a/package/libusbgx/libusbgx.mk b/package/libusbgx/libusbgx.mk
>> index e7c082f9f3..516ad25970 100644
>> --- a/package/libusbgx/libusbgx.mk
>> +++ b/package/libusbgx/libusbgx.mk
>> @@ -4,8 +4,8 @@
>> #
>> ################################################################################
>>
>> -LIBUSBGX_VERSION = libusbgx-v0.2.0
>> -LIBUSBGX_SITE = $(call github,libusbgx,libusbgx,$(LIBUSBGX_VERSION))
>> +LIBUSBGX_VERSION = 0.2.0
>> +LIBUSBGX_SITE = $(call github,libusbgx,libusbgx,libusbgx-v$(LIBUSBGX_VERSION))
>
> Missing on release-monitoring.
Unfortunately many packages doesn't have an entry on release-monitoring.
But this one does have one now :)
>> LIBUSBGX_LICENSE = GPL-2.0+ (examples), LGPL-2.1+ (library)
>> LIBUSBGX_LICENSE_FILES = COPYING COPYING.LGPL
>> LIBUSBGX_DEPENDENCIES = host-pkgconf libconfig
>> diff --git a/package/lua-cqueues/lua-cqueues.hash b/package/lua-cqueues/lua-cqueues.hash
>> index 9fd664d69a..7824c08f9b 100644
>> --- a/package/lua-cqueues/lua-cqueues.hash
>> +++ b/package/lua-cqueues/lua-cqueues.hash
>> @@ -1,2 +1,2 @@
>> # Locally calculated
>> -sha256 ae51b713bdf966215b87244e03ac60b5a12beb82d15dfb02755a000cfb2df905 lua-cqueues-rel-20161215.tar.gz
>> +sha256 ae51b713bdf966215b87244e03ac60b5a12beb82d15dfb02755a000cfb2df905 lua-cqueues-20161215.tar.gz
>> diff --git a/package/lua-cqueues/lua-cqueues.mk b/package/lua-cqueues/lua-cqueues.mk
>> index 4f31c3277f..5cd30ce8dc 100644
>> --- a/package/lua-cqueues/lua-cqueues.mk
>> +++ b/package/lua-cqueues/lua-cqueues.mk
>> @@ -4,8 +4,8 @@
>> #
>> ################################################################################
>>
>> -LUA_CQUEUES_VERSION = rel-20161215
>> -LUA_CQUEUES_SITE = $(call github,wahern,cqueues,$(LUA_CQUEUES_VERSION))
>> +LUA_CQUEUES_VERSION = 20161215
>> +LUA_CQUEUES_SITE = $(call github,wahern,cqueues,rel-$(LUA_CQUEUES_VERSION))
>
> Missing mapping on github. Or maybe we should update pkg-stats to guess without
> the lua- prefix.
We don't want to introduce a complicated logic in pkg-stats when a
simple mapping in release-monitoring suffice.
>> LUA_CQUEUES_LICENSE = MIT
>> LUA_CQUEUES_LICENSE_FILES = LICENSE
>> LUA_CQUEUES_DEPENDENCIES = luainterpreter openssl host-m4
>> diff --git a/package/motion/motion.hash b/package/motion/motion.hash
>> index 679defa3d3..4ce70f8640 100644
>> --- a/package/motion/motion.hash
>> +++ b/package/motion/motion.hash
>> @@ -1,3 +1,3 @@
>> # Locally computed:
>> -sha256 d97ec6ae766adfd478b6f7f9cc0da5f2fe21faa9366d98664be255714c1cf81d motion-release-4.2.1.tar.gz
>> +sha256 d97ec6ae766adfd478b6f7f9cc0da5f2fe21faa9366d98664be255714c1cf81d motion-4.2.1.tar.gz
>> sha256 91df39d1816bfb17a4dda2d3d2c83b1f6f2d38d53e53e41e8f97ad5ac46a0cad COPYING
>> diff --git a/package/motion/motion.mk b/package/motion/motion.mk
>> index 6dfc5a5619..eb7f75e3fb 100644
>> --- a/package/motion/motion.mk
>> +++ b/package/motion/motion.mk
>> @@ -4,8 +4,8 @@
>> #
>> ################################################################################
>>
>> -MOTION_VERSION = release-4.2.1
>> -MOTION_SITE = $(call github,Motion-Project,motion,$(MOTION_VERSION))
>> +MOTION_VERSION = 4.2.1
>> +MOTION_SITE = $(call github,Motion-Project,motion,release-$(MOTION_VERSION))
>
> Missing on release-monitoring.
One less to add.
>
>> MOTION_LICENSE = GPL-2.0
>> MOTION_LICENSE_FILES = COPYING
>> MOTION_DEPENDENCIES = host-pkgconf jpeg libmicrohttpd $(TARGET_NLS_DEPENDENCIES)
>> diff --git a/package/openjdk/openjdk.hash b/package/openjdk/openjdk.hash
>> index 91d0f1dbce..e94d4d6d44 100644
>> --- a/package/openjdk/openjdk.hash
>> +++ b/package/openjdk/openjdk.hash
>> @@ -1,3 +1,3 @@
>> # Locally computed
>> -sha256 de278328668bdaf35d50d0319d15d64d195ddd8a0de9c6fde3a6c9ca10135a92 openjdk-jdk-12+33.tar.gz
>> +sha256 de278328668bdaf35d50d0319d15d64d195ddd8a0de9c6fde3a6c9ca10135a92 openjdk-12+33.tar.gz
>> sha256 4b9abebc4338048a7c2dc184e9f800deb349366bdf28eb23c2677a77b4c87726 LICENSE
>> diff --git a/package/openjdk/openjdk.mk b/package/openjdk/openjdk.mk
>> index 91a00870c5..e6e834cde9 100644
>> --- a/package/openjdk/openjdk.mk
>> +++ b/package/openjdk/openjdk.mk
>> @@ -6,8 +6,8 @@
>>
>> OPENJDK_VERSION_MAJOR = 12
>> OPENJDK_VERSION_MINOR = 33
>> -OPENJDK_VERSION = jdk-$(OPENJDK_VERSION_MAJOR)+$(OPENJDK_VERSION_MINOR)
>> -OPENJDK_SITE = $(call github,AdoptOpenJDK,openjdk-jdk12u,$(OPENJDK_VERSION))
>> +OPENJDK_VERSION = $(OPENJDK_VERSION_MAJOR)+$(OPENJDK_VERSION_MINOR)
>> +OPENJDK_SITE = $(call github,AdoptOpenJDK,openjdk-jdk12u,jdk-$(OPENJDK_VERSION))
>
> release-monitoring only has openjdk-1.8.0, and calls it java-1.8.0-openjdk.
>
> This is an annoying one, because upstream will create a completely new package
> for every major release. It kind of makes sense, it's a bit like python2/python3
> (well, slightly less bad, but not by much). So maybe our package is not
> correctly named.
>
> Anyway, the release-monitoring versions for java-1.8.0-openjdk are called 8u212
> and similar. So that's annoying...
Why not simply add entries on release-monitoring for all version of
openjdk? There are two options:
- Add one entry with all version of openjdk (retrived from
http://jdk.java.net/archive/), the downside is that there is only the
latest minor/revision of each version and only since version 9...
- Add multiple entry, one for each major version, this could be easely
done via the github mirror.
I could add the entries on next week if this solution looks good to
everyone.
>
>> OPENJDK_LICENSE = GPL-2.0+ with exception
>> OPENJDK_LICENSE_FILES = LICENSE
> [snip]
>
>> diff --git a/package/ptpd2/ptpd2.hash b/package/ptpd2/ptpd2.hash
>> index af1f78a5a8..0a7379a1d8 100644
>> --- a/package/ptpd2/ptpd2.hash
>> +++ b/package/ptpd2/ptpd2.hash
>> @@ -1,2 +1,2 @@
>> # Locally computed:
>> -sha256 267ad61d09d97069acec5d4878dceda20d0ddbebd27557d80230847848cee6c2 ptpd2-ptpd-2.3.1.tar.gz
>> +sha256 267ad61d09d97069acec5d4878dceda20d0ddbebd27557d80230847848cee6c2 ptpd2-2.3.1.tar.gz
>> diff --git a/package/ptpd2/ptpd2.mk b/package/ptpd2/ptpd2.mk
>> index c0c414ae83..f4a70760ad 100644
>> --- a/package/ptpd2/ptpd2.mk
>> +++ b/package/ptpd2/ptpd2.mk
>> @@ -4,8 +4,8 @@
>> #
>> ################################################################################
>>
>> -PTPD2_VERSION = ptpd-2.3.1
>> -PTPD2_SITE = $(call github,ptpd,ptpd,$(PTPD2_VERSION))
>> +PTPD2_VERSION = 2.3.1
>> +PTPD2_SITE = $(call github,ptpd,ptpd,ptpd-$(PTPD2_VERSION))
>
> Needs mapping on release-monitoring.org.
Done.
>> PTPD2_DEPENDENCIES = libpcap
>> PTPD2_CONF_OPTS = --with-pcap-config=$(STAGING_DIR)/usr/bin/pcap-config
>> # configure not shipped
>> diff --git a/package/python-web2py/python-web2py.hash b/package/python-web2py/python-web2py.hash
>> index 9a1df0c2a1..57ac02c2a9 100644
>> --- a/package/python-web2py/python-web2py.hash
>> +++ b/package/python-web2py/python-web2py.hash
>> @@ -1,3 +1,3 @@
>> # sha256 locally computed
>> -sha256 8205a7a08595ca1a41919750a8dc4e431258966cb46c8021564b25003cf90863 python-web2py-R-2.17.2.tar.gz
>> +sha256 8205a7a08595ca1a41919750a8dc4e431258966cb46c8021564b25003cf90863 python-web2py-2.17.2.tar.gz
>> sha256 2aae96826184a492bc799add49aed7b29036e7aba2d2294fb65053bd30fe55fe LICENSE
>> diff --git a/package/python-web2py/python-web2py.mk b/package/python-web2py/python-web2py.mk
>> index 922b267b8b..0b86fb148e 100644
>> --- a/package/python-web2py/python-web2py.mk
>> +++ b/package/python-web2py/python-web2py.mk
>> @@ -4,8 +4,8 @@
>> #
>> ################################################################################
>>
>> -PYTHON_WEB2PY_VERSION = R-2.17.2
>> -PYTHON_WEB2PY_SITE = $(call github,web2py,web2py,$(PYTHON_WEB2PY_VERSION))
>> +PYTHON_WEB2PY_VERSION = 2.17.2
>> +PYTHON_WEB2PY_SITE = $(call github,web2py,web2py,R-$(PYTHON_WEB2PY_VERSION))
>
> Missing on release-monitoring.
Same.
>> PYTHON_WEB2PY_LICENSE = LGPL-3.0
>> PYTHON_WEB2PY_LICENSE_FILES = LICENSE
>> PYTHON_WEB2PY_DEPENDENCIES = $(if $(BR2_PACKAGE_PYTHON3),host-python3 python3,host-python python) \
>> diff --git a/package/python-webpy/python-webpy.hash b/package/python-webpy/python-webpy.hash
>> index 70981e0cb4..8ac6827538 100644
>> --- a/package/python-webpy/python-webpy.hash
>> +++ b/package/python-webpy/python-webpy.hash
>> @@ -1,4 +1,4 @@
>> # Locally computed
>> -sha256 f074241a0b839408a0b9840ade1198e16fbd6aa6393a48a0e84f73b545baab9a python-webpy-webpy-0.39.tar.gz
>> +sha256 f074241a0b839408a0b9840ade1198e16fbd6aa6393a48a0e84f73b545baab9a python-webpy-0.39.tar.gz
>> sha256 3826fd531a9b904841f5e3560fcda7e93f2ab8d11ef124ec65e10625efa26c34 LICENSE.txt
>> sha256 7347fd17bfd33c4093c31dc77076733e1e0150ce8c13296c56dc042bbecede84 web/wsgiserver/LICENSE.txt
>> diff --git a/package/python-webpy/python-webpy.mk b/package/python-webpy/python-webpy.mk
>> index 192ba5727f..86812a04cb 100644
>> --- a/package/python-webpy/python-webpy.mk
>> +++ b/package/python-webpy/python-webpy.mk
>> @@ -4,8 +4,8 @@
>> #
>> ################################################################################
>>
>> -PYTHON_WEBPY_VERSION = webpy-0.39
>> -PYTHON_WEBPY_SITE = $(call github,webpy,webpy,$(PYTHON_WEBPY_VERSION))
>> +PYTHON_WEBPY_VERSION = 0.39
>> +PYTHON_WEBPY_SITE = $(call github,webpy,webpy,webpy-$(PYTHON_WEBPY_VERSION))
>
> web.py on release-monitoring.
Ditto.
>> PYTHON_WEBPY_SETUP_TYPE = setuptools
>> PYTHON_WEBPY_LICENSE = Public Domain, CherryPy License
>> PYTHON_WEBPY_LICENSE_FILES = LICENSE.txt web/wsgiserver/LICENSE.txt
>
>
> All the rest is OK on release-monitoring, so I applied this patch (unchanged!)
> to master, thanks.
Great!
Victor,
Best regards
--
Victor Huesca, Bootlin
Embedded Linux and kernel engineering
https://bootlin.com
^ permalink raw reply
* Re: [PATCH 0/5] Fixes for HiSilicon LPC driver and logical PIO code
From: Olof Johansson @ 2019-06-20 12:42 UTC (permalink / raw)
To: John Garry
Cc: xuwei5, Bjorn Helgaas, Linuxarm, ARM-SoC Maintainers,
Linux Kernel Mailing List, linux-pci, Joe Perches
In-Reply-To: <1561026716-140537-1-git-send-email-john.garry@huawei.com>
Hi John,
For patches that go to a soc maintainer for merge, we're asking that
people don't cc arm@kernel.org directly.
We prefer to keep that alias mostly for pull requests from other
maintainers and patches we might have a reason to apply directly.
Otherwise we risk essentially getting all of linux-arm-kernel into
this mailbox as well.
Thanks!
-Olof
On Thu, Jun 20, 2019 at 11:33 AM John Garry <john.garry@huawei.com> wrote:
>
> As reported in [1], the hisi-lpc driver has certain issues in handling
> logical PIO regions, specifically unregistering regions.
>
> This series add a method to unregister a logical PIO region, and fixes up
> the driver to use them.
>
> RCU usage in logical PIO code looks to always have been broken, so that
> is fixed also. This is not a major fix as the list which RCU protects is
> very rarely modified.
>
> There is another patch to simplify logical PIO registration, made possible
> by the fixes.
>
> At this point, there are still separate ongoing discussions about how to
> stop the logical PIO and PCI host bridge code leaking ranges, as in [2].
>
> Hopefully this series can go through the arm soc tree and the maintainers
> have no issue with that. I'm talking specifically about the logical PIO
> code, which went through PCI tree on only previous upstreaming.
>
> Cc. linux-pci@vger.kernel.org
>
> [1] https://lore.kernel.org/lkml/1560770148-57960-1-git-send-email-john.garry@huawei.com/
> [2] https://lore.kernel.org/lkml/4b24fd36-e716-7c5e-31cc-13da727802e7@huawei.com/
>
> John Garry (5):
> lib: logic_pio: Fix RCU usage
> lib: logic_pio: Add logic_pio_unregister_range()
> bus: hisi_lpc: Unregister logical PIO range to avoid potential
> use-after-free
> bus: hisi_lpc: Add .remove method to avoid driver unbind crash
> lib: logic_pio: Enforce LOGIC_PIO_INDIRECT region ops are set at
> registration
>
> drivers/bus/hisi_lpc.c | 43 ++++++++++++++++++---
> include/linux/logic_pio.h | 1 +
> lib/logic_pio.c | 78 ++++++++++++++++++++++++++++-----------
> 3 files changed, 95 insertions(+), 27 deletions(-)
>
> --
> 2.17.1
>
^ permalink raw reply
* Re: [PATCH] delta-islands: respect progress flag
From: Derrick Stolee @ 2019-06-20 12:42 UTC (permalink / raw)
To: Jeff King, git
In-Reply-To: <20190620085832.GA5039@sigill.intra.peff.net>
On 6/20/2019 4:58 AM, Jeff King wrote:
> The delta island code always prints "Marked %d islands", even if
> progress has been suppressed with --no-progress or by sending stderr to
> a non-tty.
>
> Let's pass a progress boolean to load_delta_islands(). We already do
> the same thing for the progress meter in resolve_tree_islands().
>
> Signed-off-by: Jeff King <peff@peff.net>
> ---
> Arguably this should be a real progress meter that counts up, but I'm
> not sure what it should be counting. Refs we analyzed? Islands found?
> Unless you have a ton of refs, it doesn't really matter, so I just
> punted on that part for now and only fixed the egregious bug. :)
I agree that the first goal should be to stop writing 'progress' output
to stderr when progress is disabled. Changing this to a full progress
indicator can be done on top of this patch later (without changing the
method prototypes again) if desired.
LGTM.
-Stolee
^ permalink raw reply
* Re: [Xen-devel] [PATCH 2/4] xen/link: Link .data.schedulers and CONSTRUCTERS in more appropriate locations
From: Andrew Cooper @ 2019-06-20 12:34 UTC (permalink / raw)
To: Roger Pau Monné
Cc: Xen-devel, Julien Grall, Stefano Stabellini, Wei Liu, Jan Beulich
In-Reply-To: <20190620084028.5ozq2o4wr545mpb3@MacBook-Air-de-Roger.local>
On 20/06/2019 09:40, Roger Pau Monné wrote:
> On Wed, Jun 19, 2019 at 09:11:25PM +0100, Andrew Cooper wrote:
>> Neither of these should live in .data
>>
>> * .data.schedulers is only ever read, so is moved into .rodata
>> * CONSTRUCTORS is only ever read, and only at boot, so is moved to beside
>> .init.rodata
>>
>> Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
> For x86:
>
> Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>
>
> One comment below:
>
>> ---
>> CC: Jan Beulich <JBeulich@suse.com>
>> CC: Wei Liu <wl@xen.org>
>> CC: Roger Pau Monné <roger.pau@citrix.com>
>> CC: Stefano Stabellini <sstabellini@kernel.org>
>> CC: Julien Grall <julien.grall@arm.com>
>> ---
>> xen/arch/arm/xen.lds.S | 11 ++++++-----
>> xen/arch/x86/xen.lds.S | 11 ++++++-----
>> 2 files changed, 12 insertions(+), 10 deletions(-)
>>
>> diff --git a/xen/arch/x86/xen.lds.S b/xen/arch/x86/xen.lds.S
>> index ec37d38..9fa6c99 100644
>> --- a/xen/arch/x86/xen.lds.S
>> +++ b/xen/arch/x86/xen.lds.S
>> @@ -140,6 +140,11 @@ SECTIONS
>> *(.data.param)
>> __param_end = .;
>>
>> + . = ALIGN(POINTER_ALIGN);
>> + __start_schedulers_array = .;
>> + *(.data.schedulers)
>> + __end_schedulers_array = .;
>> +
>> #if defined(CONFIG_HAS_VPCI) && defined(CONFIG_LATE_HWDOM)
>> . = ALIGN(POINTER_ALIGN);
>> __start_vpci_array = .;
>> @@ -207,6 +212,7 @@ SECTIONS
>>
>> *(.init.rodata)
>> *(.init.rodata.*)
>> + CONSTRUCTORS
> According to the ld manual CONSTRUCTORS is only relevant for a.out,
> ECOFF and XCOFF. I'm unsure whether PE does use CONSTRUCTORS or not,
> since it's a descendant of COFF.
CONSTRUCTORS is strictly needed for the GCC coverage build to function
(hence its introduction in the first place), and any code which uses
__attribute__((constructor)) (which we use it in libxc, but not in Xen).
I'd say that the ld manual is out-of-date.
~Andrew
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel
^ permalink raw reply
* Re: [PATCH] drm/i915/execlists: Preempt-to-busy
From: Mika Kuoppala @ 2019-06-20 12:41 UTC (permalink / raw)
To: Chris Wilson, intel-gfx
In-Reply-To: <20190620082428.29524-1-chris@chris-wilson.co.uk>
Chris Wilson <chris@chris-wilson.co.uk> writes:
> When using a global seqno, we required a precise stop-the-workd event to
> handle preemption and unwind the global seqno counter. To accomplish
> this, we would preempt to a special out-of-band context and wait for the
> machine to report that it was idle. Given an idle machine, we could very
> precisely see which requests had completed and which we needed to feed
> back into the run queue.
>
> However, now that we have scrapped the global seqno, we no longer need
> to precisely unwind the global counter and only track requests by their
> per-context seqno. This allows us to loosely unwind inflight requests
> while scheduling a preemption, with the enormous caveat that the
> requests we put back on the run queue are still _inflight_ (until the
> preemption request is complete). This makes request tracking much more
> messy, as at any point then we can see a completed request that we
> believe is not currently scheduled for execution. We also have to be
> careful not to rewind RING_TAIL past RING_HEAD on preempting to the
> running context, and for this we use a semaphore to prevent completion
> of the request before continuing.
>
> To accomplish this feat, we change how we track requests scheduled to
> the HW. Instead of appending our requests onto a single list as we
> submit, we track each submission to ELSP as its own block. Then upon
> receiving the CS preemption event, we promote the pending block to the
> inflight block (discarding what was previously being tracked). As normal
> CS completion events arrive, we then remove stale entries from the
> inflight tracker.
>
> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> ---
> Skip the bonus asserts if the context is already completed.
> ---
> drivers/gpu/drm/i915/gem/i915_gem_context.c | 2 +-
> drivers/gpu/drm/i915/gt/intel_context_types.h | 5 +
> drivers/gpu/drm/i915/gt/intel_engine.h | 61 +-
> drivers/gpu/drm/i915/gt/intel_engine_cs.c | 63 +-
> drivers/gpu/drm/i915/gt/intel_engine_types.h | 52 +-
> drivers/gpu/drm/i915/gt/intel_lrc.c | 678 ++++++++----------
> drivers/gpu/drm/i915/i915_gpu_error.c | 19 +-
> drivers/gpu/drm/i915/i915_request.c | 6 +
> drivers/gpu/drm/i915/i915_request.h | 1 +
> drivers/gpu/drm/i915/i915_scheduler.c | 3 +-
> drivers/gpu/drm/i915/i915_utils.h | 12 +
> drivers/gpu/drm/i915/intel_guc_submission.c | 175 ++---
> drivers/gpu/drm/i915/selftests/i915_request.c | 8 +-
> 13 files changed, 475 insertions(+), 610 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.c b/drivers/gpu/drm/i915/gem/i915_gem_context.c
> index 0f2c22a3bcb6..35871c8a42a6 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_context.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c
> @@ -646,7 +646,7 @@ static void init_contexts(struct drm_i915_private *i915)
>
> static bool needs_preempt_context(struct drm_i915_private *i915)
> {
> - return HAS_EXECLISTS(i915);
> + return USES_GUC_SUBMISSION(i915);
> }
>
> int i915_gem_contexts_init(struct drm_i915_private *dev_priv)
> diff --git a/drivers/gpu/drm/i915/gt/intel_context_types.h b/drivers/gpu/drm/i915/gt/intel_context_types.h
> index 08049ee91cee..4c0e211c715d 100644
> --- a/drivers/gpu/drm/i915/gt/intel_context_types.h
> +++ b/drivers/gpu/drm/i915/gt/intel_context_types.h
> @@ -13,6 +13,7 @@
> #include <linux/types.h>
>
> #include "i915_active_types.h"
> +#include "i915_utils.h"
> #include "intel_engine_types.h"
> #include "intel_sseu.h"
>
> @@ -38,6 +39,10 @@ struct intel_context {
> struct i915_gem_context *gem_context;
> struct intel_engine_cs *engine;
> struct intel_engine_cs *inflight;
> +#define intel_context_inflight(ce) ptr_mask_bits((ce)->inflight, 2)
> +#define intel_context_inflight_count(ce) ptr_unmask_bits((ce)->inflight, 2)
> +#define intel_context_inflight_inc(ce) ptr_count_inc(&(ce)->inflight)
> +#define intel_context_inflight_dec(ce) ptr_count_dec(&(ce)->inflight)
Just curious here that what you consider the advantages of carrying
this info with the pointer?
>
> struct list_head signal_link;
> struct list_head signals;
> diff --git a/drivers/gpu/drm/i915/gt/intel_engine.h b/drivers/gpu/drm/i915/gt/intel_engine.h
> index 2f1c6871ee95..9bb6ff76680e 100644
> --- a/drivers/gpu/drm/i915/gt/intel_engine.h
> +++ b/drivers/gpu/drm/i915/gt/intel_engine.h
> @@ -125,71 +125,26 @@ hangcheck_action_to_str(const enum intel_engine_hangcheck_action a)
>
> void intel_engines_set_scheduler_caps(struct drm_i915_private *i915);
>
> -static inline void
> -execlists_set_active(struct intel_engine_execlists *execlists,
> - unsigned int bit)
> -{
> - __set_bit(bit, (unsigned long *)&execlists->active);
> -}
> -
> -static inline bool
> -execlists_set_active_once(struct intel_engine_execlists *execlists,
> - unsigned int bit)
> -{
> - return !__test_and_set_bit(bit, (unsigned long *)&execlists->active);
> -}
> -
> -static inline void
> -execlists_clear_active(struct intel_engine_execlists *execlists,
> - unsigned int bit)
> -{
> - __clear_bit(bit, (unsigned long *)&execlists->active);
> -}
> -
> -static inline void
> -execlists_clear_all_active(struct intel_engine_execlists *execlists)
> +static inline unsigned int
> +execlists_num_ports(const struct intel_engine_execlists * const execlists)
> {
> - execlists->active = 0;
> + return execlists->port_mask + 1;
> }
>
> -static inline bool
> -execlists_is_active(const struct intel_engine_execlists *execlists,
> - unsigned int bit)
> +static inline struct i915_request *
> +execlists_active(const struct intel_engine_execlists *execlists)
> {
> - return test_bit(bit, (unsigned long *)&execlists->active);
> + GEM_BUG_ON(execlists->active - execlists->inflight >
> + execlists_num_ports(execlists));
> + return READ_ONCE(*execlists->active);
> }
>
> -void execlists_user_begin(struct intel_engine_execlists *execlists,
> - const struct execlist_port *port);
> -void execlists_user_end(struct intel_engine_execlists *execlists);
> -
> void
> execlists_cancel_port_requests(struct intel_engine_execlists * const execlists);
>
> struct i915_request *
> execlists_unwind_incomplete_requests(struct intel_engine_execlists *execlists);
>
> -static inline unsigned int
> -execlists_num_ports(const struct intel_engine_execlists * const execlists)
> -{
> - return execlists->port_mask + 1;
> -}
> -
> -static inline struct execlist_port *
> -execlists_port_complete(struct intel_engine_execlists * const execlists,
> - struct execlist_port * const port)
> -{
> - const unsigned int m = execlists->port_mask;
> -
> - GEM_BUG_ON(port_index(port, execlists) != 0);
> - GEM_BUG_ON(!execlists_is_active(execlists, EXECLISTS_ACTIVE_USER));
> -
> - memmove(port, port + 1, m * sizeof(struct execlist_port));
> - memset(port + m, 0, sizeof(struct execlist_port));
> -
> - return port;
> -}
> -
> static inline u32
> intel_read_status_page(const struct intel_engine_cs *engine, int reg)
> {
> diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
> index 7fd33e81c2d9..d45328e254dc 100644
> --- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c
> +++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
> @@ -508,6 +508,10 @@ void intel_engine_init_execlists(struct intel_engine_cs *engine)
> GEM_BUG_ON(!is_power_of_2(execlists_num_ports(execlists)));
> GEM_BUG_ON(execlists_num_ports(execlists) > EXECLIST_MAX_PORTS);
>
> + memset(execlists->pending, 0, sizeof(execlists->pending));
> + execlists->active =
> + memset(execlists->inflight, 0, sizeof(execlists->inflight));
> +
> execlists->queue_priority_hint = INT_MIN;
> execlists->queue = RB_ROOT_CACHED;
> }
> @@ -1152,7 +1156,7 @@ bool intel_engine_is_idle(struct intel_engine_cs *engine)
> return true;
>
> /* Waiting to drain ELSP? */
> - if (READ_ONCE(engine->execlists.active)) {
> + if (execlists_active(&engine->execlists)) {
> struct tasklet_struct *t = &engine->execlists.tasklet;
>
> synchronize_hardirq(engine->i915->drm.irq);
> @@ -1169,7 +1173,7 @@ bool intel_engine_is_idle(struct intel_engine_cs *engine)
> /* Otherwise flush the tasklet if it was on another cpu */
> tasklet_unlock_wait(t);
>
> - if (READ_ONCE(engine->execlists.active))
> + if (execlists_active(&engine->execlists))
> return false;
> }
>
> @@ -1367,6 +1371,7 @@ static void intel_engine_print_registers(struct intel_engine_cs *engine,
> }
>
> if (HAS_EXECLISTS(dev_priv)) {
> + struct i915_request * const *port, *rq;
> const u32 *hws =
> &engine->status_page.addr[I915_HWS_CSB_BUF0_INDEX];
> const u8 num_entries = execlists->csb_size;
> @@ -1399,27 +1404,33 @@ static void intel_engine_print_registers(struct intel_engine_cs *engine,
> }
>
> spin_lock_irqsave(&engine->active.lock, flags);
> - for (idx = 0; idx < execlists_num_ports(execlists); idx++) {
> - struct i915_request *rq;
> - unsigned int count;
> + for (port = execlists->active; (rq = *port); port++) {
> + char hdr[80];
> + int len;
> +
> + len = snprintf(hdr, sizeof(hdr),
> + "\t\tActive[%d: ",
> + (int)(port - execlists->active));
> + if (!i915_request_signaled(rq))
> + len += snprintf(hdr + len, sizeof(hdr) - len,
> + "ring:{start:%08x, hwsp:%08x, seqno:%08x}, ",
> + i915_ggtt_offset(rq->ring->vma),
> + rq->timeline->hwsp_offset,
> + hwsp_seqno(rq));
> + snprintf(hdr + len, sizeof(hdr) - len, "rq: ");
> + print_request(m, rq, hdr);
> + }
> + for (port = execlists->pending; (rq = *port); port++) {
> char hdr[80];
>
> - rq = port_unpack(&execlists->port[idx], &count);
> - if (!rq) {
> - drm_printf(m, "\t\tELSP[%d] idle\n", idx);
> - } else if (!i915_request_signaled(rq)) {
> - snprintf(hdr, sizeof(hdr),
> - "\t\tELSP[%d] count=%d, ring:{start:%08x, hwsp:%08x, seqno:%08x}, rq: ",
> - idx, count,
> - i915_ggtt_offset(rq->ring->vma),
> - rq->timeline->hwsp_offset,
> - hwsp_seqno(rq));
> - print_request(m, rq, hdr);
> - } else {
> - print_request(m, rq, "\t\tELSP[%d] rq: ");
> - }
> + snprintf(hdr, sizeof(hdr),
> + "\t\tPending[%d] ring:{start:%08x, hwsp:%08x, seqno:%08x}, rq: ",
> + (int)(port - execlists->pending),
> + i915_ggtt_offset(rq->ring->vma),
> + rq->timeline->hwsp_offset,
> + hwsp_seqno(rq));
> + print_request(m, rq, hdr);
> }
> - drm_printf(m, "\t\tHW active? 0x%x\n", execlists->active);
> spin_unlock_irqrestore(&engine->active.lock, flags);
> } else if (INTEL_GEN(dev_priv) > 6) {
> drm_printf(m, "\tPP_DIR_BASE: 0x%08x\n",
> @@ -1583,15 +1594,19 @@ int intel_enable_engine_stats(struct intel_engine_cs *engine)
> }
>
> if (engine->stats.enabled++ == 0) {
> - const struct execlist_port *port = execlists->port;
> - unsigned int num_ports = execlists_num_ports(execlists);
> + struct i915_request * const *port;
> + struct i915_request *rq;
>
> engine->stats.enabled_at = ktime_get();
>
> /* XXX submission method oblivious? */
> - while (num_ports-- && port_isset(port)) {
> + for (port = execlists->active; (rq = *port); port++)
> engine->stats.active++;
> - port++;
> +
> + for (port = execlists->pending; (rq = *port); port++) {
> + /* Exclude any contexts already counted in active */
> + if (intel_context_inflight_count(rq->hw_context) == 1)
> + engine->stats.active++;
> }
>
> if (engine->stats.active)
> diff --git a/drivers/gpu/drm/i915/gt/intel_engine_types.h b/drivers/gpu/drm/i915/gt/intel_engine_types.h
> index 43e975a26016..411b7a807b99 100644
> --- a/drivers/gpu/drm/i915/gt/intel_engine_types.h
> +++ b/drivers/gpu/drm/i915/gt/intel_engine_types.h
> @@ -172,51 +172,10 @@ struct intel_engine_execlists {
> */
> u32 __iomem *ctrl_reg;
>
> - /**
> - * @port: execlist port states
> - *
> - * For each hardware ELSP (ExecList Submission Port) we keep
> - * track of the last request and the number of times we submitted
> - * that port to hw. We then count the number of times the hw reports
> - * a context completion or preemption. As only one context can
> - * be active on hw, we limit resubmission of context to port[0]. This
> - * is called Lite Restore, of the context.
> - */
> - struct execlist_port {
> - /**
> - * @request_count: combined request and submission count
> - */
> - struct i915_request *request_count;
> -#define EXECLIST_COUNT_BITS 2
> -#define port_request(p) ptr_mask_bits((p)->request_count, EXECLIST_COUNT_BITS)
> -#define port_count(p) ptr_unmask_bits((p)->request_count, EXECLIST_COUNT_BITS)
> -#define port_pack(rq, count) ptr_pack_bits(rq, count, EXECLIST_COUNT_BITS)
> -#define port_unpack(p, count) ptr_unpack_bits((p)->request_count, count, EXECLIST_COUNT_BITS)
> -#define port_set(p, packed) ((p)->request_count = (packed))
> -#define port_isset(p) ((p)->request_count)
> -#define port_index(p, execlists) ((p) - (execlists)->port)
> -
> - /**
> - * @context_id: context ID for port
> - */
> - GEM_DEBUG_DECL(u32 context_id);
> -
> #define EXECLIST_MAX_PORTS 2
> - } port[EXECLIST_MAX_PORTS];
> -
> - /**
> - * @active: is the HW active? We consider the HW as active after
> - * submitting any context for execution and until we have seen the
> - * last context completion event. After that, we do not expect any
> - * more events until we submit, and so can park the HW.
> - *
> - * As we have a small number of different sources from which we feed
> - * the HW, we track the state of each inside a single bitfield.
> - */
> - unsigned int active;
> -#define EXECLISTS_ACTIVE_USER 0
> -#define EXECLISTS_ACTIVE_PREEMPT 1
> -#define EXECLISTS_ACTIVE_HWACK 2
> + struct i915_request * const *active;
> + struct i915_request *inflight[EXECLIST_MAX_PORTS + 1 /* sentinel */];
> + struct i915_request *pending[EXECLIST_MAX_PORTS + 1];
>
> /**
> * @port_mask: number of execlist ports - 1
> @@ -257,11 +216,6 @@ struct intel_engine_execlists {
> */
> u32 *csb_status;
>
> - /**
> - * @preempt_complete_status: expected CSB upon completing preemption
> - */
> - u32 preempt_complete_status;
> -
> /**
> * @csb_size: context status buffer FIFO size
> */
> diff --git a/drivers/gpu/drm/i915/gt/intel_lrc.c b/drivers/gpu/drm/i915/gt/intel_lrc.c
> index 82b7ace62d97..b1e45c651660 100644
> --- a/drivers/gpu/drm/i915/gt/intel_lrc.c
> +++ b/drivers/gpu/drm/i915/gt/intel_lrc.c
> @@ -161,6 +161,8 @@
> #define GEN8_CTX_STATUS_COMPLETED_MASK \
> (GEN8_CTX_STATUS_COMPLETE | GEN8_CTX_STATUS_PREEMPTED)
>
> +#define CTX_DESC_FORCE_RESTORE BIT_ULL(2)
> +
> /* Typical size of the average request (2 pipecontrols and a MI_BB) */
> #define EXECLISTS_REQUEST_SIZE 64 /* bytes */
> #define WA_TAIL_DWORDS 2
> @@ -221,6 +223,14 @@ static void execlists_init_reg_state(u32 *reg_state,
> struct intel_engine_cs *engine,
> struct intel_ring *ring);
>
> +static inline u32 intel_hws_preempt_address(struct intel_engine_cs *engine)
> +{
> + return (i915_ggtt_offset(engine->status_page.vma) +
> + I915_GEM_HWS_PREEMPT_ADDR);
> +}
> +
> +#define ring_pause(E) ((E)->status_page.addr[I915_GEM_HWS_PREEMPT])
Scary. Please lets make a function of ring_pause and use
intel_write_status_page in it.
So I guess you have and you want squeeze the latency fruit.
When we have everything in place, CI is green and
everyone is happy, then we tear it down?
> +
> static inline struct i915_priolist *to_priolist(struct rb_node *rb)
> {
> return rb_entry(rb, struct i915_priolist, node);
> @@ -271,12 +281,6 @@ static inline bool need_preempt(const struct intel_engine_cs *engine,
> {
> int last_prio;
>
> - if (!engine->preempt_context)
> - return false;
> -
> - if (i915_request_completed(rq))
> - return false;
> -
> /*
> * Check if the current priority hint merits a preemption attempt.
> *
> @@ -338,9 +342,6 @@ __maybe_unused static inline bool
> assert_priority_queue(const struct i915_request *prev,
> const struct i915_request *next)
> {
> - const struct intel_engine_execlists *execlists =
> - &prev->engine->execlists;
> -
> /*
> * Without preemption, the prev may refer to the still active element
> * which we refuse to let go.
> @@ -348,7 +349,7 @@ assert_priority_queue(const struct i915_request *prev,
> * Even with preemption, there are times when we think it is better not
> * to preempt and leave an ostensibly lower priority request in flight.
> */
> - if (port_request(execlists->port) == prev)
> + if (i915_request_is_active(prev))
> return true;
>
> return rq_prio(prev) >= rq_prio(next);
> @@ -442,13 +443,11 @@ __unwind_incomplete_requests(struct intel_engine_cs *engine)
> struct intel_engine_cs *owner;
>
> if (i915_request_completed(rq))
> - break;
> + continue; /* XXX */
Yeah, but what is the plan with the XXX.
>
> __i915_request_unsubmit(rq);
> unwind_wa_tail(rq);
>
> - GEM_BUG_ON(rq->hw_context->inflight);
> -
> /*
> * Push the request back into the queue for later resubmission.
> * If this request is not native to this physical engine (i.e.
> @@ -500,32 +499,32 @@ execlists_context_status_change(struct i915_request *rq, unsigned long status)
> status, rq);
> }
>
> -inline void
> -execlists_user_begin(struct intel_engine_execlists *execlists,
> - const struct execlist_port *port)
> +static inline struct i915_request *
> +execlists_schedule_in(struct i915_request *rq, int idx)
> {
> - execlists_set_active_once(execlists, EXECLISTS_ACTIVE_USER);
> -}
> + struct intel_context *ce = rq->hw_context;
> + int count;
>
> -inline void
> -execlists_user_end(struct intel_engine_execlists *execlists)
> -{
> - execlists_clear_active(execlists, EXECLISTS_ACTIVE_USER);
> -}
> + trace_i915_request_in(rq, idx);
>
> -static inline void
> -execlists_context_schedule_in(struct i915_request *rq)
> -{
> - GEM_BUG_ON(rq->hw_context->inflight);
> + count = intel_context_inflight_count(ce);
> + if (!count) {
> + intel_context_get(ce);
> + ce->inflight = rq->engine;
> +
> + execlists_context_status_change(rq, INTEL_CONTEXT_SCHEDULE_IN);
> + intel_engine_context_in(ce->inflight);
> + }
>
> - execlists_context_status_change(rq, INTEL_CONTEXT_SCHEDULE_IN);
> - intel_engine_context_in(rq->engine);
> - rq->hw_context->inflight = rq->engine;
> + intel_context_inflight_inc(ce);
> + GEM_BUG_ON(intel_context_inflight(ce) != rq->engine);
> +
> + return i915_request_get(rq);
> }
>
> -static void kick_siblings(struct i915_request *rq)
> +static void kick_siblings(struct i915_request *rq, struct intel_context *ce)
> {
> - struct virtual_engine *ve = to_virtual_engine(rq->hw_context->engine);
> + struct virtual_engine *ve = container_of(ce, typeof(*ve), context);
> struct i915_request *next = READ_ONCE(ve->request);
>
> if (next && next->execution_mask & ~rq->execution_mask)
> @@ -533,29 +532,42 @@ static void kick_siblings(struct i915_request *rq)
> }
>
> static inline void
> -execlists_context_schedule_out(struct i915_request *rq, unsigned long status)
> +execlists_schedule_out(struct i915_request *rq)
> {
> - rq->hw_context->inflight = NULL;
> - intel_engine_context_out(rq->engine);
> - execlists_context_status_change(rq, status);
> + struct intel_context *ce = rq->hw_context;
> +
> + GEM_BUG_ON(!intel_context_inflight_count(ce));
> +
> trace_i915_request_out(rq);
>
> - /*
> - * If this is part of a virtual engine, its next request may have
> - * been blocked waiting for access to the active context. We have
> - * to kick all the siblings again in case we need to switch (e.g.
> - * the next request is not runnable on this engine). Hopefully,
> - * we will already have submitted the next request before the
> - * tasklet runs and do not need to rebuild each virtual tree
> - * and kick everyone again.
> - */
> - if (rq->engine != rq->hw_context->engine)
> - kick_siblings(rq);
> + intel_context_inflight_dec(ce);
> + if (!intel_context_inflight_count(ce)) {
> + intel_engine_context_out(ce->inflight);
> + execlists_context_status_change(rq, INTEL_CONTEXT_SCHEDULE_OUT);
> +
> + ce->inflight = NULL;
> + intel_context_put(ce);
> +
> + /*
> + * If this is part of a virtual engine, its next request may
> + * have been blocked waiting for access to the active context.
> + * We have to kick all the siblings again in case we need to
> + * switch (e.g. the next request is not runnable on this
> + * engine). Hopefully, we will already have submitted the next
> + * request before the tasklet runs and do not need to rebuild
> + * each virtual tree and kick everyone again.
> + */
> + if (rq->engine != ce->engine)
> + kick_siblings(rq, ce);
> + }
> +
> + i915_request_put(rq);
> }
>
> -static u64 execlists_update_context(struct i915_request *rq)
> +static u64 execlists_update_context(const struct i915_request *rq)
> {
> struct intel_context *ce = rq->hw_context;
> + u64 desc;
>
> ce->lrc_reg_state[CTX_RING_TAIL + 1] =
> intel_ring_set_tail(rq->ring, rq->tail);
> @@ -576,7 +588,11 @@ static u64 execlists_update_context(struct i915_request *rq)
> * wmb).
> */
> mb();
> - return ce->lrc_desc;
> +
> + desc = ce->lrc_desc;
> + ce->lrc_desc &= ~CTX_DESC_FORCE_RESTORE;
> +
> + return desc;
> }
>
> static inline void write_desc(struct intel_engine_execlists *execlists, u64 desc, u32 port)
> @@ -590,12 +606,59 @@ static inline void write_desc(struct intel_engine_execlists *execlists, u64 desc
> }
> }
>
> +static __maybe_unused void
> +trace_ports(const struct intel_engine_execlists *execlists,
> + const char *msg,
> + struct i915_request * const *ports)
> +{
> + const struct intel_engine_cs *engine =
> + container_of(execlists, typeof(*engine), execlists);
> +
> + GEM_TRACE("%s: %s { %llx:%lld%s, %llx:%lld }\n",
> + engine->name, msg,
> + ports[0]->fence.context,
> + ports[0]->fence.seqno,
> + i915_request_completed(ports[0]) ? "!" :
> + i915_request_started(ports[0]) ? "*" :
> + "",
> + ports[1] ? ports[1]->fence.context : 0,
> + ports[1] ? ports[1]->fence.seqno : 0);
> +}
> +
> +static __maybe_unused bool
> +assert_pending_valid(const struct intel_engine_execlists *execlists,
> + const char *msg)
> +{
> + struct i915_request * const *port, *rq;
> + struct intel_context *ce = NULL;
> +
> + trace_ports(execlists, msg, execlists->pending);
> +
> + if (execlists->pending[execlists_num_ports(execlists)])
> + return false;
> +
> + for (port = execlists->pending; (rq = *port); port++) {
> + if (ce == rq->hw_context)
> + return false;
> +
> + ce = rq->hw_context;
> + if (i915_request_completed(rq))
> + continue;
> +
> + GEM_BUG_ON(i915_active_is_idle(&ce->active));
> + GEM_BUG_ON(!i915_vma_is_pinned(ce->state));
> + }
> +
> + return ce;
> +}
> +
> static void execlists_submit_ports(struct intel_engine_cs *engine)
> {
> struct intel_engine_execlists *execlists = &engine->execlists;
> - struct execlist_port *port = execlists->port;
> unsigned int n;
>
> + GEM_BUG_ON(!assert_pending_valid(execlists, "submit"));
> +
> /*
> * We can skip acquiring intel_runtime_pm_get() here as it was taken
> * on our behalf by the request (see i915_gem_mark_busy()) and it will
> @@ -613,38 +676,16 @@ static void execlists_submit_ports(struct intel_engine_cs *engine)
> * of elsq entries, keep this in mind before changing the loop below.
> */
> for (n = execlists_num_ports(execlists); n--; ) {
> - struct i915_request *rq;
> - unsigned int count;
> - u64 desc;
> + struct i915_request *rq = execlists->pending[n];
>
> - rq = port_unpack(&port[n], &count);
> - if (rq) {
> - GEM_BUG_ON(count > !n);
> - if (!count++)
> - execlists_context_schedule_in(rq);
> - port_set(&port[n], port_pack(rq, count));
> - desc = execlists_update_context(rq);
> - GEM_DEBUG_EXEC(port[n].context_id = upper_32_bits(desc));
> -
> - GEM_TRACE("%s in[%d]: ctx=%d.%d, fence %llx:%lld (current %d), prio=%d\n",
> - engine->name, n,
> - port[n].context_id, count,
> - rq->fence.context, rq->fence.seqno,
> - hwsp_seqno(rq),
> - rq_prio(rq));
> - } else {
> - GEM_BUG_ON(!n);
> - desc = 0;
> - }
> -
> - write_desc(execlists, desc, n);
> + write_desc(execlists,
> + rq ? execlists_update_context(rq) : 0,
> + n);
> }
>
> /* we need to manually load the submit queue */
> if (execlists->ctrl_reg)
> writel(EL_CTRL_LOAD, execlists->ctrl_reg);
> -
> - execlists_clear_active(execlists, EXECLISTS_ACTIVE_HWACK);
> }
>
> static bool ctx_single_port_submission(const struct intel_context *ce)
> @@ -668,6 +709,7 @@ static bool can_merge_ctx(const struct intel_context *prev,
> static bool can_merge_rq(const struct i915_request *prev,
> const struct i915_request *next)
> {
> + GEM_BUG_ON(prev == next);
> GEM_BUG_ON(!assert_priority_queue(prev, next));
>
> if (!can_merge_ctx(prev->hw_context, next->hw_context))
> @@ -676,58 +718,6 @@ static bool can_merge_rq(const struct i915_request *prev,
> return true;
> }
>
> -static void port_assign(struct execlist_port *port, struct i915_request *rq)
> -{
> - GEM_BUG_ON(rq == port_request(port));
> -
> - if (port_isset(port))
> - i915_request_put(port_request(port));
> -
> - port_set(port, port_pack(i915_request_get(rq), port_count(port)));
> -}
> -
> -static void inject_preempt_context(struct intel_engine_cs *engine)
> -{
> - struct intel_engine_execlists *execlists = &engine->execlists;
> - struct intel_context *ce = engine->preempt_context;
> - unsigned int n;
> -
> - GEM_BUG_ON(execlists->preempt_complete_status !=
> - upper_32_bits(ce->lrc_desc));
> -
> - /*
> - * Switch to our empty preempt context so
> - * the state of the GPU is known (idle).
> - */
> - GEM_TRACE("%s\n", engine->name);
> - for (n = execlists_num_ports(execlists); --n; )
> - write_desc(execlists, 0, n);
> -
> - write_desc(execlists, ce->lrc_desc, n);
> -
> - /* we need to manually load the submit queue */
> - if (execlists->ctrl_reg)
> - writel(EL_CTRL_LOAD, execlists->ctrl_reg);
> -
> - execlists_clear_active(execlists, EXECLISTS_ACTIVE_HWACK);
> - execlists_set_active(execlists, EXECLISTS_ACTIVE_PREEMPT);
> -
> - (void)I915_SELFTEST_ONLY(execlists->preempt_hang.count++);
> -}
> -
> -static void complete_preempt_context(struct intel_engine_execlists *execlists)
> -{
> - GEM_BUG_ON(!execlists_is_active(execlists, EXECLISTS_ACTIVE_PREEMPT));
> -
> - if (inject_preempt_hang(execlists))
> - return;
> -
> - execlists_cancel_port_requests(execlists);
> - __unwind_incomplete_requests(container_of(execlists,
> - struct intel_engine_cs,
> - execlists));
> -}
> -
> static void virtual_update_register_offsets(u32 *regs,
> struct intel_engine_cs *engine)
> {
> @@ -792,7 +782,7 @@ static bool virtual_matches(const struct virtual_engine *ve,
> * we reuse the register offsets). This is a very small
> * hystersis on the greedy seelction algorithm.
> */
> - inflight = READ_ONCE(ve->context.inflight);
> + inflight = intel_context_inflight(&ve->context);
> if (inflight && inflight != engine)
> return false;
>
> @@ -815,13 +805,23 @@ static void virtual_xfer_breadcrumbs(struct virtual_engine *ve,
> spin_unlock(&old->breadcrumbs.irq_lock);
> }
>
> +static struct i915_request *
> +last_active(const struct intel_engine_execlists *execlists)
> +{
> + struct i915_request * const *last = execlists->active;
> +
> + while (*last && i915_request_completed(*last))
> + last++;
> +
> + return *last;
> +}
> +
> static void execlists_dequeue(struct intel_engine_cs *engine)
> {
> struct intel_engine_execlists * const execlists = &engine->execlists;
> - struct execlist_port *port = execlists->port;
> - const struct execlist_port * const last_port =
> - &execlists->port[execlists->port_mask];
> - struct i915_request *last = port_request(port);
> + struct i915_request **port = execlists->pending;
> + struct i915_request ** const last_port = port + execlists->port_mask;
> + struct i915_request *last;
> struct rb_node *rb;
> bool submit = false;
>
> @@ -867,65 +867,72 @@ static void execlists_dequeue(struct intel_engine_cs *engine)
> break;
> }
>
> + /*
> + * If the queue is higher priority than the last
> + * request in the currently active context, submit afresh.
> + * We will resubmit again afterwards in case we need to split
> + * the active context to interject the preemption request,
> + * i.e. we will retrigger preemption following the ack in case
> + * of trouble.
> + */
> + last = last_active(execlists);
> if (last) {
> - /*
> - * Don't resubmit or switch until all outstanding
> - * preemptions (lite-restore) are seen. Then we
> - * know the next preemption status we see corresponds
> - * to this ELSP update.
> - */
> - GEM_BUG_ON(!execlists_is_active(execlists,
> - EXECLISTS_ACTIVE_USER));
> - GEM_BUG_ON(!port_count(&port[0]));
> -
> - /*
> - * If we write to ELSP a second time before the HW has had
> - * a chance to respond to the previous write, we can confuse
> - * the HW and hit "undefined behaviour". After writing to ELSP,
> - * we must then wait until we see a context-switch event from
> - * the HW to indicate that it has had a chance to respond.
> - */
> - if (!execlists_is_active(execlists, EXECLISTS_ACTIVE_HWACK))
> - return;
> -
> if (need_preempt(engine, last, rb)) {
> - inject_preempt_context(engine);
> - return;
> - }
> + GEM_TRACE("%s: preempting last=%llx:%lld, prio=%d, hint=%d\n",
> + engine->name,
> + last->fence.context,
> + last->fence.seqno,
> + last->sched.attr.priority,
> + execlists->queue_priority_hint);
> + /*
> + * Don't let the RING_HEAD advance past the breadcrumb
> + * as we unwind (and until we resubmit) so that we do
> + * not accidentally tell it to go backwards.
> + */
> + ring_pause(engine) = 1;
>
> - /*
> - * In theory, we could coalesce more requests onto
> - * the second port (the first port is active, with
> - * no preemptions pending). However, that means we
> - * then have to deal with the possible lite-restore
> - * of the second port (as we submit the ELSP, there
> - * may be a context-switch) but also we may complete
> - * the resubmission before the context-switch. Ergo,
> - * coalescing onto the second port will cause a
> - * preemption event, but we cannot predict whether
> - * that will affect port[0] or port[1].
> - *
> - * If the second port is already active, we can wait
> - * until the next context-switch before contemplating
> - * new requests. The GPU will be busy and we should be
> - * able to resubmit the new ELSP before it idles,
> - * avoiding pipeline bubbles (momentary pauses where
> - * the driver is unable to keep up the supply of new
> - * work). However, we have to double check that the
> - * priorities of the ports haven't been switch.
> - */
> - if (port_count(&port[1]))
> - return;
> + /*
> + * Note that we have not stopped the GPU at this point,
> + * so we are unwinding the incomplete requests as they
> + * remain inflight and so by the time we do complete
> + * the preemption, some of the unwound requests may
> + * complete!
> + */
> + __unwind_incomplete_requests(engine);
>
> - /*
> - * WaIdleLiteRestore:bdw,skl
> - * Apply the wa NOOPs to prevent
> - * ring:HEAD == rq:TAIL as we resubmit the
> - * request. See gen8_emit_fini_breadcrumb() for
> - * where we prepare the padding after the
> - * end of the request.
> - */
> - last->tail = last->wa_tail;
> + /*
> + * If we need to return to the preempted context, we
> + * need to skip the lite-restore and force it to
> + * reload the RING_TAIL. Otherwise, the HW has a
> + * tendency to ignore us rewinding the TAIL to the
> + * end of an earlier request.
> + */
> + last->hw_context->lrc_desc |= CTX_DESC_FORCE_RESTORE;
> + last = NULL;
> + } else {
> + /*
> + * Otherwise if we already have a request pending
> + * for execution after the current one, we can
> + * just wait until the next CS event before
> + * queuing more. In either case we will force a
> + * lite-restore preemption event, but if we wait
> + * we hopefully coalesce several updates into a single
> + * submission.
> + */
> + if (!list_is_last(&last->sched.link,
> + &engine->active.requests))
> + return;
> +
> + /*
> + * WaIdleLiteRestore:bdw,skl
> + * Apply the wa NOOPs to prevent
> + * ring:HEAD == rq:TAIL as we resubmit the
> + * request. See gen8_emit_fini_breadcrumb() for
> + * where we prepare the padding after the
> + * end of the request.
> + */
> + last->tail = last->wa_tail;
> + }
> }
>
> while (rb) { /* XXX virtual is always taking precedence */
> @@ -955,9 +962,24 @@ static void execlists_dequeue(struct intel_engine_cs *engine)
> continue;
> }
>
> + if (i915_request_completed(rq)) {
> + ve->request = NULL;
> + ve->base.execlists.queue_priority_hint = INT_MIN;
> + rb_erase_cached(rb, &execlists->virtual);
> + RB_CLEAR_NODE(rb);
> +
> + rq->engine = engine;
> + __i915_request_submit(rq);
> +
> + spin_unlock(&ve->base.active.lock);
> +
> + rb = rb_first_cached(&execlists->virtual);
> + continue;
> + }
> +
> if (last && !can_merge_rq(last, rq)) {
> spin_unlock(&ve->base.active.lock);
> - return; /* leave this rq for another engine */
> + return; /* leave this for another */
> }
>
> GEM_TRACE("%s: virtual rq=%llx:%lld%s, new engine? %s\n",
> @@ -1006,9 +1028,10 @@ static void execlists_dequeue(struct intel_engine_cs *engine)
> }
>
> __i915_request_submit(rq);
> - trace_i915_request_in(rq, port_index(port, execlists));
> - submit = true;
> - last = rq;
> + if (!i915_request_completed(rq)) {
> + submit = true;
> + last = rq;
> + }
> }
>
> spin_unlock(&ve->base.active.lock);
> @@ -1021,6 +1044,9 @@ static void execlists_dequeue(struct intel_engine_cs *engine)
> int i;
>
> priolist_for_each_request_consume(rq, rn, p, i) {
> + if (i915_request_completed(rq))
> + goto skip;
> +
> /*
> * Can we combine this request with the current port?
> * It has to be the same context/ringbuffer and not
> @@ -1060,19 +1086,14 @@ static void execlists_dequeue(struct intel_engine_cs *engine)
> ctx_single_port_submission(rq->hw_context))
> goto done;
>
> -
> - if (submit)
> - port_assign(port, last);
> + *port = execlists_schedule_in(last, port - execlists->pending);
> port++;
> -
> - GEM_BUG_ON(port_isset(port));
> }
>
> - __i915_request_submit(rq);
> - trace_i915_request_in(rq, port_index(port, execlists));
> -
> last = rq;
> submit = true;
> +skip:
> + __i915_request_submit(rq);
> }
>
> rb_erase_cached(&p->node, &execlists->queue);
> @@ -1097,54 +1118,30 @@ static void execlists_dequeue(struct intel_engine_cs *engine)
> * interrupt for secondary ports).
> */
> execlists->queue_priority_hint = queue_prio(execlists);
> + GEM_TRACE("%s: queue_priority_hint:%d, submit:%s\n",
> + engine->name, execlists->queue_priority_hint,
> + yesno(submit));
>
> if (submit) {
> - port_assign(port, last);
> + *port = execlists_schedule_in(last, port - execlists->pending);
> + memset(port + 1, 0, (last_port - port) * sizeof(*port));
> execlists_submit_ports(engine);
> }
> -
> - /* We must always keep the beast fed if we have work piled up */
> - GEM_BUG_ON(rb_first_cached(&execlists->queue) &&
> - !port_isset(execlists->port));
> -
> - /* Re-evaluate the executing context setup after each preemptive kick */
> - if (last)
> - execlists_user_begin(execlists, execlists->port);
> -
> - /* If the engine is now idle, so should be the flag; and vice versa. */
> - GEM_BUG_ON(execlists_is_active(&engine->execlists,
> - EXECLISTS_ACTIVE_USER) ==
> - !port_isset(engine->execlists.port));
> }
>
> void
> execlists_cancel_port_requests(struct intel_engine_execlists * const execlists)
> {
> - struct execlist_port *port = execlists->port;
> - unsigned int num_ports = execlists_num_ports(execlists);
> -
> - while (num_ports-- && port_isset(port)) {
> - struct i915_request *rq = port_request(port);
> -
> - GEM_TRACE("%s:port%u fence %llx:%lld, (current %d)\n",
> - rq->engine->name,
> - (unsigned int)(port - execlists->port),
> - rq->fence.context, rq->fence.seqno,
> - hwsp_seqno(rq));
> + struct i915_request * const *port, *rq;
>
> - GEM_BUG_ON(!execlists->active);
> - execlists_context_schedule_out(rq,
> - i915_request_completed(rq) ?
> - INTEL_CONTEXT_SCHEDULE_OUT :
> - INTEL_CONTEXT_SCHEDULE_PREEMPTED);
> + for (port = execlists->pending; (rq = *port); port++)
> + execlists_schedule_out(rq);
> + memset(execlists->pending, 0, sizeof(execlists->pending));
>
> - i915_request_put(rq);
> -
> - memset(port, 0, sizeof(*port));
> - port++;
> - }
> -
> - execlists_clear_all_active(execlists);
> + for (port = execlists->active; (rq = *port); port++)
> + execlists_schedule_out(rq);
> + execlists->active =
> + memset(execlists->inflight, 0, sizeof(execlists->inflight));
> }
>
> static inline void
> @@ -1163,7 +1160,6 @@ reset_in_progress(const struct intel_engine_execlists *execlists)
> static void process_csb(struct intel_engine_cs *engine)
> {
> struct intel_engine_execlists * const execlists = &engine->execlists;
> - struct execlist_port *port = execlists->port;
> const u32 * const buf = execlists->csb_status;
> const u8 num_entries = execlists->csb_size;
> u8 head, tail;
> @@ -1198,9 +1194,7 @@ static void process_csb(struct intel_engine_cs *engine)
> rmb();
>
> do {
> - struct i915_request *rq;
> unsigned int status;
> - unsigned int count;
>
> if (++head == num_entries)
> head = 0;
> @@ -1223,68 +1217,37 @@ static void process_csb(struct intel_engine_cs *engine)
> * status notifier.
> */
>
> - GEM_TRACE("%s csb[%d]: status=0x%08x:0x%08x, active=0x%x\n",
> + GEM_TRACE("%s csb[%d]: status=0x%08x:0x%08x\n",
> engine->name, head,
> - buf[2 * head + 0], buf[2 * head + 1],
> - execlists->active);
> + buf[2 * head + 0], buf[2 * head + 1]);
>
> status = buf[2 * head];
> - if (status & (GEN8_CTX_STATUS_IDLE_ACTIVE |
> - GEN8_CTX_STATUS_PREEMPTED))
> - execlists_set_active(execlists,
> - EXECLISTS_ACTIVE_HWACK);
> - if (status & GEN8_CTX_STATUS_ACTIVE_IDLE)
> - execlists_clear_active(execlists,
> - EXECLISTS_ACTIVE_HWACK);
> -
> - if (!(status & GEN8_CTX_STATUS_COMPLETED_MASK))
> - continue;
> + if (status & GEN8_CTX_STATUS_IDLE_ACTIVE) {
> +promote:
> + GEM_BUG_ON(!assert_pending_valid(execlists, "promote"));
> + execlists->active =
> + memcpy(execlists->inflight,
> + execlists->pending,
> + execlists_num_ports(execlists) *
> + sizeof(*execlists->pending));
> + execlists->pending[0] = NULL;
I can't decide if comment or a helper inline function would
serve better as documentation of between inflight and pending
movement.
I guess it is better to be left as a future work after
the dust settles.
Just general yearning for a similar kind of level of documentation
steps as in dequeue.
>
> - /* We should never get a COMPLETED | IDLE_ACTIVE! */
> - GEM_BUG_ON(status & GEN8_CTX_STATUS_IDLE_ACTIVE);
Is our assert coverage going to suffer?
> + if (!inject_preempt_hang(execlists))
> + ring_pause(engine) = 0;
> + } else if (status & GEN8_CTX_STATUS_PREEMPTED) {
> + struct i915_request * const *port = execlists->active;
>
> - if (status & GEN8_CTX_STATUS_COMPLETE &&
> - buf[2*head + 1] == execlists->preempt_complete_status) {
> - GEM_TRACE("%s preempt-idle\n", engine->name);
> - complete_preempt_context(execlists);
> - continue;
> - }
> -
> - if (status & GEN8_CTX_STATUS_PREEMPTED &&
> - execlists_is_active(execlists,
> - EXECLISTS_ACTIVE_PREEMPT))
> - continue;
> + trace_ports(execlists, "preempted", execlists->active);
>
> - GEM_BUG_ON(!execlists_is_active(execlists,
> - EXECLISTS_ACTIVE_USER));
> + while (*port)
> + execlists_schedule_out(*port++);
>
> - rq = port_unpack(port, &count);
> - GEM_TRACE("%s out[0]: ctx=%d.%d, fence %llx:%lld (current %d), prio=%d\n",
> - engine->name,
> - port->context_id, count,
> - rq ? rq->fence.context : 0,
> - rq ? rq->fence.seqno : 0,
> - rq ? hwsp_seqno(rq) : 0,
> - rq ? rq_prio(rq) : 0);
> + goto promote;
> + } else if (*execlists->active) {
> + struct i915_request *rq = *execlists->active++;
>
> - /* Check the context/desc id for this event matches */
> - GEM_DEBUG_BUG_ON(buf[2 * head + 1] != port->context_id);
> -
> - GEM_BUG_ON(count == 0);
> - if (--count == 0) {
> - /*
> - * On the final event corresponding to the
> - * submission of this context, we expect either
> - * an element-switch event or a completion
> - * event (and on completion, the active-idle
> - * marker). No more preemptions, lite-restore
> - * or otherwise.
> - */
> - GEM_BUG_ON(status & GEN8_CTX_STATUS_PREEMPTED);
> - GEM_BUG_ON(port_isset(&port[1]) &&
> - !(status & GEN8_CTX_STATUS_ELEMENT_SWITCH));
> - GEM_BUG_ON(!port_isset(&port[1]) &&
> - !(status & GEN8_CTX_STATUS_ACTIVE_IDLE));
> + trace_ports(execlists, "completed",
> + execlists->active - 1);
>
> /*
> * We rely on the hardware being strongly
> @@ -1293,21 +1256,10 @@ static void process_csb(struct intel_engine_cs *engine)
> * user interrupt and CSB is processed.
> */
> GEM_BUG_ON(!i915_request_completed(rq));
> + execlists_schedule_out(rq);
>
> - execlists_context_schedule_out(rq,
> - INTEL_CONTEXT_SCHEDULE_OUT);
> - i915_request_put(rq);
> -
> - GEM_TRACE("%s completed ctx=%d\n",
> - engine->name, port->context_id);
> -
> - port = execlists_port_complete(execlists, port);
> - if (port_isset(port))
> - execlists_user_begin(execlists, port);
> - else
> - execlists_user_end(execlists);
> - } else {
> - port_set(port, port_pack(rq, count));
> + GEM_BUG_ON(execlists->active - execlists->inflight >
> + execlists_num_ports(execlists));
> }
> } while (head != tail);
>
> @@ -1332,7 +1284,7 @@ static void __execlists_submission_tasklet(struct intel_engine_cs *const engine)
> lockdep_assert_held(&engine->active.lock);
>
> process_csb(engine);
> - if (!execlists_is_active(&engine->execlists, EXECLISTS_ACTIVE_PREEMPT))
> + if (!engine->execlists.pending[0])
> execlists_dequeue(engine);
> }
>
> @@ -1345,11 +1297,6 @@ static void execlists_submission_tasklet(unsigned long data)
> struct intel_engine_cs * const engine = (struct intel_engine_cs *)data;
> unsigned long flags;
>
> - GEM_TRACE("%s awake?=%d, active=%x\n",
> - engine->name,
> - !!intel_wakeref_active(&engine->wakeref),
> - engine->execlists.active);
> -
> spin_lock_irqsave(&engine->active.lock, flags);
> __execlists_submission_tasklet(engine);
> spin_unlock_irqrestore(&engine->active.lock, flags);
> @@ -1376,12 +1323,16 @@ static void __submit_queue_imm(struct intel_engine_cs *engine)
> tasklet_hi_schedule(&execlists->tasklet);
> }
>
> -static void submit_queue(struct intel_engine_cs *engine, int prio)
> +static void submit_queue(struct intel_engine_cs *engine,
> + const struct i915_request *rq)
> {
> - if (prio > engine->execlists.queue_priority_hint) {
> - engine->execlists.queue_priority_hint = prio;
> - __submit_queue_imm(engine);
> - }
> + struct intel_engine_execlists *execlists = &engine->execlists;
> +
> + if (rq_prio(rq) <= execlists->queue_priority_hint)
> + return;
> +
> + execlists->queue_priority_hint = rq_prio(rq);
> + __submit_queue_imm(engine);
> }
>
> static void execlists_submit_request(struct i915_request *request)
> @@ -1397,7 +1348,7 @@ static void execlists_submit_request(struct i915_request *request)
> GEM_BUG_ON(RB_EMPTY_ROOT(&engine->execlists.queue.rb_root));
> GEM_BUG_ON(list_empty(&request->sched.link));
>
> - submit_queue(engine, rq_prio(request));
> + submit_queue(engine, request);
>
> spin_unlock_irqrestore(&engine->active.lock, flags);
> }
> @@ -2048,27 +1999,13 @@ static void execlists_reset_prepare(struct intel_engine_cs *engine)
> spin_unlock_irqrestore(&engine->active.lock, flags);
> }
>
> -static bool lrc_regs_ok(const struct i915_request *rq)
> -{
> - const struct intel_ring *ring = rq->ring;
> - const u32 *regs = rq->hw_context->lrc_reg_state;
> -
> - /* Quick spot check for the common signs of context corruption */
> -
> - if (regs[CTX_RING_BUFFER_CONTROL + 1] !=
> - (RING_CTL_SIZE(ring->size) | RING_VALID))
> - return false;
> -
> - if (regs[CTX_RING_BUFFER_START + 1] != i915_ggtt_offset(ring->vma))
> - return false;
> -
> - return true;
> -}
> -
> -static void reset_csb_pointers(struct intel_engine_execlists *execlists)
> +static void reset_csb_pointers(struct intel_engine_cs *engine)
> {
> + struct intel_engine_execlists * const execlists = &engine->execlists;
> const unsigned int reset_value = execlists->csb_size - 1;
>
> + ring_pause(engine) = 0;
> +
> /*
> * After a reset, the HW starts writing into CSB entry [0]. We
> * therefore have to set our HEAD pointer back one entry so that
> @@ -2115,18 +2052,21 @@ static void __execlists_reset(struct intel_engine_cs *engine, bool stalled)
> process_csb(engine); /* drain preemption events */
>
> /* Following the reset, we need to reload the CSB read/write pointers */
> - reset_csb_pointers(&engine->execlists);
> + reset_csb_pointers(engine);
>
> /*
> * Save the currently executing context, even if we completed
> * its request, it was still running at the time of the
> * reset and will have been clobbered.
> */
> - if (!port_isset(execlists->port))
> - goto out_clear;
> + rq = execlists_active(execlists);
> + if (!rq)
> + return;
>
> - rq = port_request(execlists->port);
> ce = rq->hw_context;
> + GEM_BUG_ON(i915_active_is_idle(&ce->active));
> + GEM_BUG_ON(!i915_vma_is_pinned(ce->state));
> + rq = active_request(rq);
>
> /*
> * Catch up with any missed context-switch interrupts.
> @@ -2139,9 +2079,12 @@ static void __execlists_reset(struct intel_engine_cs *engine, bool stalled)
> */
> execlists_cancel_port_requests(execlists);
>
> - rq = active_request(rq);
> - if (!rq)
> + if (!rq) {
> + ce->ring->head = ce->ring->tail;
> goto out_replay;
> + }
> +
> + ce->ring->head = intel_ring_wrap(ce->ring, rq->head);
>
> /*
> * If this request hasn't started yet, e.g. it is waiting on a
> @@ -2155,7 +2098,7 @@ static void __execlists_reset(struct intel_engine_cs *engine, bool stalled)
> * Otherwise, if we have not started yet, the request should replay
> * perfectly and we do not need to flag the result as being erroneous.
> */
> - if (!i915_request_started(rq) && lrc_regs_ok(rq))
> + if (!i915_request_started(rq))
> goto out_replay;
>
> /*
> @@ -2170,7 +2113,7 @@ static void __execlists_reset(struct intel_engine_cs *engine, bool stalled)
> * image back to the expected values to skip over the guilty request.
> */
> i915_reset_request(rq, stalled);
> - if (!stalled && lrc_regs_ok(rq))
> + if (!stalled)
> goto out_replay;
>
> /*
> @@ -2190,17 +2133,13 @@ static void __execlists_reset(struct intel_engine_cs *engine, bool stalled)
> execlists_init_reg_state(regs, ce, engine, ce->ring);
>
> out_replay:
> - /* Rerun the request; its payload has been neutered (if guilty). */
> - ce->ring->head =
> - rq ? intel_ring_wrap(ce->ring, rq->head) : ce->ring->tail;
> + GEM_TRACE("%s replay {head:%04x, tail:%04x\n",
> + engine->name, ce->ring->head, ce->ring->tail);
> intel_ring_update_space(ce->ring);
> __execlists_update_reg_state(ce, engine);
>
> /* Push back any incomplete requests for replay after the reset. */
> __unwind_incomplete_requests(engine);
> -
> -out_clear:
> - execlists_clear_all_active(execlists);
> }
>
> static void execlists_reset(struct intel_engine_cs *engine, bool stalled)
> @@ -2296,7 +2235,6 @@ static void execlists_cancel_requests(struct intel_engine_cs *engine)
>
> execlists->queue_priority_hint = INT_MIN;
> execlists->queue = RB_ROOT_CACHED;
> - GEM_BUG_ON(port_isset(execlists->port));
>
> GEM_BUG_ON(__tasklet_is_enabled(&execlists->tasklet));
> execlists->tasklet.func = nop_submission_tasklet;
> @@ -2514,15 +2452,29 @@ static u32 *gen8_emit_wa_tail(struct i915_request *request, u32 *cs)
> return cs;
> }
>
> +static u32 *emit_preempt_busywait(struct i915_request *request, u32 *cs)
> +{
> + *cs++ = MI_SEMAPHORE_WAIT |
> + MI_SEMAPHORE_GLOBAL_GTT |
> + MI_SEMAPHORE_POLL |
> + MI_SEMAPHORE_SAD_EQ_SDD;
> + *cs++ = 0;
> + *cs++ = intel_hws_preempt_address(request->engine);
> + *cs++ = 0;
> +
> + return cs;
> +}
> +
> static u32 *gen8_emit_fini_breadcrumb(struct i915_request *request, u32 *cs)
> {
> cs = gen8_emit_ggtt_write(cs,
> request->fence.seqno,
> request->timeline->hwsp_offset,
> 0);
> -
> *cs++ = MI_USER_INTERRUPT;
> +
> *cs++ = MI_ARB_ON_OFF | MI_ARB_ENABLE;
This was discussed in irc, could warrant a comment here of
why this is needed. Precious info.
> + cs = emit_preempt_busywait(request, cs);
>
> request->tail = intel_ring_offset(request, cs);
> assert_ring_tail_valid(request->ring, request->tail);
> @@ -2543,9 +2495,10 @@ static u32 *gen8_emit_fini_breadcrumb_rcs(struct i915_request *request, u32 *cs)
> PIPE_CONTROL_FLUSH_ENABLE |
> PIPE_CONTROL_CS_STALL,
> 0);
> -
> *cs++ = MI_USER_INTERRUPT;
> +
> *cs++ = MI_ARB_ON_OFF | MI_ARB_ENABLE;
Comment could be copied here. Or a common helper created for common parts.
-Mika
> + cs = emit_preempt_busywait(request, cs);
>
> request->tail = intel_ring_offset(request, cs);
> assert_ring_tail_valid(request->ring, request->tail);
> @@ -2594,8 +2547,7 @@ void intel_execlists_set_default_submission(struct intel_engine_cs *engine)
> engine->flags |= I915_ENGINE_SUPPORTS_STATS;
> if (!intel_vgpu_active(engine->i915))
> engine->flags |= I915_ENGINE_HAS_SEMAPHORES;
> - if (engine->preempt_context &&
> - HAS_LOGICAL_RING_PREEMPTION(engine->i915))
> + if (HAS_LOGICAL_RING_PREEMPTION(engine->i915))
> engine->flags |= I915_ENGINE_HAS_PREEMPTION;
> }
>
> @@ -2718,11 +2670,6 @@ int intel_execlists_submission_init(struct intel_engine_cs *engine)
> i915_mmio_reg_offset(RING_ELSP(base));
> }
>
> - execlists->preempt_complete_status = ~0u;
> - if (engine->preempt_context)
> - execlists->preempt_complete_status =
> - upper_32_bits(engine->preempt_context->lrc_desc);
> -
> execlists->csb_status =
> &engine->status_page.addr[I915_HWS_CSB_BUF0_INDEX];
>
> @@ -2734,7 +2681,7 @@ int intel_execlists_submission_init(struct intel_engine_cs *engine)
> else
> execlists->csb_size = GEN11_CSB_ENTRIES;
>
> - reset_csb_pointers(execlists);
> + reset_csb_pointers(engine);
>
> return 0;
> }
> @@ -2917,11 +2864,6 @@ populate_lr_context(struct intel_context *ce,
> if (!engine->default_state)
> regs[CTX_CONTEXT_CONTROL + 1] |=
> _MASKED_BIT_ENABLE(CTX_CTRL_ENGINE_CTX_RESTORE_INHIBIT);
> - if (ce->gem_context == engine->i915->preempt_context &&
> - INTEL_GEN(engine->i915) < 11)
> - regs[CTX_CONTEXT_CONTROL + 1] |=
> - _MASKED_BIT_ENABLE(CTX_CTRL_ENGINE_CTX_RESTORE_INHIBIT |
> - CTX_CTRL_ENGINE_CTX_SAVE_INHIBIT);
>
> ret = 0;
> err_unpin_ctx:
> diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c
> index b7e9fddef270..a497cf7acb6a 100644
> --- a/drivers/gpu/drm/i915/i915_gpu_error.c
> +++ b/drivers/gpu/drm/i915/i915_gpu_error.c
> @@ -1248,10 +1248,10 @@ static void error_record_engine_registers(struct i915_gpu_state *error,
> }
> }
>
> -static void record_request(struct i915_request *request,
> +static void record_request(const struct i915_request *request,
> struct drm_i915_error_request *erq)
> {
> - struct i915_gem_context *ctx = request->gem_context;
> + const struct i915_gem_context *ctx = request->gem_context;
>
> erq->flags = request->fence.flags;
> erq->context = request->fence.context;
> @@ -1315,20 +1315,15 @@ static void engine_record_requests(struct intel_engine_cs *engine,
> ee->num_requests = count;
> }
>
> -static void error_record_engine_execlists(struct intel_engine_cs *engine,
> +static void error_record_engine_execlists(const struct intel_engine_cs *engine,
> struct drm_i915_error_engine *ee)
> {
> const struct intel_engine_execlists * const execlists = &engine->execlists;
> - unsigned int n;
> + struct i915_request * const *port = execlists->active;
> + unsigned int n = 0;
>
> - for (n = 0; n < execlists_num_ports(execlists); n++) {
> - struct i915_request *rq = port_request(&execlists->port[n]);
> -
> - if (!rq)
> - break;
> -
> - record_request(rq, &ee->execlist[n]);
> - }
> + while (*port)
> + record_request(*port++, &ee->execlist[n++]);
>
> ee->num_ports = n;
> }
> diff --git a/drivers/gpu/drm/i915/i915_request.c b/drivers/gpu/drm/i915/i915_request.c
> index 7083e6ab92c5..0c99694faab7 100644
> --- a/drivers/gpu/drm/i915/i915_request.c
> +++ b/drivers/gpu/drm/i915/i915_request.c
> @@ -276,6 +276,12 @@ static bool i915_request_retire(struct i915_request *rq)
>
> local_irq_disable();
>
> + /*
> + * We only loosely track inflight requests across preemption,
> + * and so we may find ourselves attempting to retire a _completed_
> + * request that we have removed from the HW and put back on a run
> + * queue.
> + */
> spin_lock(&rq->engine->active.lock);
> list_del(&rq->sched.link);
> spin_unlock(&rq->engine->active.lock);
> diff --git a/drivers/gpu/drm/i915/i915_request.h b/drivers/gpu/drm/i915/i915_request.h
> index edbbdfec24ab..bebc1e9b4a5e 100644
> --- a/drivers/gpu/drm/i915/i915_request.h
> +++ b/drivers/gpu/drm/i915/i915_request.h
> @@ -28,6 +28,7 @@
> #include <linux/dma-fence.h>
> #include <linux/lockdep.h>
>
> +#include "gt/intel_context_types.h"
> #include "gt/intel_engine_types.h"
>
> #include "i915_gem.h"
> diff --git a/drivers/gpu/drm/i915/i915_scheduler.c b/drivers/gpu/drm/i915/i915_scheduler.c
> index 2e9b38bdc33c..b1ba3e65cd52 100644
> --- a/drivers/gpu/drm/i915/i915_scheduler.c
> +++ b/drivers/gpu/drm/i915/i915_scheduler.c
> @@ -179,8 +179,7 @@ static inline int rq_prio(const struct i915_request *rq)
>
> static void kick_submission(struct intel_engine_cs *engine, int prio)
> {
> - const struct i915_request *inflight =
> - port_request(engine->execlists.port);
> + const struct i915_request *inflight = *engine->execlists.active;
>
> /*
> * If we are already the currently executing context, don't
> diff --git a/drivers/gpu/drm/i915/i915_utils.h b/drivers/gpu/drm/i915/i915_utils.h
> index 2987219a6300..4920ff9aba62 100644
> --- a/drivers/gpu/drm/i915/i915_utils.h
> +++ b/drivers/gpu/drm/i915/i915_utils.h
> @@ -131,6 +131,18 @@ __check_struct_size(size_t base, size_t arr, size_t count, size_t *size)
> ((typeof(ptr))((unsigned long)(ptr) | __bits)); \
> })
>
> +#define ptr_count_dec(p_ptr) do { \
> + typeof(p_ptr) __p = (p_ptr); \
> + unsigned long __v = (unsigned long)(*__p); \
> + *__p = (typeof(*p_ptr))(--__v); \
> +} while (0)
> +
> +#define ptr_count_inc(p_ptr) do { \
> + typeof(p_ptr) __p = (p_ptr); \
> + unsigned long __v = (unsigned long)(*__p); \
> + *__p = (typeof(*p_ptr))(++__v); \
> +} while (0)
> +
> #define page_mask_bits(ptr) ptr_mask_bits(ptr, PAGE_SHIFT)
> #define page_unmask_bits(ptr) ptr_unmask_bits(ptr, PAGE_SHIFT)
> #define page_pack_bits(ptr, bits) ptr_pack_bits(ptr, bits, PAGE_SHIFT)
> diff --git a/drivers/gpu/drm/i915/intel_guc_submission.c b/drivers/gpu/drm/i915/intel_guc_submission.c
> index db531ebc7704..12c22359fdac 100644
> --- a/drivers/gpu/drm/i915/intel_guc_submission.c
> +++ b/drivers/gpu/drm/i915/intel_guc_submission.c
> @@ -32,7 +32,11 @@
> #include "intel_guc_submission.h"
> #include "i915_drv.h"
>
> -#define GUC_PREEMPT_FINISHED 0x1
> +enum {
> + GUC_PREEMPT_NONE = 0,
> + GUC_PREEMPT_INPROGRESS,
> + GUC_PREEMPT_FINISHED,
> +};
> #define GUC_PREEMPT_BREADCRUMB_DWORDS 0x8
> #define GUC_PREEMPT_BREADCRUMB_BYTES \
> (sizeof(u32) * GUC_PREEMPT_BREADCRUMB_DWORDS)
> @@ -537,15 +541,11 @@ static void guc_add_request(struct intel_guc *guc, struct i915_request *rq)
> u32 ctx_desc = lower_32_bits(rq->hw_context->lrc_desc);
> u32 ring_tail = intel_ring_set_tail(rq->ring, rq->tail) / sizeof(u64);
>
> - spin_lock(&client->wq_lock);
> -
> guc_wq_item_append(client, engine->guc_id, ctx_desc,
> ring_tail, rq->fence.seqno);
> guc_ring_doorbell(client);
>
> client->submissions[engine->id] += 1;
> -
> - spin_unlock(&client->wq_lock);
> }
>
> /*
> @@ -631,8 +631,9 @@ static void inject_preempt_context(struct work_struct *work)
> data[6] = intel_guc_ggtt_offset(guc, guc->shared_data);
>
> if (WARN_ON(intel_guc_send(guc, data, ARRAY_SIZE(data)))) {
> - execlists_clear_active(&engine->execlists,
> - EXECLISTS_ACTIVE_PREEMPT);
> + intel_write_status_page(engine,
> + I915_GEM_HWS_PREEMPT,
> + GUC_PREEMPT_NONE);
> tasklet_schedule(&engine->execlists.tasklet);
> }
>
> @@ -672,8 +673,6 @@ static void complete_preempt_context(struct intel_engine_cs *engine)
> {
> struct intel_engine_execlists *execlists = &engine->execlists;
>
> - GEM_BUG_ON(!execlists_is_active(execlists, EXECLISTS_ACTIVE_PREEMPT));
> -
> if (inject_preempt_hang(execlists))
> return;
>
> @@ -681,89 +680,90 @@ static void complete_preempt_context(struct intel_engine_cs *engine)
> execlists_unwind_incomplete_requests(execlists);
>
> wait_for_guc_preempt_report(engine);
> - intel_write_status_page(engine, I915_GEM_HWS_PREEMPT, 0);
> + intel_write_status_page(engine, I915_GEM_HWS_PREEMPT, GUC_PREEMPT_NONE);
> }
>
> -/**
> - * guc_submit() - Submit commands through GuC
> - * @engine: engine associated with the commands
> - *
> - * The only error here arises if the doorbell hardware isn't functioning
> - * as expected, which really shouln't happen.
> - */
> -static void guc_submit(struct intel_engine_cs *engine)
> +static void guc_submit(struct intel_engine_cs *engine,
> + struct i915_request **out,
> + struct i915_request **end)
> {
> struct intel_guc *guc = &engine->i915->guc;
> - struct intel_engine_execlists * const execlists = &engine->execlists;
> - struct execlist_port *port = execlists->port;
> - unsigned int n;
> + struct intel_guc_client *client = guc->execbuf_client;
>
> - for (n = 0; n < execlists_num_ports(execlists); n++) {
> - struct i915_request *rq;
> - unsigned int count;
> + spin_lock(&client->wq_lock);
>
> - rq = port_unpack(&port[n], &count);
> - if (rq && count == 0) {
> - port_set(&port[n], port_pack(rq, ++count));
> + do {
> + struct i915_request *rq = *out++;
>
> - flush_ggtt_writes(rq->ring->vma);
> + flush_ggtt_writes(rq->ring->vma);
> + guc_add_request(guc, rq);
> + } while (out != end);
>
> - guc_add_request(guc, rq);
> - }
> - }
> + spin_unlock(&client->wq_lock);
> }
>
> -static void port_assign(struct execlist_port *port, struct i915_request *rq)
> +static inline int rq_prio(const struct i915_request *rq)
> {
> - GEM_BUG_ON(port_isset(port));
> -
> - port_set(port, i915_request_get(rq));
> + return rq->sched.attr.priority | __NO_PREEMPTION;
> }
>
> -static inline int rq_prio(const struct i915_request *rq)
> +static struct i915_request *schedule_in(struct i915_request *rq, int idx)
> {
> - return rq->sched.attr.priority;
> + trace_i915_request_in(rq, idx);
> +
> + if (!rq->hw_context->inflight)
> + rq->hw_context->inflight = rq->engine;
> + intel_context_inflight_inc(rq->hw_context);
> +
> + return i915_request_get(rq);
> }
>
> -static inline int port_prio(const struct execlist_port *port)
> +static void schedule_out(struct i915_request *rq)
> {
> - return rq_prio(port_request(port)) | __NO_PREEMPTION;
> + trace_i915_request_out(rq);
> +
> + intel_context_inflight_dec(rq->hw_context);
> + if (!intel_context_inflight_count(rq->hw_context))
> + rq->hw_context->inflight = NULL;
> +
> + i915_request_put(rq);
> }
>
> -static bool __guc_dequeue(struct intel_engine_cs *engine)
> +static void __guc_dequeue(struct intel_engine_cs *engine)
> {
> struct intel_engine_execlists * const execlists = &engine->execlists;
> - struct execlist_port *port = execlists->port;
> - struct i915_request *last = NULL;
> - const struct execlist_port * const last_port =
> - &execlists->port[execlists->port_mask];
> + struct i915_request **first = execlists->inflight;
> + struct i915_request ** const last_port = first + execlists->port_mask;
> + struct i915_request *last = first[0];
> + struct i915_request **port;
> bool submit = false;
> struct rb_node *rb;
>
> lockdep_assert_held(&engine->active.lock);
>
> - if (port_isset(port)) {
> + if (last) {
> if (intel_engine_has_preemption(engine)) {
> struct guc_preempt_work *preempt_work =
> &engine->i915->guc.preempt_work[engine->id];
> int prio = execlists->queue_priority_hint;
>
> - if (i915_scheduler_need_preempt(prio,
> - port_prio(port))) {
> - execlists_set_active(execlists,
> - EXECLISTS_ACTIVE_PREEMPT);
> + if (i915_scheduler_need_preempt(prio, rq_prio(last))) {
> + intel_write_status_page(engine,
> + I915_GEM_HWS_PREEMPT,
> + GUC_PREEMPT_INPROGRESS);
> queue_work(engine->i915->guc.preempt_wq,
> &preempt_work->work);
> - return false;
> + return;
> }
> }
>
> - port++;
> - if (port_isset(port))
> - return false;
> + if (*++first)
> + return;
> +
> + last = NULL;
> }
> - GEM_BUG_ON(port_isset(port));
>
> + port = first;
> while ((rb = rb_first_cached(&execlists->queue))) {
> struct i915_priolist *p = to_priolist(rb);
> struct i915_request *rq, *rn;
> @@ -774,18 +774,15 @@ static bool __guc_dequeue(struct intel_engine_cs *engine)
> if (port == last_port)
> goto done;
>
> - if (submit)
> - port_assign(port, last);
> + *port = schedule_in(last,
> + port - execlists->inflight);
> port++;
> }
>
> list_del_init(&rq->sched.link);
> -
> __i915_request_submit(rq);
> - trace_i915_request_in(rq, port_index(port, execlists));
> -
> - last = rq;
> submit = true;
> + last = rq;
> }
>
> rb_erase_cached(&p->node, &execlists->queue);
> @@ -794,58 +791,41 @@ static bool __guc_dequeue(struct intel_engine_cs *engine)
> done:
> execlists->queue_priority_hint =
> rb ? to_priolist(rb)->priority : INT_MIN;
> - if (submit)
> - port_assign(port, last);
> - if (last)
> - execlists_user_begin(execlists, execlists->port);
> -
> - /* We must always keep the beast fed if we have work piled up */
> - GEM_BUG_ON(port_isset(execlists->port) &&
> - !execlists_is_active(execlists, EXECLISTS_ACTIVE_USER));
> - GEM_BUG_ON(rb_first_cached(&execlists->queue) &&
> - !port_isset(execlists->port));
> -
> - return submit;
> -}
> -
> -static void guc_dequeue(struct intel_engine_cs *engine)
> -{
> - if (__guc_dequeue(engine))
> - guc_submit(engine);
> + if (submit) {
> + *port = schedule_in(last, port - execlists->inflight);
> + *++port = NULL;
> + guc_submit(engine, first, port);
> + }
> + execlists->active = execlists->inflight;
> }
>
> static void guc_submission_tasklet(unsigned long data)
> {
> struct intel_engine_cs * const engine = (struct intel_engine_cs *)data;
> struct intel_engine_execlists * const execlists = &engine->execlists;
> - struct execlist_port *port = execlists->port;
> - struct i915_request *rq;
> + struct i915_request **port, *rq;
> unsigned long flags;
>
> spin_lock_irqsave(&engine->active.lock, flags);
>
> - rq = port_request(port);
> - while (rq && i915_request_completed(rq)) {
> - trace_i915_request_out(rq);
> - i915_request_put(rq);
> + for (port = execlists->inflight; (rq = *port); port++) {
> + if (!i915_request_completed(rq))
> + break;
>
> - port = execlists_port_complete(execlists, port);
> - if (port_isset(port)) {
> - execlists_user_begin(execlists, port);
> - rq = port_request(port);
> - } else {
> - execlists_user_end(execlists);
> - rq = NULL;
> - }
> + schedule_out(rq);
> + }
> + if (port != execlists->inflight) {
> + int idx = port - execlists->inflight;
> + int rem = ARRAY_SIZE(execlists->inflight) - idx;
> + memmove(execlists->inflight, port, rem * sizeof(*port));
> }
>
> - if (execlists_is_active(execlists, EXECLISTS_ACTIVE_PREEMPT) &&
> - intel_read_status_page(engine, I915_GEM_HWS_PREEMPT) ==
> + if (intel_read_status_page(engine, I915_GEM_HWS_PREEMPT) ==
> GUC_PREEMPT_FINISHED)
> complete_preempt_context(engine);
>
> - if (!execlists_is_active(execlists, EXECLISTS_ACTIVE_PREEMPT))
> - guc_dequeue(engine);
> + if (!intel_read_status_page(engine, I915_GEM_HWS_PREEMPT))
> + __guc_dequeue(engine);
>
> spin_unlock_irqrestore(&engine->active.lock, flags);
> }
> @@ -959,7 +939,6 @@ static void guc_cancel_requests(struct intel_engine_cs *engine)
>
> execlists->queue_priority_hint = INT_MIN;
> execlists->queue = RB_ROOT_CACHED;
> - GEM_BUG_ON(port_isset(execlists->port));
>
> spin_unlock_irqrestore(&engine->active.lock, flags);
> }
> @@ -1422,7 +1401,7 @@ int intel_guc_submission_enable(struct intel_guc *guc)
> * and it is guaranteed that it will remove the work item from the
> * queue before our request is completed.
> */
> - BUILD_BUG_ON(ARRAY_SIZE(engine->execlists.port) *
> + BUILD_BUG_ON(ARRAY_SIZE(engine->execlists.inflight) *
> sizeof(struct guc_wq_item) *
> I915_NUM_ENGINES > GUC_WQ_SIZE);
>
> diff --git a/drivers/gpu/drm/i915/selftests/i915_request.c b/drivers/gpu/drm/i915/selftests/i915_request.c
> index 298bb7116c51..1a5b9e284ca9 100644
> --- a/drivers/gpu/drm/i915/selftests/i915_request.c
> +++ b/drivers/gpu/drm/i915/selftests/i915_request.c
> @@ -366,13 +366,15 @@ static int __igt_breadcrumbs_smoketest(void *arg)
>
> if (!wait_event_timeout(wait->wait,
> i915_sw_fence_done(wait),
> - HZ / 2)) {
> + 5 * HZ)) {
> struct i915_request *rq = requests[count - 1];
>
> - pr_err("waiting for %d fences (last %llx:%lld) on %s timed out!\n",
> - count,
> + pr_err("waiting for %d/%d fences (last %llx:%lld) on %s timed out!\n",
> + atomic_read(&wait->pending), count,
> rq->fence.context, rq->fence.seqno,
> t->engine->name);
> + GEM_TRACE_DUMP();
> +
> i915_gem_set_wedged(t->engine->i915);
> GEM_BUG_ON(!i915_request_completed(rq));
> i915_sw_fence_wait(wait);
> --
> 2.20.1
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply
* Re: [igt-dev] [PATCH i-g-t v2] Add Arm drivers as supported drivers by igt.
From: Liviu Dudau @ 2019-06-20 12:41 UTC (permalink / raw)
To: Daniel Vetter; +Cc: IGT GPU Tool, Petri Latvala
In-Reply-To: <20190620123632.GS12905@phenom.ffwll.local>
On Thu, Jun 20, 2019 at 02:36:32PM +0200, Daniel Vetter wrote:
> On Wed, Jun 19, 2019 at 04:13:58PM +0100, Liviu Dudau wrote:
> > Add the drivers maintained by Arm developers to the igt.
> >
> > v2: Order the modules array entries alphabetically, as per
> > Petri Latvala's suggestion.
> >
> > Signed-off-by: Liviu Dudau <liviu.dudau@arm.com>
>
> Still kinda wondering why you need this here ... kms is supposed to be
> hw/driver agnostic, so DRIVER_ANY should work.
I'm looking at adding writeback scaling tests that not all drivers are going to
support from the start, so I thought it is better to have a more specific
driver that I can target, even if the DRM APIs are generic.
Best regards,
Liviu
>
> Maybe you want to check specific constraints in your tests, but then we
> need something like igt_require(is_komeda_driver(fd)); which can inspect
> what you're actually running on when the test executes.
>
> The drivers in this list thus far are all about exercising the gem side of
> things, where you _really_ don't want to open random garbage. Because the
> ioctls aren't even defined.
>
> On kms all ioctls are cross-driver, and only once you've opened something
> does it make sense to check for features and stuff (looking at properties,
> or getcap flags, or whatever).
>
> Cheers, Daniel
>
> PS: Yes I know that some of the DRIVER_I915 | DRIVER_AMDGPU tests really
> should have been converted to DRIVER_ANY instead. I didn't catch that in
> review way back, but I think I explained to Harry et al meanwhile ...
>
> > ---
> > lib/drmtest.c | 3 +++
> > lib/drmtest.h | 4 ++++
> > 2 files changed, 7 insertions(+)
> >
> > diff --git a/lib/drmtest.c b/lib/drmtest.c
> > index 25f203530..17bb87d1f 100644
> > --- a/lib/drmtest.c
> > +++ b/lib/drmtest.c
> > @@ -205,7 +205,10 @@ static const struct module {
> > void (*modprobe)(const char *name);
> > } modules[] = {
> > { DRIVER_AMDGPU, "amdgpu" },
> > + { DRIVER_HDLCD, "hdlcd" },
> > { DRIVER_INTEL, "i915", modprobe_i915 },
> > + { DRIVER_KOMEDA, "komeda" },
> > + { DRIVER_MALIDP, "mali_dp" },
> > { DRIVER_PANFROST, "panfrost" },
> > { DRIVER_V3D, "v3d" },
> > { DRIVER_VC4, "vc4" },
> > diff --git a/lib/drmtest.h b/lib/drmtest.h
> > index 6c4c3899c..952f0c4b6 100644
> > --- a/lib/drmtest.h
> > +++ b/lib/drmtest.h
> > @@ -45,6 +45,10 @@
> > #define DRIVER_AMDGPU (1 << 4)
> > #define DRIVER_V3D (1 << 5)
> > #define DRIVER_PANFROST (1 << 6)
> > +#define DRIVER_HDLCD (1 << 7)
> > +#define DRIVER_MALIDP (1 << 8)
> > +#define DRIVER_KOMEDA (1 << 9)
> > +
> > /*
> > * Exclude DRVER_VGEM from DRIVER_ANY since if you run on a system
> > * with vgem as well as a supported driver, you can end up with a
> > --
> > 2.22.0
> >
> > _______________________________________________
> > igt-dev mailing list
> > igt-dev@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/igt-dev
>
> --
> Daniel Vetter
> Software Engineer, Intel Corporation
> http://blog.ffwll.ch
--
====================
| I would like to |
| fix the world, |
| but they're not |
| giving me the |
\ source code! /
---------------
¯\_(ツ)_/¯
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.