All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v1 21/34] hw/arm: add control knob to disable kaslr_seed via DTB
From: Alex Bennée @ 2022-01-05 13:49 UTC (permalink / raw)
  To: qemu-devel
  Cc: fam, Peter Maydell, berrange, Heinrich Schuchardt,
	Ilias Apalodimas, f4bug, Jerome Forissier, stefanha, crosa,
	pbonzini, open list:Virt, Alex Bennée, aurelien
In-Reply-To: <20220105135009.1584676-1-alex.bennee@linaro.org>

Generally a guest needs an external source of randomness to properly
enable things like address space randomisation. However in a trusted
boot environment where the firmware will cryptographically verify
components having random data in the DTB will cause verification to
fail. Add a control knob so we can prevent this being added to the
system DTB.

Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Tested-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Acked-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
Acked-by: Jerome Forissier <jerome@forissier.org>
Message-Id: <20211215120926.1696302-1-alex.bennee@linaro.org>
---
 docs/system/arm/virt.rst |  7 +++++++
 include/hw/arm/virt.h    |  1 +
 hw/arm/virt.c            | 32 ++++++++++++++++++++++++++++++--
 3 files changed, 38 insertions(+), 2 deletions(-)

diff --git a/docs/system/arm/virt.rst b/docs/system/arm/virt.rst
index 850787495b..c86a4808df 100644
--- a/docs/system/arm/virt.rst
+++ b/docs/system/arm/virt.rst
@@ -121,6 +121,13 @@ ras
   Set ``on``/``off`` to enable/disable reporting host memory errors to a guest
   using ACPI and guest external abort exceptions. The default is off.
 
+kaslr-dtb-seed
+  Set ``on``/``off`` to pass a random seed via the guest dtb to use for features
+  like address space randomisation. The default is ``on``. You will want
+  to disable it if your trusted boot chain will verify the DTB it is
+  passed. It would be the responsibility of the firmware to come up
+  with a seed and pass it on if it wants to.
+
 Linux guest kernel configuration
 """"""""""""""""""""""""""""""""
 
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
index dc6b66ffc8..acd0665fe7 100644
--- a/include/hw/arm/virt.h
+++ b/include/hw/arm/virt.h
@@ -148,6 +148,7 @@ struct VirtMachineState {
     bool virt;
     bool ras;
     bool mte;
+    bool kaslr_dtb_seed;
     OnOffAuto acpi;
     VirtGICType gic_version;
     VirtIOMMUType iommu;
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 6bce595aba..1781e47c76 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -247,11 +247,15 @@ static void create_fdt(VirtMachineState *vms)
 
     /* /chosen must exist for load_dtb to fill in necessary properties later */
     qemu_fdt_add_subnode(fdt, "/chosen");
-    create_kaslr_seed(ms, "/chosen");
+    if (vms->kaslr_dtb_seed) {
+        create_kaslr_seed(ms, "/chosen");
+    }
 
     if (vms->secure) {
         qemu_fdt_add_subnode(fdt, "/secure-chosen");
-        create_kaslr_seed(ms, "/secure-chosen");
+        if (vms->kaslr_dtb_seed) {
+            create_kaslr_seed(ms, "/secure-chosen");
+        }
     }
 
     /* Clock node, for the benefit of the UART. The kernel device tree
@@ -2235,6 +2239,20 @@ static void virt_set_its(Object *obj, bool value, Error **errp)
     vms->its = value;
 }
 
+static bool virt_get_kaslr_dtb_seed(Object *obj, Error **errp)
+{
+    VirtMachineState *vms = VIRT_MACHINE(obj);
+
+    return vms->kaslr_dtb_seed;
+}
+
+static void virt_set_kaslr_dtb_seed(Object *obj, bool value, Error **errp)
+{
+    VirtMachineState *vms = VIRT_MACHINE(obj);
+
+    vms->kaslr_dtb_seed = value;
+}
+
 static char *virt_get_oem_id(Object *obj, Error **errp)
 {
     VirtMachineState *vms = VIRT_MACHINE(obj);
@@ -2764,6 +2782,13 @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
                                           "Set on/off to enable/disable "
                                           "ITS instantiation");
 
+    object_class_property_add_bool(oc, "kaslr-dtb-seed",
+                                   virt_get_kaslr_dtb_seed,
+                                   virt_set_kaslr_dtb_seed);
+    object_class_property_set_description(oc, "kaslr-dtb-seed",
+                                          "Set off to disable passing of kaslr "
+                                          "dtb node to guest");
+
     object_class_property_add_str(oc, "x-oem-id",
                                   virt_get_oem_id,
                                   virt_set_oem_id);
@@ -2828,6 +2853,9 @@ static void virt_instance_init(Object *obj)
     /* MTE is disabled by default.  */
     vms->mte = false;
 
+    /* Supply a kaslr-seed by default */
+    vms->kaslr_dtb_seed = true;
+
     vms->irqmap = a15irqmap;
 
     virt_flash_create(vms);
-- 
2.30.2



^ permalink raw reply related

* Re: [PATCH] RDMA: null pointer in __ib_umem_release causes kernel panic
From: Jason Gunthorpe @ 2022-01-05 14:37 UTC (permalink / raw)
  To: trondmy; +Cc: linux-rdma, linux-nfs
In-Reply-To: <20220105141841.411197-1-trondmy@kernel.org>

On Wed, Jan 05, 2022 at 09:18:41AM -0500, trondmy@kernel.org wrote:
> From: Trond Myklebust <trond.myklebust@hammerspace.com>
> 
> When doing RPC/RDMA, we're seeing a kernel panic when __ib_umem_release()
> iterates over the scatter gather list and hits NULL pages.
> 
> It turns out that commit 79fbd3e1241c ended up changing the iteration
> from being over only the mapped entries to being over the original list
> size.

You mean this?

-       for_each_sg(umem->sg_head.sgl, sg, umem->sg_nents, i)
+       for_each_sgtable_sg(&umem->sgt_append.sgt, sg, i)

I don't see what changed there? The invarient should be that

  umem->sg_nents == sgt->orig_nents

> @@ -55,7 +55,7 @@ static void __ib_umem_release(struct ib_device *dev, struct ib_umem *umem, int d
>  		ib_dma_unmap_sgtable_attrs(dev, &umem->sgt_append.sgt,
>  					   DMA_BIDIRECTIONAL, 0);
>  
> -	for_each_sgtable_sg(&umem->sgt_append.sgt, sg, i)
> +	for_each_sgtable_dma_sg(&umem->sgt_append.sgt, sg, i)
>  		unpin_user_page_range_dirty_lock(sg_page(sg),

Calling sg_page() from under a dma_sg iterator is unconditionally
wrong..

More likely your case is something has gone wrong when the sgtable was
created and it has the wrong value in orig_nents..

Jason

^ permalink raw reply

* [PATCH v2 1/1] docs: automarkup.py: Fix invalid HTML link output and broken URI fragments
From: James Clark @ 2022-01-05 14:36 UTC (permalink / raw)
  To: nfraprado, n, linux-doc; +Cc: mchehab+huawei, corbet, James Clark, linux-kernel
In-Reply-To: <20220105143640.330602-1-james.clark@arm.com>

Since commit d18b01789ae5 ("docs: Add automatic cross-reference for
documentation pages"), references that were already explicitly defined
with "ref:" and referred to other pages with a path have been doubled.
This is reported as the following error by Firefox:

  Start tag "a" seen but an element of the same type was already open.
  End tag "a" violates nesting rules.

As well as the invalid HTML, this also obscures the URI fragment links
to subsections because the second link overrides the first. For example
on the page admin-guide/hw-vuln/mds.html the last link should be to the
"Default Mitigations" subsection using a # URI fragment:

  admin-guide/hw-vuln/l1tf.html#default-mitigations

But it is obsured by a second link to the whole page:

  admin-guide/hw-vuln/l1tf.html

The full HTML with the double <a> tags looks like this:

  <a class="reference internal" href="l1tf.html#default-mitigations">
    <span class="std std-ref">
      <a class="reference internal" href="l1tf.html">
        <span class="doc">L1TF - L1 Terminal Fault</span>
      </a>
    </span>
  </a>

After this commit, there is only a single link:

  <a class="reference internal" href="l1tf.html#default-mitigations">
    <span class="std std-ref">Documentation/admin-guide/hw-vuln//l1tf.rst</span>
  </a>

Now that the second link is removed, the browser correctly jumps to the
default-mitigations subsection when clicking the link.

The fix is to check that nodes in the document to be modified are not
already references. A reference is counted as any text that is a
descendant of a reference type node. Only plain text should be converted
to new references, otherwise the doubling occurs.

Testing
=======

 * Test that the build stdout is the same (ignoring ordering), and that
   no new warnings are printed.

 * Diff all .html files and check that the only modifications occur
   to the bad double links.

 * The auto linking of bare references to pages without "ref:" is still
   working.

Fixes: d18b01789ae5 ("docs: Add automatic cross-reference for
       documentation pages")
Reviewed-by: Nícolas F. R. A. Prado <n@nfraprado.net>
Signed-off-by: James Clark <james.clark@arm.com>
---
 Documentation/sphinx/automarkup.py | 25 ++++++++++++++++++-------
 1 file changed, 18 insertions(+), 7 deletions(-)

diff --git a/Documentation/sphinx/automarkup.py b/Documentation/sphinx/automarkup.py
index acf5473002f3..cc348b219fca 100644
--- a/Documentation/sphinx/automarkup.py
+++ b/Documentation/sphinx/automarkup.py
@@ -271,19 +271,30 @@ def get_c_namespace(app, docname):
 def auto_markup(app, doctree, name):
     global c_namespace
     c_namespace = get_c_namespace(app, name)
+    def text_but_not_a_reference(node):
+        # The nodes.literal test catches ``literal text``, its purpose is to
+        # avoid adding cross-references to functions that have been explicitly
+        # marked with cc:func:.
+        if not isinstance(node, nodes.Text) or isinstance(node.parent, nodes.literal):
+            return False
+
+        child_of_reference = False
+        parent = node.parent
+        while parent:
+            if isinstance(parent, nodes.Referential):
+                child_of_reference = True
+                break
+            parent = parent.parent
+        return not child_of_reference
+
     #
     # This loop could eventually be improved on.  Someday maybe we
     # want a proper tree traversal with a lot of awareness of which
     # kinds of nodes to prune.  But this works well for now.
     #
-    # The nodes.literal test catches ``literal text``, its purpose is to
-    # avoid adding cross-references to functions that have been explicitly
-    # marked with cc:func:.
-    #
     for para in doctree.traverse(nodes.paragraph):
-        for node in para.traverse(nodes.Text):
-            if not isinstance(node.parent, nodes.literal):
-                node.parent.replace(node, markup_refs(name, app, node))
+        for node in para.traverse(condition=text_but_not_a_reference):
+            node.parent.replace(node, markup_refs(name, app, node))
 
 def setup(app):
     app.connect('doctree-resolved', auto_markup)
-- 
2.28.0


^ permalink raw reply related

* [PATCH v2 0/1] docs: automarkup.py: Fix invalid HTML link output and broken URI fragments
From: James Clark @ 2022-01-05 14:36 UTC (permalink / raw)
  To: nfraprado, n, linux-doc; +Cc: mchehab+huawei, corbet, James Clark, linux-kernel

Changes since v1:
 * Re-ordered comments so that they align with the correct code
 * Add Nícolas's review tag

James Clark (1):
  docs: automarkup.py: Fix invalid HTML link output and broken URI
    fragments

 Documentation/sphinx/automarkup.py | 25 ++++++++++++++++++-------
 1 file changed, 18 insertions(+), 7 deletions(-)

-- 
2.28.0


^ permalink raw reply

* [PATCH] ARM: disable vmap'ed stacks on suspend-capable SMP configs
From: Ard Biesheuvel @ 2022-01-05 14:34 UTC (permalink / raw)
  To: linux
  Cc: linux-arm-kernel, arnd, linus.walleij, keescook, Ard Biesheuvel,
	Marek Szyprowski, Geert Uytterhoeven, Jon Hunter

There are several reports about the new vmap'ed stacks code breaking
suspend/resume on Exynos, Renesas and Tegra SMP platforms. While this is
under investigation, let's disable the vmap'ed stacks feature for the
time being for SMP configurations that have suspend/resume enabled.

[0] https://lore.kernel.org/linux-arm-kernel/20211122092816.2865873-8-ardb@kernel.org/

Cc: Marek Szyprowski <m.szyprowski@samsung.com>
Cc: Geert Uytterhoeven <geert@linux-m68k.org>
Cc: Jon Hunter <jonathanh@nvidia.com>
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
 arch/arm/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 4817343b1d97..938f7c392cc7 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -129,7 +129,7 @@ config ARM
 	select RTC_LIB
 	select SYS_SUPPORTS_APM_EMULATION
 	select THREAD_INFO_IN_TASK
-	select HAVE_ARCH_VMAP_STACK if MMU && (!LD_IS_LLD || LLD_VERSION >= 140000)
+	select HAVE_ARCH_VMAP_STACK if MMU && (!LD_IS_LLD || LLD_VERSION >= 140000) && !PM_SLEEP_SMP
 	select TRACE_IRQFLAGS_SUPPORT if !CPU_V7M
 	# Above selects are sorted alphabetically; please add new ones
 	# according to that.  Thanks.
-- 
2.30.2


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* [PATCH v3 12/16] jobs: use job locks and helpers also in the unit tests
From: Emanuele Giuseppe Esposito @ 2022-01-05 14:02 UTC (permalink / raw)
  To: qemu-block
  Cc: Kevin Wolf, Fam Zheng, Vladimir Sementsov-Ogievskiy, Wen Congyang,
	Xie Changlong, Emanuele Giuseppe Esposito, Markus Armbruster,
	qemu-devel, Hanna Reitz, Stefan Hajnoczi, Paolo Bonzini,
	John Snow
In-Reply-To: <20220105140208.365608-1-eesposit@redhat.com>

Add missing job synchronization in the unit tests, with
both explicit locks and helpers.

Note: at this stage, job_{lock/unlock} and job lock guard macros
are *nop*.

Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
---
 tests/unit/test-bdrv-drain.c     | 40 +++++++++++-----------
 tests/unit/test-block-iothread.c |  4 +++
 tests/unit/test-blockjob-txn.c   | 10 ++++++
 tests/unit/test-blockjob.c       | 57 +++++++++++++++++++++-----------
 4 files changed, 72 insertions(+), 39 deletions(-)

diff --git a/tests/unit/test-bdrv-drain.c b/tests/unit/test-bdrv-drain.c
index 3f344a0d0d..c03560e63d 100644
--- a/tests/unit/test-bdrv-drain.c
+++ b/tests/unit/test-bdrv-drain.c
@@ -941,61 +941,63 @@ static void test_blockjob_common_drain_node(enum drain_type drain_type,
         }
     }
 
-    g_assert_cmpint(job->job.pause_count, ==, 0);
-    g_assert_false(job->job.paused);
+    g_assert_cmpint(job_get_pause_count(&job->job), ==, 0);
+    g_assert_false(job_get_paused(&job->job));
     g_assert_true(tjob->running);
-    g_assert_true(job->job.busy); /* We're in qemu_co_sleep_ns() */
+    g_assert_true(job_get_busy(&job->job)); /* We're in qemu_co_sleep_ns() */
 
     do_drain_begin_unlocked(drain_type, drain_bs);
 
     if (drain_type == BDRV_DRAIN_ALL) {
         /* bdrv_drain_all() drains both src and target */
-        g_assert_cmpint(job->job.pause_count, ==, 2);
+        g_assert_cmpint(job_get_pause_count(&job->job), ==, 2);
     } else {
-        g_assert_cmpint(job->job.pause_count, ==, 1);
+        g_assert_cmpint(job_get_pause_count(&job->job), ==, 1);
     }
-    g_assert_true(job->job.paused);
-    g_assert_false(job->job.busy); /* The job is paused */
+    g_assert_true(job_get_paused(&job->job));
+    g_assert_false(job_get_busy(&job->job)); /* The job is paused */
 
     do_drain_end_unlocked(drain_type, drain_bs);
 
     if (use_iothread) {
         /* paused is reset in the I/O thread, wait for it */
-        while (job->job.paused) {
+        while (job_get_paused(&job->job)) {
             aio_poll(qemu_get_aio_context(), false);
         }
     }
 
-    g_assert_cmpint(job->job.pause_count, ==, 0);
-    g_assert_false(job->job.paused);
-    g_assert_true(job->job.busy); /* We're in qemu_co_sleep_ns() */
+    g_assert_cmpint(job_get_pause_count(&job->job), ==, 0);
+    g_assert_false(job_get_paused(&job->job));
+    g_assert_true(job_get_busy(&job->job)); /* We're in qemu_co_sleep_ns() */
 
     do_drain_begin_unlocked(drain_type, target);
 
     if (drain_type == BDRV_DRAIN_ALL) {
         /* bdrv_drain_all() drains both src and target */
-        g_assert_cmpint(job->job.pause_count, ==, 2);
+        g_assert_cmpint(job_get_pause_count(&job->job), ==, 2);
     } else {
-        g_assert_cmpint(job->job.pause_count, ==, 1);
+        g_assert_cmpint(job_get_pause_count(&job->job), ==, 1);
     }
-    g_assert_true(job->job.paused);
-    g_assert_false(job->job.busy); /* The job is paused */
+    g_assert_true(job_get_paused(&job->job));
+    g_assert_false(job_get_busy(&job->job)); /* The job is paused */
 
     do_drain_end_unlocked(drain_type, target);
 
     if (use_iothread) {
         /* paused is reset in the I/O thread, wait for it */
-        while (job->job.paused) {
+        while (job_get_paused(&job->job)) {
             aio_poll(qemu_get_aio_context(), false);
         }
     }
 
-    g_assert_cmpint(job->job.pause_count, ==, 0);
-    g_assert_false(job->job.paused);
-    g_assert_true(job->job.busy); /* We're in qemu_co_sleep_ns() */
+    g_assert_cmpint(job_get_pause_count(&job->job), ==, 0);
+    g_assert_false(job_get_paused(&job->job));
+    g_assert_true(job_get_busy(&job->job)); /* We're in qemu_co_sleep_ns() */
 
     aio_context_acquire(ctx);
+    job_lock();
     ret = job_complete_sync_locked(&job->job, &error_abort);
+    job_unlock();
     g_assert_cmpint(ret, ==, (result == TEST_JOB_SUCCESS ? 0 : -EIO));
 
     if (use_iothread) {
diff --git a/tests/unit/test-block-iothread.c b/tests/unit/test-block-iothread.c
index 7e1b521d61..b9309beec2 100644
--- a/tests/unit/test-block-iothread.c
+++ b/tests/unit/test-block-iothread.c
@@ -456,7 +456,9 @@ static void test_attach_blockjob(void)
     }
 
     aio_context_acquire(ctx);
+    job_lock();
     job_complete_sync_locked(&tjob->common.job, &error_abort);
+    job_unlock();
     blk_set_aio_context(blk, qemu_get_aio_context(), &error_abort);
     aio_context_release(ctx);
 
@@ -630,7 +632,9 @@ static void test_propagate_mirror(void)
                  BLOCKDEV_ON_ERROR_REPORT, BLOCKDEV_ON_ERROR_REPORT,
                  false, "filter_node", MIRROR_COPY_MODE_BACKGROUND,
                  &error_abort);
+    job_lock();
     job = job_get_locked("job0");
+    job_unlock();
     filter = bdrv_find_node("filter_node");
 
     /* Change the AioContext of src */
diff --git a/tests/unit/test-blockjob-txn.c b/tests/unit/test-blockjob-txn.c
index 5396fcef10..bd69076300 100644
--- a/tests/unit/test-blockjob-txn.c
+++ b/tests/unit/test-blockjob-txn.c
@@ -124,16 +124,20 @@ static void test_single_job(int expected)
     job = test_block_job_start(1, true, expected, &result, txn);
     job_start(&job->job);
 
+    job_lock();
     if (expected == -ECANCELED) {
         job_cancel_locked(&job->job, false);
     }
+    job_unlock();
 
     while (result == -EINPROGRESS) {
         aio_poll(qemu_get_aio_context(), true);
     }
     g_assert_cmpint(result, ==, expected);
 
+    job_lock();
     job_txn_unref_locked(txn);
+    job_unlock();
 }
 
 static void test_single_job_success(void)
@@ -168,6 +172,7 @@ static void test_pair_jobs(int expected1, int expected2)
     /* Release our reference now to trigger as many nice
      * use-after-free bugs as possible.
      */
+    job_lock();
     job_txn_unref_locked(txn);
 
     if (expected1 == -ECANCELED) {
@@ -176,6 +181,7 @@ static void test_pair_jobs(int expected1, int expected2)
     if (expected2 == -ECANCELED) {
         job_cancel_locked(&job2->job, false);
     }
+    job_unlock();
 
     while (result1 == -EINPROGRESS || result2 == -EINPROGRESS) {
         aio_poll(qemu_get_aio_context(), true);
@@ -227,7 +233,9 @@ static void test_pair_jobs_fail_cancel_race(void)
     job_start(&job1->job);
     job_start(&job2->job);
 
+    job_lock();
     job_cancel_locked(&job1->job, false);
+    job_unlock();
 
     /* Now make job2 finish before the main loop kicks jobs.  This simulates
      * the race between a pending kick and another job completing.
@@ -242,7 +250,9 @@ static void test_pair_jobs_fail_cancel_race(void)
     g_assert_cmpint(result1, ==, -ECANCELED);
     g_assert_cmpint(result2, ==, -ECANCELED);
 
+    job_lock();
     job_txn_unref_locked(txn);
+    job_unlock();
 }
 
 int main(int argc, char **argv)
diff --git a/tests/unit/test-blockjob.c b/tests/unit/test-blockjob.c
index 2beed3623e..ec9128dbb5 100644
--- a/tests/unit/test-blockjob.c
+++ b/tests/unit/test-blockjob.c
@@ -211,8 +211,11 @@ static CancelJob *create_common(Job **pjob)
     bjob = mk_job(blk, "Steve", &test_cancel_driver, true,
                   JOB_MANUAL_FINALIZE | JOB_MANUAL_DISMISS);
     job = &bjob->job;
+    job_lock();
     job_ref_locked(job);
     assert(job->status == JOB_STATUS_CREATED);
+    job_unlock();
+
     s = container_of(bjob, CancelJob, common);
     s->blk = blk;
 
@@ -230,6 +233,7 @@ static void cancel_common(CancelJob *s)
     ctx = job->job.aio_context;
     aio_context_acquire(ctx);
 
+    job_lock();
     job_cancel_sync_locked(&job->job, true);
     if (sts != JOB_STATUS_CREATED && sts != JOB_STATUS_CONCLUDED) {
         Job *dummy = &job->job;
@@ -237,6 +241,7 @@ static void cancel_common(CancelJob *s)
     }
     assert(job->job.status == JOB_STATUS_NULL);
     job_unref_locked(&job->job);
+    job_unlock();
     destroy_blk(blk);
 
     aio_context_release(ctx);
@@ -259,7 +264,7 @@ static void test_cancel_running(void)
     s = create_common(&job);
 
     job_start(job);
-    assert(job->status == JOB_STATUS_RUNNING);
+    assert(job_get_status(job) == JOB_STATUS_RUNNING);
 
     cancel_common(s);
 }
@@ -272,11 +277,13 @@ static void test_cancel_paused(void)
     s = create_common(&job);
 
     job_start(job);
-    assert(job->status == JOB_STATUS_RUNNING);
+    assert(job_get_status(job) == JOB_STATUS_RUNNING);
 
+    job_lock();
     job_user_pause_locked(job, &error_abort);
+    job_unlock();
     job_enter(job);
-    assert(job->status == JOB_STATUS_PAUSED);
+    assert(job_get_status(job) == JOB_STATUS_PAUSED);
 
     cancel_common(s);
 }
@@ -289,11 +296,11 @@ static void test_cancel_ready(void)
     s = create_common(&job);
 
     job_start(job);
-    assert(job->status == JOB_STATUS_RUNNING);
+    assert(job_get_status(job) == JOB_STATUS_RUNNING);
 
     s->should_converge = true;
     job_enter(job);
-    assert(job->status == JOB_STATUS_READY);
+    assert(job_get_status(job) == JOB_STATUS_READY);
 
     cancel_common(s);
 }
@@ -306,15 +313,17 @@ static void test_cancel_standby(void)
     s = create_common(&job);
 
     job_start(job);
-    assert(job->status == JOB_STATUS_RUNNING);
+    assert(job_get_status(job) == JOB_STATUS_RUNNING);
 
     s->should_converge = true;
     job_enter(job);
-    assert(job->status == JOB_STATUS_READY);
+    assert(job_get_status(job) == JOB_STATUS_READY);
 
+    job_lock();
     job_user_pause_locked(job, &error_abort);
+    job_unlock();
     job_enter(job);
-    assert(job->status == JOB_STATUS_STANDBY);
+    assert(job_get_status(job) == JOB_STATUS_STANDBY);
 
     cancel_common(s);
 }
@@ -327,20 +336,22 @@ static void test_cancel_pending(void)
     s = create_common(&job);
 
     job_start(job);
-    assert(job->status == JOB_STATUS_RUNNING);
+    assert(job_get_status(job) == JOB_STATUS_RUNNING);
 
     s->should_converge = true;
     job_enter(job);
-    assert(job->status == JOB_STATUS_READY);
+    assert(job_get_status(job) == JOB_STATUS_READY);
 
+    job_lock();
     job_complete_locked(job, &error_abort);
+    job_unlock();
     job_enter(job);
     while (!job->deferred_to_main_loop) {
         aio_poll(qemu_get_aio_context(), true);
     }
-    assert(job->status == JOB_STATUS_READY);
+    assert(job_get_status(job) == JOB_STATUS_READY);
     aio_poll(qemu_get_aio_context(), true);
-    assert(job->status == JOB_STATUS_PENDING);
+    assert(job_get_status(job) == JOB_STATUS_PENDING);
 
     cancel_common(s);
 }
@@ -353,25 +364,29 @@ static void test_cancel_concluded(void)
     s = create_common(&job);
 
     job_start(job);
-    assert(job->status == JOB_STATUS_RUNNING);
+    assert(job_get_status(job) == JOB_STATUS_RUNNING);
 
     s->should_converge = true;
     job_enter(job);
-    assert(job->status == JOB_STATUS_READY);
+    assert(job_get_status(job) == JOB_STATUS_READY);
 
+    job_lock();
     job_complete_locked(job, &error_abort);
+    job_unlock();
     job_enter(job);
     while (!job->deferred_to_main_loop) {
         aio_poll(qemu_get_aio_context(), true);
     }
-    assert(job->status == JOB_STATUS_READY);
+    assert(job_get_status(job) == JOB_STATUS_READY);
     aio_poll(qemu_get_aio_context(), true);
-    assert(job->status == JOB_STATUS_PENDING);
+    assert(job_get_status(job) == JOB_STATUS_PENDING);
 
     aio_context_acquire(job->aio_context);
+    job_lock();
     job_finalize_locked(job, &error_abort);
+    job_unlock();
     aio_context_release(job->aio_context);
-    assert(job->status == JOB_STATUS_CONCLUDED);
+    assert(job_get_status(job) == JOB_STATUS_CONCLUDED);
 
     cancel_common(s);
 }
@@ -459,22 +474,23 @@ static void test_complete_in_standby(void)
     bjob = mk_job(blk, "job", &test_yielding_driver, true,
                   JOB_MANUAL_FINALIZE | JOB_MANUAL_DISMISS);
     job = &bjob->job;
-    assert(job->status == JOB_STATUS_CREATED);
+    assert(job_get_status(job) == JOB_STATUS_CREATED);
 
     /* Wait for the job to become READY */
     job_start(job);
     aio_context_acquire(ctx);
-    AIO_WAIT_WHILE(ctx, job->status != JOB_STATUS_READY);
+    AIO_WAIT_WHILE(ctx, job_get_status(job) != JOB_STATUS_READY);
     aio_context_release(ctx);
 
     /* Begin the drained section, pausing the job */
     bdrv_drain_all_begin();
-    assert(job->status == JOB_STATUS_STANDBY);
+    assert(job_get_status(job) == JOB_STATUS_STANDBY);
     /* Lock the IO thread to prevent the job from being run */
     aio_context_acquire(ctx);
     /* This will schedule the job to resume it */
     bdrv_drain_all_end();
 
+    job_lock();
     /* But the job cannot run, so it will remain on standby */
     assert(job->status == JOB_STATUS_STANDBY);
 
@@ -489,6 +505,7 @@ static void test_complete_in_standby(void)
     assert(job->status == JOB_STATUS_CONCLUDED);
 
     job_dismiss_locked(&job, &error_abort);
+    job_unlock();
 
     destroy_blk(blk);
     aio_context_release(ctx);
-- 
2.31.1



^ permalink raw reply related

* [PATCH v1 22/34] monitor: move x-query-profile into accel/tcg to fix build
From: Alex Bennée @ 2022-01-05 13:49 UTC (permalink / raw)
  To: qemu-devel
  Cc: fam, Eduardo Habkost, berrange, Markus Armbruster,
	Richard Henderson, Mark Cave-Ayland, f4bug, Eric Blake,
	Dr. David Alan Gilbert, Yanan Wang, stefanha, crosa, pbonzini,
	Alex Bennée, aurelien
In-Reply-To: <20220105135009.1584676-1-alex.bennee@linaro.org>

As --enable-profiler isn't defended in CI we missed this breakage.
Move the qmp handler into accel/tcg so we have access to the helpers
we need. While we are at it ensure we gate the feature on CONFIG_TCG.

Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Suggested-by: Daniel P. Berrangé <berrange@redhat.com>
Reported-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Fixes: 37087fde0e ("qapi: introduce x-query-profile QMP command")
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/773
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Tested-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Message-Id: <20211214195048.1438209-1-alex.bennee@linaro.org>

---
v3
  - also add #ifdef CONFIG_TCG to hmp-commands-info.hx
---
 qapi/machine.json    |  1 +
 accel/tcg/cpu-exec.c | 31 +++++++++++++++++++++++++++++++
 monitor/qmp-cmds.c   | 31 -------------------------------
 hmp-commands-info.hx |  2 ++
 4 files changed, 34 insertions(+), 31 deletions(-)

diff --git a/qapi/machine.json b/qapi/machine.json
index 372535b348..91d15b91c3 100644
--- a/qapi/machine.json
+++ b/qapi/machine.json
@@ -1503,6 +1503,7 @@
 ##
 { 'command': 'x-query-profile',
   'returns': 'HumanReadableText',
+  'if': 'CONFIG_TCG',
   'features': [ 'unstable' ] }
 
 ##
diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
index 409ec8c38c..8b4cd6c59d 100644
--- a/accel/tcg/cpu-exec.c
+++ b/accel/tcg/cpu-exec.c
@@ -1090,4 +1090,35 @@ HumanReadableText *qmp_x_query_opcount(Error **errp)
     return human_readable_text_from_str(buf);
 }
 
+#ifdef CONFIG_PROFILER
+
+int64_t dev_time;
+
+HumanReadableText *qmp_x_query_profile(Error **errp)
+{
+    g_autoptr(GString) buf = g_string_new("");
+    static int64_t last_cpu_exec_time;
+    int64_t cpu_exec_time;
+    int64_t delta;
+
+    cpu_exec_time = tcg_cpu_exec_time();
+    delta = cpu_exec_time - last_cpu_exec_time;
+
+    g_string_append_printf(buf, "async time  %" PRId64 " (%0.3f)\n",
+                           dev_time, dev_time / (double)NANOSECONDS_PER_SECOND);
+    g_string_append_printf(buf, "qemu time   %" PRId64 " (%0.3f)\n",
+                           delta, delta / (double)NANOSECONDS_PER_SECOND);
+    last_cpu_exec_time = cpu_exec_time;
+    dev_time = 0;
+
+    return human_readable_text_from_str(buf);
+}
+#else
+HumanReadableText *qmp_x_query_profile(Error **errp)
+{
+    error_setg(errp, "Internal profiler not compiled");
+    return NULL;
+}
+#endif
+
 #endif /* !CONFIG_USER_ONLY */
diff --git a/monitor/qmp-cmds.c b/monitor/qmp-cmds.c
index 14e3beeaaf..db4d186448 100644
--- a/monitor/qmp-cmds.c
+++ b/monitor/qmp-cmds.c
@@ -368,37 +368,6 @@ void qmp_display_reload(DisplayReloadOptions *arg, Error **errp)
     }
 }
 
-#ifdef CONFIG_PROFILER
-
-int64_t dev_time;
-
-HumanReadableText *qmp_x_query_profile(Error **errp)
-{
-    g_autoptr(GString) buf = g_string_new("");
-    static int64_t last_cpu_exec_time;
-    int64_t cpu_exec_time;
-    int64_t delta;
-
-    cpu_exec_time = tcg_cpu_exec_time();
-    delta = cpu_exec_time - last_cpu_exec_time;
-
-    g_string_append_printf(buf, "async time  %" PRId64 " (%0.3f)\n",
-                           dev_time, dev_time / (double)NANOSECONDS_PER_SECOND);
-    g_string_append_printf(buf, "qemu time   %" PRId64 " (%0.3f)\n",
-                           delta, delta / (double)NANOSECONDS_PER_SECOND);
-    last_cpu_exec_time = cpu_exec_time;
-    dev_time = 0;
-
-    return human_readable_text_from_str(buf);
-}
-#else
-HumanReadableText *qmp_x_query_profile(Error **errp)
-{
-    error_setg(errp, "Internal profiler not compiled");
-    return NULL;
-}
-#endif
-
 static int qmp_x_query_rdma_foreach(Object *obj, void *opaque)
 {
     RdmaProvider *rdma;
diff --git a/hmp-commands-info.hx b/hmp-commands-info.hx
index 407a1da800..e90f20a107 100644
--- a/hmp-commands-info.hx
+++ b/hmp-commands-info.hx
@@ -358,6 +358,7 @@ SRST
     Show host USB devices.
 ERST
 
+#if defined(CONFIG_TCG)
     {
         .name       = "profile",
         .args_type  = "",
@@ -365,6 +366,7 @@ ERST
         .help       = "show profiling information",
         .cmd_info_hrt = qmp_x_query_profile,
     },
+#endif
 
 SRST
   ``info profile``
-- 
2.30.2



^ permalink raw reply related

* Re: [PATCH v1 1/1] can: mcp251x: Get rid of duplicate of_node assignment
From: Marc Kleine-Budde @ 2022-01-05 14:34 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: linux-can, netdev, linux-kernel, Wolfgang Grandegger,
	David S. Miller, Jakub Kicinski
In-Reply-To: <YdWpWSMhzmElnIJH@smile.fi.intel.com>

[-- Attachment #1: Type: text/plain, Size: 991 bytes --]

On 05.01.2022 16:21:13, Andy Shevchenko wrote:
> On Fri, Dec 10, 2021 at 03:19:31PM +0200, Andy Shevchenko wrote:
> > On Fri, Dec 10, 2021 at 02:06:07PM +0100, Marc Kleine-Budde wrote:
> > > On 09.12.2021 13:58:40, Andy Shevchenko wrote:
> > > > On Thu, Dec 02, 2021 at 10:58:55PM +0200, Andy Shevchenko wrote:
> > 
> > ...
> > 
> > > > Marc, what do you think about this change?
> > > 
> > > LGTM, added to linux-can-next/testing.
> > 
> > Thanks for applying this and hi311x patches!
> 
> Can we have a chance to see it in the v5.17-rc1?

Yes:
https://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can-next.git/log/?h=linux-can-next-for-5.17-20220105

'about to send that PR.

regards,
Marc

-- 
Pengutronix e.K.                 | Marc Kleine-Budde           |
Embedded Linux                   | https://www.pengutronix.de  |
Vertretung West/Dortmund         | Phone: +49-231-2826-924     |
Amtsgericht Hildesheim, HRA 2686 | Fax:   +49-5121-206917-5555 |

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply

* Re: Possible bug? DOM-U network stopped working after fatal error reported in DOM0
From: Roger Pau Monné @ 2022-01-05 14:33 UTC (permalink / raw)
  To: G.R.; +Cc: xen-devel
In-Reply-To: <CAKhsbWbrvF6M-SAocACO5NvBaitUQ9mB5Qx+fMGtn_yVu0ZvEA@mail.gmail.com>

On Wed, Jan 05, 2022 at 12:05:39AM +0800, G.R. wrote:
> > > > > But seems like this patch is not stable enough yet and has its own
> > > > > issue -- memory is not properly released?
> > > >
> > > > I know. I've been working on improving it this morning and I'm
> > > > attaching an updated version below.
> > > >
> > > Good news.
> > > With this  new patch, the NAS domU can serve iSCSI disk without OOM
> > > panic, at least for a little while.
> > > I'm going to keep it up and running for a while to see if it's stable over time.
> >
> > Thanks again for all the testing. Do you see any difference
> > performance wise?
> I'm still on a *debug* kernel build to capture any potential panic --
> none so far -- no performance testing yet.
> Since I'm a home user with a relatively lightweight workload, so far I
> didn't observe any difference in daily usage.
> 
> I did some quick iperf3 testing just now.

Thanks for doing this.

> 1. between nas domU <=> Linux dom0 running on an old i7-3770 based box.
> The peak is roughly 12 Gbits/s when domU is the server.
> But I do see regression down to ~8.5 Gbits/s when I repeat the test in
> a short burst.
> The regression can recover when I leave the system idle for a while.
> 
> When dom0 is the iperf3 server, the transfer rate is much lower, down
> all the way to 1.x Gbits/s.
> Sometimes, I can see the following kernel log repeats during the
> testing, likely contributing to the slowdown.
>              interrupt storm detected on "irq2328:"; throttling interrupt source

I assume the message is in the domU, not the dom0?

> Another thing that looks alarming is the retransmission is high:
> [ ID] Interval           Transfer     Bitrate         Retr  Cwnd
> [  5]   0.00-1.00   sec   212 MBytes  1.78 Gbits/sec  110    231 KBytes
> [  5]   1.00-2.00   sec   230 MBytes  1.92 Gbits/sec    1    439 KBytes
> [  5]   2.00-3.00   sec   228 MBytes  1.92 Gbits/sec    3    335 KBytes
> [  5]   3.00-4.00   sec   204 MBytes  1.71 Gbits/sec    1    486 KBytes
> [  5]   4.00-5.00   sec   201 MBytes  1.69 Gbits/sec  812    258 KBytes
> [  5]   5.00-6.00   sec   179 MBytes  1.51 Gbits/sec    1    372 KBytes
> [  5]   6.00-7.00   sec  50.5 MBytes   423 Mbits/sec    2    154 KBytes
> [  5]   7.00-8.00   sec   194 MBytes  1.63 Gbits/sec  339    172 KBytes
> [  5]   8.00-9.00   sec   156 MBytes  1.30 Gbits/sec  854    215 KBytes
> [  5]   9.00-10.00  sec   143 MBytes  1.20 Gbits/sec  997   93.8 KBytes
> - - - - - - - - - - - - - - - - - - - - - - - - -
> [ ID] Interval           Transfer     Bitrate         Retr
> [  5]   0.00-10.00  sec  1.76 GBytes  1.51 Gbits/sec  3120             sender
> [  5]   0.00-10.45  sec  1.76 GBytes  1.44 Gbits/sec                  receiver

Do you see the same when running the same tests on a debug kernel
without my patch applied? (ie: a kernel build yourself from the same
baseline but just without my patch applied)

I'm mostly interested in knowing whether the patch itself causes any
regressions from the current state (which might not be great already).

> 
> 2. between a remote box <=> nas domU, through a 1Gbps ethernet cable.
> Roughly saturate the link when domU is the server, without obvious perf drop
> When domU running as a client, the achieved BW is ~30Mbps lower than the peak.
> Retransmission sometimes also shows up in this scenario, more
> seriously when domU is the client.
> 
> I cannot test with the stock kernel nor with your patch in release
> mode immediately.
> 
> But according to the observed imbalance between inbounding and
> outgoing path, non-trivial penalty applies I guess?

We should get a baseline using the same sources without my path
applied.

Thanks, Roger.


^ permalink raw reply

* Re: [LTP] [PATCH v1 2/3] shell: add kconfig parse api
From: Petr Vorel @ 2022-01-05 14:34 UTC (permalink / raw)
  To: xuyang2018.jy@fujitsu.com; +Cc: ltp@lists.linux.it
In-Reply-To: <61D545B7.7020003@fujitsu.com>

Hi Xu,

> >> +'$TST_NEEDS_KCONFIGS'.
> >> +Optional '$TST_NEEDS_KCONFIG_IFS' is used for splitting, default value is comma.
> >> +Optional '$TST_TCONF_IF_KCONFIG' is used for deciding how to exit the test if kernel
> >> +.config doesn't meet test's requirement, default value is 1(TCONF). Otherwise, just
> > I wonder if we need TST_TCONF_IF_KCONFIG functionality in the test or if it's an
> > user request (i.e. user like variable LTP_TCONF_IF_KCONFIG doc/user-guide.txt).
> > Because I'm not sure whether test would need it, but I can imagine user want to
> > have test running even kernel config is not available (e.g. embedded platforms).
> > Or maybe we need both user variable and test variable.
> Oh, I misunderstand the usage.

> I should use TST_TCONF_IF_KCONFIG for non-found kconfig file instead of 
> non-found kconfig list.

> I think one variable is enough.

OK, but I'd like to know others' opinion what's needed.
Cyril, Li?

> > Also not sure about TST_TCONF_IF_KCONFIG name, IMHO "IF" should be replaced to
> > something which describes what it does.
> Thinking a good name isn't a easy thing.

> how about TCONF_IF_NO_KCONFIG?

Well, I was not sure about "IF" part. For use in test code it should have "TST_"
prefix, for users to set it should have "LTP_" prefix.

> > Also this patchset is about syncing C API functionality with shell API. But you
> > introduce TST_TCONF_IF_KCONFIG only for shell. Shouldn't it be functionality for
> > both parts?
> Yes, code maybe as below:

> void tst_kconfig_read(struct tst_kconfig_var vars[], size_t vars_len)
> +static char kconfig_flag;
> +
> +int tst_kconfig_read(struct tst_kconfig_var vars[], size_t vars_len)
>   {
>          char line[128];
>          unsigned int vars_found = 0;
> +       const char *flag = getenv("TWARN_IF_NO_KCONFIG");
> +
> +       if (flag && !strcmp(flag,"y"))
> +               kconfig_flag = 'y';

>          FILE *fp = open_kconfig();
> -       if (!fp)
> +       if (!fp) {
> +               if (kconfig_flag == 'y') {
> +                       tst_res(TWARN, "Cannot parse kernel .config");
> +                       return 1;
> +               }
>                  tst_brk(TBROK, "Cannot parse kernel .config");
> -
> +       }
>          while (fgets(line, sizeof(line), fp)) {
>                  if (kconfig_parse_line(line, vars, vars_len))
>                          vars_found++;
> @@ -198,6 +210,7 @@ void tst_kconfig_read(struct tst_kconfig_var vars[], 
> size_t vars_len)

>   exit:
>          close_kconfig(fp);
> +       return 0;
>   }

Sure, once we agree what should be implemented.

>   static size_t array_len(const char *const kconfigs[])
> @@ -504,7 +517,9 @@ int tst_kconfig_check(const char *const kconfigs[])

>          var_cnt = populate_vars(exprs, expr_cnt, vars);

> -       tst_kconfig_read(vars, var_cnt);
> +       ret = tst_kconfig_read(vars, var_cnt);
> +       if (ret)
> +               return kconfig_flag == 'y' ? 0 : 1;




> > More notes about this variable also below.

> > BTW github actions have probably kernel config on expected place, which means
> > that most of the new tests TCONF, but tst_check_kconfig05.sh TFAIL.
> I guess we can export the  KCONFIG_PATH to solve this problem. But I 
> don't know the expected place on github actions.

Sure, for github we can find config place.
But this can happen to user who runs the test. IMHO test should not fail if
user's system is without config. That's why I'd like to have a variable making
errors non-fatal.

> > tst_rhost_run 1 TCONF: veth(null)      0  TWARN  :  /__w/ltp/ltp/lib/tst_kernel.c:110: expected file /lib/modules/5.11.0-1022-azure/modules.dep does not exist or not a file
> > 320
> > (null)      0  TWARN  :  /__w/ltp/ltp/lib/tst_kernel.c:110: expected file /lib/modules/5.11.0-1022-azure/modules.builtin does not exist or not a file driver not available

> >> +use TWRAN and continue to run test.
> >> +
> >> +Now, we support the length of kconfig list is 10.
> > Why 10? Cyril suggested that in PR, where he suggested to use separated
> > variables:
> > https://github.com/linux-test-project/ltp/issues/891#issuecomment-989712350

> > But for string used like array there is no performance limitation, thus I'd use
> > something like 50 or 100. Because for certain IMA tests there are at least 6
> > kconfig requirements, thus>  10 could be hit.
> If case needs more than 10 kconfigs, we can use & ie
> "CONFIG_EX4_FS & CONFIG_XFS_FS & CONFIG_QUOTAL_FS, CONFIG_PROC_FS..."
Sure. I just meant there is no reason to put low number and then workaround it.

> >> --- a/testcases/lib/tst_test.sh
> >> +	tst_check_kconfigs $kconfig1 $kconfig2 $kconfig3 $kconfig4 $kconfig5 $kconfig6\
> >> +			$kconfig7 $kconfig8 $kconfig9 $kconfig10
> >> +	if [ $? -ne 0 ]; then
> >> +		if [ $TST_TCONF_IF_KCONFIG -eq 1 ]; then
> >> +			tst_brk TCONF "kconfig not available"

> >> +		else
> >> +			tst_res TWARN "kconfig not available"
> > This is quite strong: either test "fails" due TWARN non-zero exit code or it's
> > skipped. I'd prefer to have user variable for systems which are properly
> > configured (user will make sure all kconfig options are set), but it's just
> > missing kconfig due system configuration.
> I plan to fix the variable usage for non-found kconfig path/file instead 
> of kconfig list.

> Best Regards
> Yang Xu

Kind regards,
Petr

-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply

* [PATCH v3 13/16] jobs: add job lock in find_* functions
From: Emanuele Giuseppe Esposito @ 2022-01-05 14:02 UTC (permalink / raw)
  To: qemu-block
  Cc: Kevin Wolf, Fam Zheng, Vladimir Sementsov-Ogievskiy, Wen Congyang,
	Xie Changlong, Emanuele Giuseppe Esposito, Markus Armbruster,
	qemu-devel, Hanna Reitz, Stefan Hajnoczi, Paolo Bonzini,
	John Snow
In-Reply-To: <20220105140208.365608-1-eesposit@redhat.com>

Both blockdev.c and job-qmp.c have TOC/TOU conditions, because
they first search for the job and then perform an action on it.
Therefore, we need to do the search + action under the same
job mutex critical section.

Note: at this stage, job_{lock/unlock} and job lock guard macros
are *nop*.

Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
---
 blockdev.c | 14 +++++++++++++-
 job-qmp.c  | 13 ++++++++++++-
 2 files changed, 25 insertions(+), 2 deletions(-)

diff --git a/blockdev.c b/blockdev.c
index 099d57e0d2..1fbd9b9e04 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -3305,7 +3305,10 @@ out:
     aio_context_release(aio_context);
 }
 
-/* Get a block job using its ID and acquire its AioContext */
+/*
+ * Get a block job using its ID and acquire its AioContext.
+ * Returns with job_lock held on success.
+ */
 static BlockJob *find_block_job(const char *id, AioContext **aio_context,
                                 Error **errp)
 {
@@ -3314,12 +3317,14 @@ static BlockJob *find_block_job(const char *id, AioContext **aio_context,
     assert(id != NULL);
 
     *aio_context = NULL;
+    job_lock();
 
     job = block_job_get(id);
 
     if (!job) {
         error_set(errp, ERROR_CLASS_DEVICE_NOT_ACTIVE,
                   "Block job '%s' not found", id);
+        job_unlock();
         return NULL;
     }
 
@@ -3340,6 +3345,7 @@ void qmp_block_job_set_speed(const char *device, int64_t speed, Error **errp)
 
     block_job_set_speed(job, speed, errp);
     aio_context_release(aio_context);
+    job_unlock();
 }
 
 void qmp_block_job_cancel(const char *device,
@@ -3366,6 +3372,7 @@ void qmp_block_job_cancel(const char *device,
     job_user_cancel_locked(&job->job, force, errp);
 out:
     aio_context_release(aio_context);
+    job_unlock();
 }
 
 void qmp_block_job_pause(const char *device, Error **errp)
@@ -3380,6 +3387,7 @@ void qmp_block_job_pause(const char *device, Error **errp)
     trace_qmp_block_job_pause(job);
     job_user_pause_locked(&job->job, errp);
     aio_context_release(aio_context);
+    job_unlock();
 }
 
 void qmp_block_job_resume(const char *device, Error **errp)
@@ -3394,6 +3402,7 @@ void qmp_block_job_resume(const char *device, Error **errp)
     trace_qmp_block_job_resume(job);
     job_user_resume_locked(&job->job, errp);
     aio_context_release(aio_context);
+    job_unlock();
 }
 
 void qmp_block_job_complete(const char *device, Error **errp)
@@ -3408,6 +3417,7 @@ void qmp_block_job_complete(const char *device, Error **errp)
     trace_qmp_block_job_complete(job);
     job_complete_locked(&job->job, errp);
     aio_context_release(aio_context);
+    job_unlock();
 }
 
 void qmp_block_job_finalize(const char *id, Error **errp)
@@ -3431,6 +3441,7 @@ void qmp_block_job_finalize(const char *id, Error **errp)
     aio_context = blk_get_aio_context(job->blk);
     job_unref_locked(&job->job);
     aio_context_release(aio_context);
+    job_unlock();
 }
 
 void qmp_block_job_dismiss(const char *id, Error **errp)
@@ -3447,6 +3458,7 @@ void qmp_block_job_dismiss(const char *id, Error **errp)
     job = &bjob->job;
     job_dismiss_locked(&job, errp);
     aio_context_release(aio_context);
+    job_unlock();
 }
 
 void qmp_change_backing_file(const char *device,
diff --git a/job-qmp.c b/job-qmp.c
index 9fa14bf761..615e056fc4 100644
--- a/job-qmp.c
+++ b/job-qmp.c
@@ -29,16 +29,21 @@
 #include "qapi/error.h"
 #include "trace/trace-root.h"
 
-/* Get a job using its ID and acquire its AioContext */
+/*
+ * Get a block job using its ID and acquire its AioContext.
+ * Returns with job_lock held on success.
+ */
 static Job *find_job(const char *id, AioContext **aio_context, Error **errp)
 {
     Job *job;
 
     *aio_context = NULL;
+    job_lock();
 
     job = job_get_locked(id);
     if (!job) {
         error_setg(errp, "Job not found");
+        job_unlock();
         return NULL;
     }
 
@@ -60,6 +65,7 @@ void qmp_job_cancel(const char *id, Error **errp)
     trace_qmp_job_cancel(job);
     job_user_cancel_locked(job, true, errp);
     aio_context_release(aio_context);
+    job_unlock();
 }
 
 void qmp_job_pause(const char *id, Error **errp)
@@ -74,6 +80,7 @@ void qmp_job_pause(const char *id, Error **errp)
     trace_qmp_job_pause(job);
     job_user_pause_locked(job, errp);
     aio_context_release(aio_context);
+    job_unlock();
 }
 
 void qmp_job_resume(const char *id, Error **errp)
@@ -88,6 +95,7 @@ void qmp_job_resume(const char *id, Error **errp)
     trace_qmp_job_resume(job);
     job_user_resume_locked(job, errp);
     aio_context_release(aio_context);
+    job_unlock();
 }
 
 void qmp_job_complete(const char *id, Error **errp)
@@ -102,6 +110,7 @@ void qmp_job_complete(const char *id, Error **errp)
     trace_qmp_job_complete(job);
     job_complete_locked(job, errp);
     aio_context_release(aio_context);
+    job_unlock();
 }
 
 void qmp_job_finalize(const char *id, Error **errp)
@@ -125,6 +134,7 @@ void qmp_job_finalize(const char *id, Error **errp)
     aio_context = job->aio_context;
     job_unref_locked(job);
     aio_context_release(aio_context);
+    job_unlock();
 }
 
 void qmp_job_dismiss(const char *id, Error **errp)
@@ -139,6 +149,7 @@ void qmp_job_dismiss(const char *id, Error **errp)
     trace_qmp_job_dismiss(job);
     job_dismiss_locked(&job, errp);
     aio_context_release(aio_context);
+    job_unlock();
 }
 
 static JobInfo *job_query_single(Job *job, Error **errp)
-- 
2.31.1



^ permalink raw reply related

* [PATCH  v1 31/34] docs/sphinx: fix compatibility with sphinx < 1.8
From: Alex Bennée @ 2022-01-05 13:50 UTC (permalink / raw)
  To: qemu-devel
  Cc: fam, Peter Maydell, Thomas Huth, berrange, f4bug,
	Marc-André Lureau, stefanha, crosa, pbonzini,
	Alex Bennée, aurelien
In-Reply-To: <20220105135009.1584676-1-alex.bennee@linaro.org>

From: Marc-André Lureau <marcandre.lureau@redhat.com>

SphinxDirective was added with sphinx 1.8 (2018-09-13).

Reported-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Tested-by: Thomas Huth <thuth@redhat.com>
Message-Id: <20220104074649.1712440-1-marcandre.lureau@redhat.com>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
---
 docs/sphinx/fakedbusdoc.py | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/docs/sphinx/fakedbusdoc.py b/docs/sphinx/fakedbusdoc.py
index a680b25754..d2c5079046 100644
--- a/docs/sphinx/fakedbusdoc.py
+++ b/docs/sphinx/fakedbusdoc.py
@@ -7,12 +7,12 @@
 # Author: Marc-André Lureau <marcandre.lureau@redhat.com>
 """dbus-doc is a Sphinx extension that provides documentation from D-Bus XML."""
 
+from docutils.parsers.rst import Directive
 from sphinx.application import Sphinx
-from sphinx.util.docutils import SphinxDirective
 from typing import Any, Dict
 
 
-class FakeDBusDocDirective(SphinxDirective):
+class FakeDBusDocDirective(Directive):
     has_content = True
     required_arguments = 1
 
-- 
2.30.2



^ permalink raw reply related

* Re: [Intel-gfx] [PATCH 2/2] drm/i915/uncore: rename i915_reg_read_ioctl intel_uncore_reg_read_ioctl
From: Tvrtko Ursulin @ 2022-01-05 14:33 UTC (permalink / raw)
  To: Jani Nikula, intel-gfx
In-Reply-To: <87ee5mjp7h.fsf@intel.com>


On 05/01/2022 13:18, Jani Nikula wrote:
> On Wed, 05 Jan 2022, Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com> wrote:
>> On 05/01/2022 10:32, Jani Nikula wrote:
>>> On Wed, 05 Jan 2022, Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com> wrote:
>>>> On 05/01/2022 10:05, Jani Nikula wrote:
>>>>> Follow the usual naming convention.
>>>>
>>>> But intel_uncore_ prefix usually means functions takes intel_uncore as
>>>> the first argument.
>>>>
>>>> Maybe solution here is that i915_reg_read_ioctl does not belong in
>>>> intel_uncore.c, it being the UAPI layer thing? I guess arguments could
>>>> be made for either way.
>>>
>>> My position is that the function and file prefixes go hand in
>>> hand. You'll always know where to place a function, and you'll always
>>> know where the function is to be found.
>>>
>>> If you can *also* make the context argument follow the pattern, it's
>>> obviously better, and indicates the division to files is working out
>>> nicely. However, in a lot of cases you'll need to pass struct
>>> drm_i915_private or similar as the first parameter to e.g. init
>>> functions. It can't be the rigid rule.
>>>
>>> I'm fine with moving the entire function somewhere else, as long as the
>>> declaration is not in i915_drv.h. There's no longer a i915_drv.c, and
>>> i915_drv.h should not have function declarations at all.
>>
>> Yes I agree it cannot be a rigid rule. I just that it feels
>> intel_uncore.[hc] is too low level to me to hold an ioctl
>> implementation, and header actually feels wrong to have the declaration.
>> Not least it is about _one_ of the uncores, while the ioctl is not
>> operating on that level, albeit undefined at the moment how exactly it
>> would work for multi-tile.
>>
>> Would it be too early, or unwarranted at this point, to maybe consider
>> adding i915_ioctls.[hc]?
> 
> Then the conversation would be about putting together a ton of unrelated
> functions where the only thing in common is that they're an ioctl
> implementation. Arguably many of them would have less in common than the
> reg read ioctl has with uncore!

I imagined it as a place for ioctls which don't fit anywhere else, like 
it this case it is not a family of ioctls but and odd one out. So yes, 
first "problem" would be there is only one to put there and no line of 
sight for others.

> And when is it okay to put an ioctl in the i915_ioctls.c file and when
> is it warranted to put it somewhere else? It's just a different set of
> problems.

When it does not fit anywhere else?

>> I like the i915_ prefix of ioctls for consistency.. i915_getparam_ioctl,
>> i915_query_ioctl, i915_perf_..., i915_gem_....
> 
> The display ioctls have intel_ prefix anyway. It's the _ioctl suffix
> that we use.
> 
> Again, my main driver here is cleaning up i915_drv.h. I can shove the
> reg read ioctl somewhere other than intel_uncore.[ch] too. But as it
> stands, the only alternative that seems better than intel_uncore.[ch] at
> the moment is adding a dedicated file for a 60-line function.

I understand your motivation and I wouldn't nack your efforts, but I 
also cannot yet make myself ack it. Is 60 lines so bad? Lets see..

$ find . -name "*.c" -print0 | xargs -0 wc -l | sort -nr
...
      59 ./selftests/mock_request.c
      59 ./gt/uc/intel_uc_debugfs.c
      59 ./gem/i915_gemfs.c
      52 ./selftests/igt_mmap.c
      51 ./selftests/igt_reset.c
      49 ./selftests/mock_uncore.c
      47 ./selftests/igt_atomic.c
      36 ./gt/uc/intel_huc_debugfs.c
      36 ./gt/intel_gt_engines_debugfs.c
      35 ./selftests/igt_flush_test.c
      34 ./selftests/librapl.c
      34 ./gvt/trace_points.c
      29 ./gt/selftests/mock_timeline.c
      27 ./gt/selftest_engine.c
      26 ./gt/uc/intel_huc_fw.c
      15 ./i915_config.c
      14 ./i915_trace_points.c
       9 ./display/intel_display_trace.c

So kind of meh, wouldn't be first. I'd add a dedicated file just for the 
benefit of being able to legitimately keep the i915_reg_read_ioctl name. 
Come multi-tile it may get company. Even though at the moment I am not 
aware anyone is trying to add multi-tile aware reg read, but I expect 
there will be need as long as need for the existing one exists.

Regards,

Tvrtko

^ permalink raw reply

* Re: [PATCH 02/13] kprobe: Keep traced function address
From: Masami Hiramatsu @ 2022-01-05 14:32 UTC (permalink / raw)
  To: Jiri Olsa
  Cc: Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko, netdev, bpf,
	lkml, Martin KaFai Lau, Song Liu, Yonghong Song, John Fastabend,
	KP Singh, Steven Rostedt, Naveen N. Rao, Anil S Keshavamurthy,
	David S. Miller
In-Reply-To: <20220104080943.113249-3-jolsa@kernel.org>

On Tue,  4 Jan 2022 09:09:32 +0100
Jiri Olsa <jolsa@redhat.com> wrote:

> The bpf_get_func_ip_kprobe helper should return traced function
> address, but it's doing so only for kprobes that are placed on
> the function entry.
> 
> If kprobe is placed within the function, bpf_get_func_ip_kprobe
> returns that address instead of function entry.
> 
> Storing the function entry directly in kprobe object, so it could
> be used in bpf_get_func_ip_kprobe helper.

Hmm, please do this in bpf side, which should have some data structure
around the kprobe itself. Do not add this "specialized" field to
the kprobe data structure.

Thank you,

> 
> Signed-off-by: Jiri Olsa <jolsa@kernel.org>
> ---
>  include/linux/kprobes.h                              |  3 +++
>  kernel/kprobes.c                                     | 12 ++++++++++++
>  kernel/trace/bpf_trace.c                             |  2 +-
>  tools/testing/selftests/bpf/progs/get_func_ip_test.c |  4 ++--
>  4 files changed, 18 insertions(+), 3 deletions(-)
> 
> diff --git a/include/linux/kprobes.h b/include/linux/kprobes.h
> index 8c8f7a4d93af..a204df4fef96 100644
> --- a/include/linux/kprobes.h
> +++ b/include/linux/kprobes.h
> @@ -74,6 +74,9 @@ struct kprobe {
>  	/* Offset into the symbol */
>  	unsigned int offset;
>  
> +	/* traced function address */
> +	unsigned long func_addr;
> +
>  	/* Called before addr is executed. */
>  	kprobe_pre_handler_t pre_handler;
>  
> diff --git a/kernel/kprobes.c b/kernel/kprobes.c
> index d20ae8232835..c4060a8da050 100644
> --- a/kernel/kprobes.c
> +++ b/kernel/kprobes.c
> @@ -1310,6 +1310,7 @@ static void init_aggr_kprobe(struct kprobe *ap, struct kprobe *p)
>  	copy_kprobe(p, ap);
>  	flush_insn_slot(ap);
>  	ap->addr = p->addr;
> +	ap->func_addr = p->func_addr;
>  	ap->flags = p->flags & ~KPROBE_FLAG_OPTIMIZED;
>  	ap->pre_handler = aggr_pre_handler;
>  	/* We don't care the kprobe which has gone. */
> @@ -1588,6 +1589,16 @@ static int check_kprobe_address_safe(struct kprobe *p,
>  	return ret;
>  }
>  
> +static unsigned long resolve_func_addr(kprobe_opcode_t *addr)
> +{
> +	char str[KSYM_SYMBOL_LEN];
> +	unsigned long offset;
> +
> +	if (kallsyms_lookup((unsigned long) addr, NULL, &offset, NULL, str))
> +		return (unsigned long) addr - offset;
> +	return 0;
> +}
> +
>  int register_kprobe(struct kprobe *p)
>  {
>  	int ret;
> @@ -1600,6 +1611,7 @@ int register_kprobe(struct kprobe *p)
>  	if (IS_ERR(addr))
>  		return PTR_ERR(addr);
>  	p->addr = addr;
> +	p->func_addr = resolve_func_addr(addr);
>  
>  	ret = warn_kprobe_rereg(p);
>  	if (ret)
> diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
> index 21aa30644219..25631253084a 100644
> --- a/kernel/trace/bpf_trace.c
> +++ b/kernel/trace/bpf_trace.c
> @@ -1026,7 +1026,7 @@ BPF_CALL_1(bpf_get_func_ip_kprobe, struct pt_regs *, regs)
>  {
>  	struct kprobe *kp = kprobe_running();
>  
> -	return kp ? (uintptr_t)kp->addr : 0;
> +	return kp ? (uintptr_t)kp->func_addr : 0;
>  }
>  
>  static const struct bpf_func_proto bpf_get_func_ip_proto_kprobe = {
> diff --git a/tools/testing/selftests/bpf/progs/get_func_ip_test.c b/tools/testing/selftests/bpf/progs/get_func_ip_test.c
> index a587aeca5ae0..e988aefa567e 100644
> --- a/tools/testing/selftests/bpf/progs/get_func_ip_test.c
> +++ b/tools/testing/selftests/bpf/progs/get_func_ip_test.c
> @@ -69,7 +69,7 @@ int test6(struct pt_regs *ctx)
>  {
>  	__u64 addr = bpf_get_func_ip(ctx);
>  
> -	test6_result = (const void *) addr == &bpf_fentry_test6 + 5;
> +	test6_result = (const void *) addr == &bpf_fentry_test6;
>  	return 0;
>  }
>  
> @@ -79,6 +79,6 @@ int test7(struct pt_regs *ctx)
>  {
>  	__u64 addr = bpf_get_func_ip(ctx);
>  
> -	test7_result = (const void *) addr == &bpf_fentry_test7 + 5;
> +	test7_result = (const void *) addr == &bpf_fentry_test7;
>  	return 0;
>  }
> -- 
> 2.33.1
> 


-- 
Masami Hiramatsu <mhiramat@kernel.org>

^ permalink raw reply

* Re: [Buildroot] candidate packages : ros2 and wxwidgets
From: Romain Naour @ 2022-01-05 14:32 UTC (permalink / raw)
  To: Thierry Bultel, buildroot
In-Reply-To: <5be78f0b-fdb2-66a0-71a1-11538c064148@linatsea.fr>

Le 05/01/2022 à 14:49, Thierry Bultel a écrit :
>> We also have some companies interested by ROS2 but they are using meta-ros Yocto
>> layer.
>>
> 
> That would be therefore of less interest to them, unless they are thinking of
> switching to buildroot.

Well, I guess they use Yocto by default since there is currently no other choice.

> In my case, I rather see companies that just start to enter in "the embedded
> world" but already use ROS(1/2) on desktops,
> so it is still not to late for them to make the good choice.

ROS is definitely not an easy framework to package into Buildroot, it's doable
but requires a lot of work and time.

Best regards,
Romain

> _______________________________________________
> buildroot mailing list
> buildroot@buildroot.org
> https://lists.buildroot.org/mailman/listinfo/buildroot

_______________________________________________
buildroot mailing list
buildroot@buildroot.org
https://lists.buildroot.org/mailman/listinfo/buildroot

^ permalink raw reply

* Re: [PATCH v1 1/1] gpio: tegra: Get rid of duplicate of_node assignment
From: Andy Shevchenko @ 2022-01-05 14:23 UTC (permalink / raw)
  To: Linus Walleij, Bartosz Golaszewski, Thierry Reding, linux-gpio,
	linux-tegra, linux-kernel
  Cc: Bartosz Golaszewski, Thierry Reding, Jonathan Hunter
In-Reply-To: <20211223122639.86923-1-andriy.shevchenko@linux.intel.com>

On Thu, Dec 23, 2021 at 02:26:39PM +0200, Andy Shevchenko wrote:
> GPIO library does copy the of_node from the parent device of
> the GPIO chip, there is no need to repeat this in the individual
> drivers. Remove these assignment all at once.
> 
> For the details one may look into the of_gpio_dev_init() implementation.

Any comments on this one?

-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply

* Re: [PATCH v1 1/1] gpio: altera-a10sr: Switch to use fwnode instead of of_node
From: Andy Shevchenko @ 2022-01-05 14:22 UTC (permalink / raw)
  To: Alexandru Ardelean, linux-gpio, linux-kernel
  Cc: Thor Thayer, Linus Walleij, Bartosz Golaszewski
In-Reply-To: <20211223122733.86981-1-andriy.shevchenko@linux.intel.com>

On Thu, Dec 23, 2021 at 02:27:33PM +0200, Andy Shevchenko wrote:
> GPIO library now accepts fwnode as a firmware node, so
> switch the driver to use it.

Any comments on this?

-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply

* [PATCH v3 11/16] jobs: document all static functions and add _locked() suffix
From: Emanuele Giuseppe Esposito @ 2022-01-05 14:02 UTC (permalink / raw)
  To: qemu-block
  Cc: Kevin Wolf, Fam Zheng, Vladimir Sementsov-Ogievskiy, Wen Congyang,
	Xie Changlong, Emanuele Giuseppe Esposito, Markus Armbruster,
	qemu-devel, Hanna Reitz, Stefan Hajnoczi, Paolo Bonzini,
	John Snow
In-Reply-To: <20220105140208.365608-1-eesposit@redhat.com>

Now that we added the job_lock/unlock pairs, we can also
rename all static functions in job.c that are called with
the job mutex held as _locked(), and add a little comment
on top.

No functional change intended.

Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
---
 blockjob.c |   8 ++
 job.c      | 243 +++++++++++++++++++++++++++++++----------------------
 2 files changed, 149 insertions(+), 102 deletions(-)

diff --git a/blockjob.c b/blockjob.c
index e00c8d31d5..cf1f49f6c2 100644
--- a/blockjob.c
+++ b/blockjob.c
@@ -242,6 +242,7 @@ int block_job_add_bdrv(BlockJob *job, const char *name, BlockDriverState *bs,
     return 0;
 }
 
+/* Called with job_mutex lock held. */
 static void block_job_on_idle(Notifier *n, void *opaque)
 {
     /*
@@ -269,6 +270,7 @@ static bool job_timer_pending(Job *job)
     return timer_pending(&job->sleep_timer);
 }
 
+/* Called with job_mutex held. May temporarly release the lock. */
 bool block_job_set_speed(BlockJob *job, int64_t speed, Error **errp)
 {
     const BlockJobDriver *drv = block_job_driver(job);
@@ -310,6 +312,7 @@ int64_t block_job_ratelimit_get_delay(BlockJob *job, uint64_t n)
     return ratelimit_calculate_delay(&job->limit, n);
 }
 
+/* Called with job_mutex lock held. */
 BlockJobInfo *block_job_query(BlockJob *job, Error **errp)
 {
     BlockJobInfo *info;
@@ -355,6 +358,7 @@ static void block_job_iostatus_set_err(BlockJob *job, int error)
     }
 }
 
+/* Called with job_mutex lock held. */
 static void block_job_event_cancelled(Notifier *n, void *opaque)
 {
     BlockJob *job = opaque;
@@ -374,6 +378,7 @@ static void block_job_event_cancelled(Notifier *n, void *opaque)
                                         job->speed);
 }
 
+/* Called with job_mutex lock held. */
 static void block_job_event_completed(Notifier *n, void *opaque)
 {
     BlockJob *job = opaque;
@@ -400,6 +405,7 @@ static void block_job_event_completed(Notifier *n, void *opaque)
                                         msg);
 }
 
+/* Called with job_mutex lock held. */
 static void block_job_event_pending(Notifier *n, void *opaque)
 {
     BlockJob *job = opaque;
@@ -412,6 +418,7 @@ static void block_job_event_pending(Notifier *n, void *opaque)
                                       job->job.id);
 }
 
+/* Called with job_mutex lock held. */
 static void block_job_event_ready(Notifier *n, void *opaque)
 {
     BlockJob *job = opaque;
@@ -504,6 +511,7 @@ void *block_job_create(const char *job_id, const BlockJobDriver *driver,
     return job;
 }
 
+/* Called with job_mutex lock held. */
 void block_job_iostatus_reset(BlockJob *job)
 {
     assert(qemu_in_main_thread());
diff --git a/job.c b/job.c
index 56722a5043..f16a4ef542 100644
--- a/job.c
+++ b/job.c
@@ -54,6 +54,7 @@
  */
 QemuMutex job_mutex;
 
+/* Protected by job_mutex */
 static QLIST_HEAD(, Job) jobs = QLIST_HEAD_INITIALIZER(jobs);
 
 /* Job State Transition Table */
@@ -129,7 +130,8 @@ JobTxn *job_txn_new(void)
     return txn;
 }
 
-static void job_txn_ref(JobTxn *txn)
+/* Called with job_mutex held. */
+static void job_txn_ref_locked(JobTxn *txn)
 {
     txn->refcnt++;
 }
@@ -151,10 +153,11 @@ void job_txn_add_job_locked(JobTxn *txn, Job *job)
     job->txn = txn;
 
     QLIST_INSERT_HEAD(&txn->jobs, job, txn_list);
-    job_txn_ref(txn);
+    job_txn_ref_locked(txn);
 }
 
-static void job_txn_del_job(Job *job)
+/* Called with job_mutex held. */
+static void job_txn_del_job_locked(Job *job)
 {
     if (job->txn) {
         QLIST_REMOVE(job, txn_list);
@@ -163,17 +166,18 @@ static void job_txn_del_job(Job *job)
     }
 }
 
-static int job_txn_apply(Job *job, int fn(Job *))
+/* Called with job_mutex held. */
+static int job_txn_apply_locked(Job *job, int fn(Job *))
 {
     Job *other_job, *next;
     JobTxn *txn = job->txn;
     int rc = 0;
 
     /*
-     * Similar to job_completed_txn_abort, we take each job's lock before
-     * applying fn, but since we assume that outer_ctx is held by the caller,
-     * we need to release it here to avoid holding the lock twice - which would
-     * break AIO_WAIT_WHILE from within fn.
+     * Similar to job_completed_txn_abort_locked, we take each job's lock
+     * before applying fn, but since we assume that outer_ctx is held by the
+     * caller, we need to release it here to avoid holding the lock
+     * twice - which would break AIO_WAIT_WHILE from within fn.
      */
     job_ref_locked(job);
     aio_context_release(job->aio_context);
@@ -199,7 +203,8 @@ bool job_is_internal(Job *job)
     return (job->id == NULL);
 }
 
-static void job_state_transition(Job *job, JobStatus s1)
+/* Called with job_mutex held. */
+static void job_state_transition_locked(Job *job, JobStatus s1)
 {
     JobStatus s0 = job->status;
     assert(s1 >= 0 && s1 < JOB_STATUS__MAX);
@@ -355,7 +360,8 @@ static bool job_started(Job *job)
     return job->co;
 }
 
-static bool job_should_pause(Job *job)
+/* Called with job_mutex held. */
+static bool job_should_pause_locked(Job *job)
 {
     return job->pause_count > 0;
 }
@@ -381,6 +387,7 @@ Job *job_get_locked(const char *id)
     return NULL;
 }
 
+/* Called with job_mutex *not* held. */
 static void job_sleep_timer_cb(void *opaque)
 {
     Job *job = opaque;
@@ -434,7 +441,7 @@ void *job_create(const char *job_id, const JobDriver *driver, JobTxn *txn,
     notifier_list_init(&job->on_pending);
     notifier_list_init(&job->on_ready);
 
-    job_state_transition(job, JOB_STATUS_CREATED);
+    job_state_transition_locked(job, JOB_STATUS_CREATED);
     aio_timer_init(qemu_get_aio_context(), &job->sleep_timer,
                    QEMU_CLOCK_REALTIME, SCALE_NS,
                    job_sleep_timer_cb, job);
@@ -502,7 +509,7 @@ void job_progress_increase_remaining(Job *job, uint64_t delta)
  * To be called when a cancelled job is finalised.
  * Called with job_mutex held.
  */
-static void job_event_cancelled(Job *job)
+static void job_event_cancelled_locked(Job *job)
 {
     notifier_list_notify(&job->on_finalize_cancelled, job);
 }
@@ -511,22 +518,25 @@ static void job_event_cancelled(Job *job)
  * To be called when a successfully completed job is finalised.
  * Called with job_mutex held.
  */
-static void job_event_completed(Job *job)
+static void job_event_completed_locked(Job *job)
 {
     notifier_list_notify(&job->on_finalize_completed, job);
 }
 
-static void job_event_pending(Job *job)
+/* Called with job_mutex held. */
+static void job_event_pending_locked(Job *job)
 {
     notifier_list_notify(&job->on_pending, job);
 }
 
-static void job_event_ready(Job *job)
+/* Called with job_mutex held. */
+static void job_event_ready_locked(Job *job)
 {
     notifier_list_notify(&job->on_ready, job);
 }
 
-static void job_event_idle(Job *job)
+/* Called with job_mutex held. */
+static void job_event_idle_locked(Job *job)
 {
     notifier_list_notify(&job->on_idle, job);
 }
@@ -571,15 +581,18 @@ void job_enter(Job *job)
  * is allowed and cancels the timer.
  *
  * If @ns is (uint64_t) -1, no timer is scheduled and job_enter() must be
- * called explicitly. */
-static void coroutine_fn job_do_yield(Job *job, uint64_t ns)
+ * called explicitly.
+ *
+ * Called with job_mutex held, but releases it temporarly.
+ */
+static void coroutine_fn job_do_yield_locked(Job *job, uint64_t ns)
 {
     real_job_lock();
     if (ns != -1) {
         timer_mod(&job->sleep_timer, ns);
     }
     job->busy = false;
-    job_event_idle(job);
+    job_event_idle_locked(job);
     real_job_unlock();
     job_unlock();
     qemu_coroutine_yield();
@@ -594,7 +607,7 @@ void coroutine_fn job_pause_point(Job *job)
     assert(job && job_started(job));
 
     job_lock();
-    if (!job_should_pause(job)) {
+    if (!job_should_pause_locked(job)) {
         job_unlock();
         return;
     }
@@ -609,15 +622,15 @@ void coroutine_fn job_pause_point(Job *job)
         job_lock();
     }
 
-    if (job_should_pause(job) && !job_is_cancelled_locked(job)) {
+    if (job_should_pause_locked(job) && !job_is_cancelled_locked(job)) {
         JobStatus status = job->status;
-        job_state_transition(job, status == JOB_STATUS_READY
+        job_state_transition_locked(job, status == JOB_STATUS_READY
                                   ? JOB_STATUS_STANDBY
                                   : JOB_STATUS_PAUSED);
         job->paused = true;
-        job_do_yield(job, -1);
+        job_do_yield_locked(job, -1);
         job->paused = false;
-        job_state_transition(job, status);
+        job_state_transition_locked(job, status);
     }
     job_unlock();
 
@@ -636,8 +649,8 @@ void job_yield(Job *job)
             return;
         }
 
-        if (!job_should_pause(job)) {
-            job_do_yield(job, -1);
+        if (!job_should_pause_locked(job)) {
+            job_do_yield_locked(job, -1);
         }
     }
 
@@ -654,8 +667,9 @@ void coroutine_fn job_sleep_ns(Job *job, int64_t ns)
             return;
         }
 
-        if (!job_should_pause(job)) {
-            job_do_yield(job, qemu_clock_get_ns(QEMU_CLOCK_REALTIME) + ns);
+        if (!job_should_pause_locked(job)) {
+            job_do_yield_locked(job,
+                                qemu_clock_get_ns(QEMU_CLOCK_REALTIME) + ns);
         }
     }
 
@@ -726,16 +740,17 @@ void job_user_resume_locked(Job *job, Error **errp)
     job_resume_locked(job);
 }
 
-static void job_do_dismiss(Job *job)
+/* Called with job_mutex held. */
+static void job_do_dismiss_locked(Job *job)
 {
     assert(job);
     job->busy = false;
     job->paused = false;
     job->deferred_to_main_loop = true;
 
-    job_txn_del_job(job);
+    job_txn_del_job_locked(job);
 
-    job_state_transition(job, JOB_STATUS_NULL);
+    job_state_transition_locked(job, JOB_STATUS_NULL);
     job_unref_locked(job);
 }
 
@@ -748,14 +763,14 @@ void job_dismiss_locked(Job **jobptr, Error **errp)
         return;
     }
 
-    job_do_dismiss(job);
+    job_do_dismiss_locked(job);
     *jobptr = NULL;
 }
 
 void job_early_fail_locked(Job *job)
 {
     assert(job->status == JOB_STATUS_CREATED);
-    job_do_dismiss(job);
+    job_do_dismiss_locked(job);
 }
 
 void job_early_fail(Job *job)
@@ -764,15 +779,17 @@ void job_early_fail(Job *job)
     job_early_fail_locked(job);
 }
 
-static void job_conclude(Job *job)
+/* Called with job_mutex held. */
+static void job_conclude_locked(Job *job)
 {
-    job_state_transition(job, JOB_STATUS_CONCLUDED);
+    job_state_transition_locked(job, JOB_STATUS_CONCLUDED);
     if (job->auto_dismiss || !job_started(job)) {
-        job_do_dismiss(job);
+        job_do_dismiss_locked(job);
     }
 }
 
-static void job_update_rc(Job *job)
+/* Called with job_mutex held. */
+static void job_update_rc_locked(Job *job)
 {
     if (!job->ret && job_is_cancelled_locked(job)) {
         job->ret = -ECANCELED;
@@ -781,11 +798,12 @@ static void job_update_rc(Job *job)
         if (!job->err) {
             error_setg(&job->err, "%s", strerror(-job->ret));
         }
-        job_state_transition(job, JOB_STATUS_ABORTING);
+        job_state_transition_locked(job, JOB_STATUS_ABORTING);
     }
 }
 
-static void job_commit(Job *job)
+/* Called with job_mutex held, but releases it temporarly */
+static void job_commit_locked(Job *job)
 {
     assert(!job->ret);
     assert(qemu_in_main_thread());
@@ -796,7 +814,8 @@ static void job_commit(Job *job)
     }
 }
 
-static void job_abort(Job *job)
+/* Called with job_mutex held, but releases it temporarly */
+static void job_abort_locked(Job *job)
 {
     assert(job->ret);
     assert(qemu_in_main_thread());
@@ -807,7 +826,8 @@ static void job_abort(Job *job)
     }
 }
 
-static void job_clean(Job *job)
+/* Called with job_mutex held, but releases it temporarly */
+static void job_clean_locked(Job *job)
 {
     assert(qemu_in_main_thread());
     if (job->driver->clean) {
@@ -817,7 +837,8 @@ static void job_clean(Job *job)
     }
 }
 
-static int job_finalize_single(Job *job)
+/* Called with job_mutex held, but releases it temporarly. */
+static int job_finalize_single_locked(Job *job)
 {
     int job_ret;
     AioContext *ctx = job->aio_context;
@@ -825,16 +846,16 @@ static int job_finalize_single(Job *job)
     assert(job_is_completed_locked(job));
 
     /* Ensure abort is called for late-transactional failures */
-    job_update_rc(job);
+    job_update_rc_locked(job);
 
     aio_context_acquire(ctx);
 
     if (!job->ret) {
-        job_commit(job);
+        job_commit_locked(job);
     } else {
-        job_abort(job);
+        job_abort_locked(job);
     }
-    job_clean(job);
+    job_clean_locked(job);
 
     aio_context_release(ctx);
 
@@ -848,18 +869,19 @@ static int job_finalize_single(Job *job)
     /* Emit events only if we actually started */
     if (job_started(job)) {
         if (job_is_cancelled_locked(job)) {
-            job_event_cancelled(job);
+            job_event_cancelled_locked(job);
         } else {
-            job_event_completed(job);
+            job_event_completed_locked(job);
         }
     }
 
-    job_txn_del_job(job);
-    job_conclude(job);
+    job_txn_del_job_locked(job);
+    job_conclude_locked(job);
     return 0;
 }
 
-static void job_cancel_async(Job *job, bool force)
+/* Called with job_mutex held, but releases it temporarly. */
+static void job_cancel_async_locked(Job *job, bool force)
 {
     assert(qemu_in_main_thread());
     if (job->driver->cancel) {
@@ -897,7 +919,8 @@ static void job_cancel_async(Job *job, bool force)
     }
 }
 
-static void job_completed_txn_abort(Job *job)
+/* Called with job_mutex held. */
+static void job_completed_txn_abort_locked(Job *job)
 {
     AioContext *ctx;
     JobTxn *txn = job->txn;
@@ -910,12 +933,12 @@ static void job_completed_txn_abort(Job *job)
         return;
     }
     txn->aborting = true;
-    job_txn_ref(txn);
+    job_txn_ref_locked(txn);
 
     /*
      * We can only hold the single job's AioContext lock while calling
-     * job_finalize_single() because the finalization callbacks can involve
-     * calls of AIO_WAIT_WHILE(), which could deadlock otherwise.
+     * job_finalize_single_locked() because the finalization callbacks can
+     *  involve calls of AIO_WAIT_WHILE(), which could deadlock otherwise.
      * Note that the job's AioContext may change when it is finalized.
      */
     job_ref_locked(job);
@@ -930,10 +953,10 @@ static void job_completed_txn_abort(Job *job)
             aio_context_acquire(ctx);
             /*
              * This is a transaction: If one job failed, no result will matter.
-             * Therefore, pass force=true to terminate all other jobs as quickly
-             * as possible.
+             * Therefore, pass force=true to terminate all other jobs as
+             * quickly as possible.
              */
-            job_cancel_async(other_job, true);
+            job_cancel_async_locked(other_job, true);
             aio_context_release(ctx);
         }
     }
@@ -949,13 +972,13 @@ static void job_completed_txn_abort(Job *job)
             assert(job_cancel_requested_locked(other_job));
             job_finish_sync_locked(other_job, NULL, NULL);
         }
-        job_finalize_single(other_job);
+        job_finalize_single_locked(other_job);
         aio_context_release(ctx);
     }
 
     /*
      * Use job_ref_locked()/job_unref_locked() so we can read the AioContext
-     * here even if the job went away during job_finalize_single().
+     * here even if the job went away during job_finalize_single_locked().
      */
     aio_context_acquire(job->aio_context);
     job_unref_locked(job);
@@ -963,7 +986,8 @@ static void job_completed_txn_abort(Job *job)
     job_txn_unref_locked(txn);
 }
 
-static int job_prepare(Job *job)
+/* Called with job_mutex held, but releases it temporarly. */
+static int job_prepare_locked(Job *job)
 {
     int ret;
     AioContext *ctx = job->aio_context;
@@ -976,28 +1000,30 @@ static int job_prepare(Job *job)
         aio_context_release(ctx);
         job_lock();
         job->ret = ret;
-        job_update_rc(job);
+        job_update_rc_locked(job);
     }
 
     return job->ret;
 }
 
-static int job_needs_finalize(Job *job)
+/* Called with job_mutex held. */
+static int job_needs_finalize_locked(Job *job)
 {
     return !job->auto_finalize;
 }
 
-static void job_do_finalize(Job *job)
+/* Called with job_mutex held. */
+static void job_do_finalize_locked(Job *job)
 {
     int rc;
     assert(job && job->txn);
 
     /* prepare the transaction to complete */
-    rc = job_txn_apply(job, job_prepare);
+    rc = job_txn_apply_locked(job, job_prepare_locked);
     if (rc) {
-        job_completed_txn_abort(job);
+        job_completed_txn_abort_locked(job);
     } else {
-        job_txn_apply(job, job_finalize_single);
+        job_txn_apply_locked(job, job_finalize_single_locked);
     }
 }
 
@@ -1007,14 +1033,15 @@ void job_finalize_locked(Job *job, Error **errp)
     if (job_apply_verb_locked(job, JOB_VERB_FINALIZE, errp)) {
         return;
     }
-    job_do_finalize(job);
+    job_do_finalize_locked(job);
 }
 
-static int job_transition_to_pending(Job *job)
+/* Called with job_mutex held. */
+static int job_transition_to_pending_locked(Job *job)
 {
-    job_state_transition(job, JOB_STATUS_PENDING);
+    job_state_transition_locked(job, JOB_STATUS_PENDING);
     if (!job->auto_finalize) {
-        job_event_pending(job);
+        job_event_pending_locked(job);
     }
     return 0;
 }
@@ -1022,16 +1049,17 @@ static int job_transition_to_pending(Job *job)
 void job_transition_to_ready(Job *job)
 {
     JOB_LOCK_GUARD();
-    job_state_transition(job, JOB_STATUS_READY);
-    job_event_ready(job);
+    job_state_transition_locked(job, JOB_STATUS_READY);
+    job_event_ready_locked(job);
 }
 
-static void job_completed_txn_success(Job *job)
+/* Called with job_mutex held. */
+static void job_completed_txn_success_locked(Job *job)
 {
     JobTxn *txn = job->txn;
     Job *other_job;
 
-    job_state_transition(job, JOB_STATUS_WAITING);
+    job_state_transition_locked(job, JOB_STATUS_WAITING);
 
     /*
      * Successful completion, see if there are other running jobs in this
@@ -1044,28 +1072,32 @@ static void job_completed_txn_success(Job *job)
         assert(other_job->ret == 0);
     }
 
-    job_txn_apply(job, job_transition_to_pending);
+    job_txn_apply_locked(job, job_transition_to_pending_locked);
 
     /* If no jobs need manual finalization, automatically do so */
-    if (job_txn_apply(job, job_needs_finalize) == 0) {
-        job_do_finalize(job);
+    if (job_txn_apply_locked(job, job_needs_finalize_locked) == 0) {
+        job_do_finalize_locked(job);
     }
 }
 
-static void job_completed(Job *job)
+/* Called with job_mutex held. */
+static void job_completed_locked(Job *job)
 {
     assert(job && job->txn && !job_is_completed_locked(job));
 
-    job_update_rc(job);
+    job_update_rc_locked(job);
     trace_job_completed(job, job->ret);
     if (job->ret) {
-        job_completed_txn_abort(job);
+        job_completed_txn_abort_locked(job);
     } else {
-        job_completed_txn_success(job);
+        job_completed_txn_success_locked(job);
     }
 }
 
-/** Useful only as a type shim for aio_bh_schedule_oneshot. */
+/**
+ * Useful only as a type shim for aio_bh_schedule_oneshot.
+ *  Called with job_mutex *not* held.
+ */
 static void job_exit(void *opaque)
 {
     Job *job = (Job *)opaque;
@@ -1080,15 +1112,15 @@ static void job_exit(void *opaque)
      * drain block nodes, and if .drained_poll still returned true, we would
      * deadlock. */
     job->busy = false;
-    job_event_idle(job);
+    job_event_idle_locked(job);
 
-    job_completed(job);
+    job_completed_locked(job);
 
     /*
-     * Note that calling job_completed can move the job to a different
-     * aio_context, so we cannot cache from above. job_txn_apply takes care of
-     * acquiring the new lock, and we ref/unref to avoid job_completed freeing
-     * the job underneath us.
+     * Note that calling job_completed_locked can move the job to a different
+     * aio_context, so we cannot cache from above. job_txn_apply_locked takes
+     * care of acquiring the new lock, and we ref/unref to avoid
+     * job_completed_locked freeing the job underneath us.
      */
     ctx = job->aio_context;
     job_unref_locked(job);
@@ -1098,6 +1130,8 @@ static void job_exit(void *opaque)
 /**
  * All jobs must allow a pause point before entering their job proper. This
  * ensures that jobs can be paused prior to being started, then resumed later.
+ *
+ * Called with job_mutex *not* held.
  */
 static void coroutine_fn job_co_entry(void *opaque)
 {
@@ -1116,6 +1150,7 @@ static void coroutine_fn job_co_entry(void *opaque)
     aio_bh_schedule_oneshot(qemu_get_aio_context(), job_exit, job);
 }
 
+/* Called with job_mutex *not* held. */
 static int job_pre_run(Job *job)
 {
     assert(qemu_in_main_thread());
@@ -1140,7 +1175,7 @@ void job_start(Job *job)
         job->pause_count--;
         job->busy = true;
         job->paused = false;
-        job_state_transition(job, JOB_STATUS_RUNNING);
+        job_state_transition_locked(job, JOB_STATUS_RUNNING);
     }
     aio_co_enter(job->aio_context, job->co);
 }
@@ -1148,25 +1183,25 @@ void job_start(Job *job)
 void job_cancel_locked(Job *job, bool force)
 {
     if (job->status == JOB_STATUS_CONCLUDED) {
-        job_do_dismiss(job);
+        job_do_dismiss_locked(job);
         return;
     }
-    job_cancel_async(job, force);
+    job_cancel_async_locked(job, force);
     if (!job_started(job)) {
-        job_completed(job);
+        job_completed_locked(job);
     } else if (job->deferred_to_main_loop) {
         /*
-         * job_cancel_async() ignores soft-cancel requests for jobs
+         * job_cancel_async_locked() ignores soft-cancel requests for jobs
          * that are already done (i.e. deferred to the main loop).  We
          * have to check again whether the job is really cancelled.
          * (job_cancel_requested() and job_is_cancelled() are equivalent
-         * here, because job_cancel_async() will make soft-cancel
+         * here, because job_cancel_async_locked() will make soft-cancel
          * requests no-ops when deferred_to_main_loop is true.  We
          * choose to call job_is_cancelled() to show that we invoke
-         * job_completed_txn_abort() only for force-cancelled jobs.)
+         * job_completed_txn_abort_locked() only for force-cancelled jobs.)
          */
         if (job_is_cancelled_locked(job)) {
-            job_completed_txn_abort(job);
+            job_completed_txn_abort_locked(job);
         }
     } else {
         job_enter_cond_locked(job, NULL);
@@ -1185,16 +1220,20 @@ void job_user_cancel_locked(Job *job, bool force, Error **errp)
  * A wrapper around job_cancel_locked() taking an Error ** parameter so
  * it may be used with job_finish_sync_locked() without the
  * need for (rather nasty) function pointer casts there.
+ *
+ * Called with job_mutex held.
  */
-static void job_cancel_err(Job *job, Error **errp)
+static void job_cancel_err_locked(Job *job, Error **errp)
 {
     job_cancel_locked(job, false);
 }
 
 /**
- * Same as job_cancel_err(), but force-cancel.
+ * Same as job_cancel_err_locked(), but force-cancel.
+ *
+ * Called with job_mutex held.
  */
-static void job_force_cancel_err(Job *job, Error **errp)
+static void job_force_cancel_err_locked(Job *job, Error **errp)
 {
     job_cancel_locked(job, true);
 }
@@ -1202,9 +1241,9 @@ static void job_force_cancel_err(Job *job, Error **errp)
 int job_cancel_sync_locked(Job *job, bool force)
 {
     if (force) {
-        return job_finish_sync_locked(job, &job_force_cancel_err, NULL);
+        return job_finish_sync_locked(job, &job_force_cancel_err_locked, NULL);
     } else {
-        return job_finish_sync_locked(job, &job_cancel_err, NULL);
+        return job_finish_sync_locked(job, &job_cancel_err_locked, NULL);
     }
 }
 
-- 
2.31.1



^ permalink raw reply related

* [PATCH v3 1/5] i2c: Introduce common module to instantiate CCGx UCSI
From: Andy Shevchenko @ 2022-01-05 14:19 UTC (permalink / raw)
  To: Wolfram Sang, Andy Shevchenko, linux-kernel, linux-i2c
  Cc: Jarkko Nikula, Mika Westerberg, Ajay Gupta,
	Shah, Nehal-bakulchandra

Introduce a common module to provide an API to instantiate UCSI device
for Cypress CCGx Type-C controller. Individual bus drivers need to select
this one on demand.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
v3: added MODULE_LICENSE(GPL); (Nehal-bakulchandra)
 drivers/i2c/busses/Kconfig         |  7 +++++++
 drivers/i2c/busses/Makefile        |  3 +++
 drivers/i2c/busses/i2c-ccgx-ucsi.c | 30 ++++++++++++++++++++++++++++++
 drivers/i2c/busses/i2c-ccgx-ucsi.h | 11 +++++++++++
 4 files changed, 51 insertions(+)
 create mode 100644 drivers/i2c/busses/i2c-ccgx-ucsi.c
 create mode 100644 drivers/i2c/busses/i2c-ccgx-ucsi.h

diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index 42da31c1ab70..08e24e396e37 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -9,6 +9,13 @@ menu "I2C Hardware Bus support"
 comment "PC SMBus host controller drivers"
 	depends on PCI
 
+config I2C_CCGX_UCSI
+	tristate
+	help
+	  A common module to provide an API to instantiate UCSI device
+	  for Cypress CCGx Type-C controller. Individual bus drivers
+	  need to select this one on demand.
+
 config I2C_ALI1535
 	tristate "ALI 1535"
 	depends on PCI
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
index 1d00dce77098..79405cb5d600 100644
--- a/drivers/i2c/busses/Makefile
+++ b/drivers/i2c/busses/Makefile
@@ -6,6 +6,9 @@
 # ACPI drivers
 obj-$(CONFIG_I2C_SCMI)		+= i2c-scmi.o
 
+# Auxiliary I2C/SMBus modules
+obj-$(CONFIG_I2C_CCGX_UCSI)	+= i2c-ccgx-ucsi.o
+
 # PC SMBus host controller drivers
 obj-$(CONFIG_I2C_ALI1535)	+= i2c-ali1535.o
 obj-$(CONFIG_I2C_ALI1563)	+= i2c-ali1563.o
diff --git a/drivers/i2c/busses/i2c-ccgx-ucsi.c b/drivers/i2c/busses/i2c-ccgx-ucsi.c
new file mode 100644
index 000000000000..092dc92dea9f
--- /dev/null
+++ b/drivers/i2c/busses/i2c-ccgx-ucsi.c
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Instantiate UCSI device for Cypress CCGx Type-C controller.
+ * Derived from i2c-designware-pcidrv.c and i2c-nvidia-gpu.c.
+ */
+
+#include <linux/i2c.h>
+#include <linux/export.h>
+#include <linux/module.h>
+#include <linux/string.h>
+
+#include "i2c-ccgx-ucsi.h"
+
+struct software_node;
+
+struct i2c_client *i2c_new_ccgx_ucsi(struct i2c_adapter *adapter, int irq,
+				     const struct software_node *swnode)
+{
+	struct i2c_board_info info = {};
+
+	strscpy(info.type, "ccgx-ucsi", sizeof(info.type));
+	info.addr = 0x08;
+	info.irq = irq;
+	info.swnode = swnode;
+
+	return i2c_new_client_device(adapter, &info);
+}
+EXPORT_SYMBOL_GPL(i2c_new_ccgx_ucsi);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/i2c/busses/i2c-ccgx-ucsi.h b/drivers/i2c/busses/i2c-ccgx-ucsi.h
new file mode 100644
index 000000000000..739ac7a4b117
--- /dev/null
+++ b/drivers/i2c/busses/i2c-ccgx-ucsi.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+#ifndef __I2C_CCGX_UCSI_H_
+#define __I2C_CCGX_UCSI_H_
+
+struct i2c_adapter;
+struct i2c_client;
+struct software_node;
+
+struct i2c_client *i2c_new_ccgx_ucsi(struct i2c_adapter *adapter, int irq,
+				     const struct software_node *swnode);
+#endif /* __I2C_CCGX_UCSI_H_ */
-- 
2.34.1


^ permalink raw reply related

* Handling SIGTSTP (Ctrl+Z) /SIGCONT/fg with aplay/cplay
From: Daniel Baluta @ 2022-01-05 14:31 UTC (permalink / raw)
  To: Linux-ALSA, Mark Brown, Takashi Iwai, sound-open-firmware,
	S.j. Wang, Vinod Koul

Hi all,

Is there any quick document for handling Ctrl + Z with aplay/cplay?

I don't see this signal handled with alsa-lib or tinycompress although
linux kernel offers PAUSE/RESUME ioctls.

What should be the expected behavior?

thanks,
Daniel.

^ permalink raw reply

* [PATCH v3 4/5] i2c: nvidia-gpu: Convert to use dev_err_probe()
From: Andy Shevchenko @ 2022-01-05 14:19 UTC (permalink / raw)
  To: Wolfram Sang, Andy Shevchenko, linux-kernel, linux-i2c
  Cc: Jarkko Nikula, Mika Westerberg, Ajay Gupta,
	Shah, Nehal-bakulchandra
In-Reply-To: <20220105141935.24109-1-andriy.shevchenko@linux.intel.com>

It's fine to call dev_err_probe() in ->probe() when error code is known.
Convert the driver to use dev_err_probe().

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
v3: no changes
 drivers/i2c/busses/i2c-nvidia-gpu.c | 18 ++++++------------
 1 file changed, 6 insertions(+), 12 deletions(-)

diff --git a/drivers/i2c/busses/i2c-nvidia-gpu.c b/drivers/i2c/busses/i2c-nvidia-gpu.c
index a82be377146e..6920c1b9a126 100644
--- a/drivers/i2c/busses/i2c-nvidia-gpu.c
+++ b/drivers/i2c/busses/i2c-nvidia-gpu.c
@@ -282,24 +282,18 @@ static int gpu_i2c_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 	dev_set_drvdata(dev, i2cd);
 
 	status = pcim_enable_device(pdev);
-	if (status < 0) {
-		dev_err(dev, "pcim_enable_device failed %d\n", status);
-		return status;
-	}
+	if (status < 0)
+		return dev_err_probe(dev, status, "pcim_enable_device failed\n");
 
 	pci_set_master(pdev);
 
 	i2cd->regs = pcim_iomap(pdev, 0, 0);
-	if (!i2cd->regs) {
-		dev_err(dev, "pcim_iomap failed\n");
-		return -ENOMEM;
-	}
+	if (!i2cd->regs)
+		return dev_err_probe(dev, -ENOMEM, "pcim_iomap failed\n");
 
 	status = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_MSI);
-	if (status < 0) {
-		dev_err(dev, "pci_alloc_irq_vectors err %d\n", status);
-		return status;
-	}
+	if (status < 0)
+		return dev_err_probe(dev, status, "pci_alloc_irq_vectors err\n");
 
 	gpu_enable_i2c_bus(i2cd);
 
-- 
2.34.1


^ permalink raw reply related

* Re: pinctrl-cherryview regression in linux-next on preproduction Braswell
From: Jarkko Nikula @ 2022-01-05 14:23 UTC (permalink / raw)
  To: Hans de Goede; +Cc: linux-gpio, Mika Westerberg, Andy Shevchenko
In-Reply-To: <d04b5312-a38f-e7a7-f6cf-35320daade39@redhat.com>

On 1/4/22 16:47, Hans de Goede wrote:
> Hi Jarkko,
> 
> On 1/4/22 15:38, Jarkko Nikula wrote:
>> That gave me an idea to look at is there anything suspicious in "top" or /proc/interrupts (no and no) but powertop shows CPU 0 is over 90 % in C0 state and max frequency.
>>
>> But comparing powertop on v5.16-rc8 it does look sometimes the same and sometimes CPU 0 is less in C0 (but still over 30 %). Hard to say is there difference but obviously v5.16-rc8 either is not good on this machine since CPU 0 and package seems to reach idle only 5 % or less.
> 
> Hmm, does this happen to with the "hack" patch to initially mask interrupts
> triggered by all the interrupt-lines of the GPIO-controller ?
> 
> Ah upon reading your reply a second time I see you already checked
> /proc/interrupts; and that you are also seeing this with 5.16-rc8.
> 
> So the load is likely not caused by the pinctrl issue and there also
> is some other issue I guess...
> 
> For the high cpu-load issue it would be good to know if this is
> also present on older kernels.
> 
Sorry I mean cpu load is near idle according to top and no visible 
interrupt flood in /proc/interrupts but powertop shows CPU 0 is mostly 
in C0 or C1 state and doesn't idle or idles very near to 0 %. This is 
from v5.16-rc8.

I think on this machine only MMC card detect is using the pincontrol. At 
least pinctrl_cherryview module usage drops to zero and no users in 
/sys/kernel/debug/gpio after unbinding all devices from 
/sys/bus/platform/drivers/sdhci-acpi/.

MMC looks like to be well behaving since nothing changes after unbinding 
it and card detect is this one "INT33FF:03: using interrupt line 0 for 
pin 81".

However if I blacklist cherryview-pinctrl then CPU 0 and package will 
reach deeper C states. Perhaps misconfigured pin etc by the firmware?

But since those issues were here before the regression and your fix 
makes the machine booting again this case is solved by it.

Jarkko

^ permalink raw reply

* Re: [PATCH v1 1/1] can: mcp251x: Get rid of duplicate of_node assignment
From: Andy Shevchenko @ 2022-01-05 14:21 UTC (permalink / raw)
  To: Marc Kleine-Budde
  Cc: linux-can, netdev, linux-kernel, Wolfgang Grandegger,
	David S. Miller, Jakub Kicinski
In-Reply-To: <YbNT4iOj+jfMiIDu@smile.fi.intel.com>

On Fri, Dec 10, 2021 at 03:19:31PM +0200, Andy Shevchenko wrote:
> On Fri, Dec 10, 2021 at 02:06:07PM +0100, Marc Kleine-Budde wrote:
> > On 09.12.2021 13:58:40, Andy Shevchenko wrote:
> > > On Thu, Dec 02, 2021 at 10:58:55PM +0200, Andy Shevchenko wrote:
> 
> ...
> 
> > > Marc, what do you think about this change?
> > 
> > LGTM, added to linux-can-next/testing.
> 
> Thanks for applying this and hi311x patches!

Can we have a chance to see it in the v5.17-rc1?

-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply

* [next] mm/shmem.c:3993:5: error: conflicting types for 'shmem_unuse'; have 'int(unsigned int, long unsigned int *)'
From: Naresh Kamboju @ 2022-01-05 14:31 UTC (permalink / raw)
  To: linux-mm, open list, Linux-Next Mailing List
  Cc: Hugh Dickins, Andrew Morton, Stephen Rothwell, Christoph Hellwig,
	Juergen Gross, Dan Streetman, Geert Uytterhoeven,
	Konrad Rzeszutek Wilk, Matthew Wilcox, Seth Jennings, Vitaly Wool,
	lkft-triage

[Please ignore this email if it already reported]
A large number of build failures noticed on Linux next for all arch's with
 - tinyconfig
 - allnoconfig

Build Error:
-------------
mm/shmem.c:3993:5: error: conflicting types for 'shmem_unuse'; have
'int(unsigned int,  long unsigned int *)'
 3993 | int shmem_unuse(unsigned int type, unsigned long *fs_pages_to_unuse)
      |     ^~~~~~~~~~~
In file included from include/linux/khugepaged.h:6,
                 from mm/shmem.c:37:
include/linux/shmem_fs.h:86:5: note: previous declaration of
'shmem_unuse' with type 'int(unsigned int)'
   86 | int shmem_unuse(unsigned int type);
      |     ^~~~~~~~~~~
make[2]: *** [scripts/Makefile.build:289: mm/shmem.o] Error 1

Reported-by: Linux Kernel Functional Testing <lkft@linaro.org>

Build link: https://builds.tuxbuild.com/23GvPWRYOYokAPaEnhSYeOKuKCk/
Kconfig: https://builds.tuxbuild.com/23GvPWRYOYokAPaEnhSYeOKuKCk/config

Steps to reproduce:
# To install tuxmake on your system globally:
# sudo pip3 install -U tuxmake

tuxmake --runtime podman --target-arch x86_64 --toolchain gcc-11
--kconfig tinyconfig

--
Linaro LKFT
https://lkft.linaro.org

^ permalink raw reply

* Re: [PATCH 0/8] Add low power hibernation support to cs35l41
From: Mark Brown @ 2022-01-05 14:30 UTC (permalink / raw)
  To: Charles Keepax; +Cc: patches, alsa-devel, david.rhodes, lgirdwood, tiwai
In-Reply-To: <20220105113026.18955-1-ckeepax@opensource.cirrus.com>

[-- Attachment #1: Type: text/plain, Size: 673 bytes --]

On Wed, Jan 05, 2022 at 11:30:18AM +0000, Charles Keepax wrote:

> Patches 7,8 specifically will cause some very minor conflicts with
> Lucas's currently outstanding work on the HDA version of cs35l41.
> Whilst things will still build, this patch adds a test key function

No they won't, an x86 allmodconfig gives this:

ERROR: modpost: "cs35l41_pm_ops" [sound/soc/codecs/snd-soc-cs35l41-i2c.ko] undefined!
ERROR: modpost: "cs35l41_pm_ops" [sound/soc/codecs/snd-soc-cs35l41-spi.ko] undefined!
ERROR: modpost: "cs35l41_test_key_lock" [sound/soc/codecs/snd-soc-cs35l41.ko] undefined!
ERROR: modpost: "cs35l41_test_key_unlock" [sound/soc/codecs/snd-soc-cs35l41.ko] undefined!

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply


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.