* [PATCH 2/3] f2fs: add migration count iff migration happens
From: Jaegeuk Kim @ 2020-02-14 18:58 UTC (permalink / raw)
To: linux-kernel, linux-f2fs-devel; +Cc: Jaegeuk Kim
In-Reply-To: <20200214185855.217360-1-jaegeuk@kernel.org>
If first segment is empty and migration_granularity is 1, we can't move this
at all.
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
---
fs/f2fs/gc.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
index 65c0687ee2bb..bbf4db3f6bb4 100644
--- a/fs/f2fs/gc.c
+++ b/fs/f2fs/gc.c
@@ -1233,12 +1233,12 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi,
segno, gc_type);
stat_inc_seg_count(sbi, type, gc_type);
+ migrated++;
freed:
if (gc_type == FG_GC &&
get_valid_blocks(sbi, segno, false) == 0)
seg_freed++;
- migrated++;
if (__is_large_section(sbi) && segno + 1 < end_segno)
sbi->next_victim_seg[gc_type] = segno + 1;
--
2.25.0.265.gbab2e86ba0-goog
^ permalink raw reply related
* Re: [PATCH 00/12] SEV Live Migration Patchset.
From: Andy Lutomirski @ 2020-02-14 18:58 UTC (permalink / raw)
To: Ashish Kalra
Cc: Andy Lutomirski, Paolo Bonzini, Thomas Gleixner, Ingo Molnar,
H. Peter Anvin, Radim Krcmar, Joerg Roedel, Borislav Petkov,
Tom Lendacky, David Rientjes, X86 ML, kvm list, LKML,
Brijesh Singh
In-Reply-To: <20200213230916.GB8784@ashkalra_ubuntu_server>
On Thu, Feb 13, 2020 at 3:09 PM Ashish Kalra <ashish.kalra@amd.com> wrote:
>
> On Wed, Feb 12, 2020 at 09:43:41PM -0800, Andy Lutomirski wrote:
> > On Wed, Feb 12, 2020 at 5:14 PM Ashish Kalra <Ashish.Kalra@amd.com> wrote:
> > >
> > > From: Ashish Kalra <ashish.kalra@amd.com>
> > >
> > > This patchset adds support for SEV Live Migration on KVM/QEMU.
> >
> > I skimmed this all and I don't see any description of how this all works.
> >
> > Does any of this address the mess in svm_register_enc_region()? Right
> > now, when QEMU (or a QEMU alternative) wants to allocate some memory
> > to be used for guest encrypted pages, it mmap()s some memory and the
> > kernel does get_user_pages_fast() on it. The pages are kept pinned
> > for the lifetime of the mapping. This is not at all okay. Let's see:
> >
> > - The memory is pinned and it doesn't play well with the Linux memory
> > management code. You just wrote a big patch set to migrate the pages
> > to a whole different machines, but we apparently can't even migrate
> > them to a different NUMA node or even just a different address. And
> > good luck swapping it out.
> >
> > - The memory is still mapped in the QEMU process, and that mapping is
> > incoherent with actual guest access to the memory. It's nice that KVM
> > clflushes it so that, in principle, everything might actually work,
> > but this is gross. We should not be exposing incoherent mappings to
> > userspace.
> >
> > Perhaps all this fancy infrastructure you're writing for migration and
> > all this new API surface could also teach the kernel how to migrate
> > pages from a guest *to the same guest* so we don't need to pin pages
> > forever. And perhaps you could put some thought into how to improve
> > the API so that it doesn't involve nonsensical incoherent mappings.o
>
> As a different key is used to encrypt memory in each VM, the hypervisor
> can't simply copy the the ciphertext from one VM to another to migrate
> the VM. Therefore, the AMD SEV Key Management API provides a new sets
> of function which the hypervisor can use to package a guest page for
> migration, while maintaining the confidentiality provided by AMD SEV.
>
> There is a new page encryption bitmap created in the kernel which
> keeps tracks of encrypted/decrypted state of guest's pages and this
> bitmap is updated by a new hypercall interface provided to the guest
> kernel and firmware.
>
> KVM_GET_PAGE_ENC_BITMAP ioctl can be used to get the guest page encryption
> bitmap. The bitmap can be used to check if the given guest page is
> private or shared.
>
> During the migration flow, the SEND_START is called on the source hypervisor
> to create an outgoing encryption context. The SEV guest policy dictates whether
> the certificate passed through the migrate-set-parameters command will be
> validated. SEND_UPDATE_DATA is called to encrypt the guest private pages.
> After migration is completed, SEND_FINISH is called to destroy the encryption
> context and make the VM non-runnable to protect it against cloning.
>
> On the target machine, RECEIVE_START is called first to create an
> incoming encryption context. The RECEIVE_UPDATE_DATA is called to copy
> the received encrypted page into guest memory. After migration has
> completed, RECEIVE_FINISH is called to make the VM runnable.
>
Thanks! This belongs somewhere in the patch set.
You still haven't answered my questions about the existing coherency
issues and whether the same infrastructure can be used to migrate
guest pages within the same machine.
Also, you're making guest-side and host-side changes. What ensures
that you don't try to migrate a guest that doesn't support the
hypercall for encryption state tracking?
^ permalink raw reply
* [f2fs-dev] [PATCH 3/3] f2fs: skip migration only when BG_GC is called
From: Jaegeuk Kim @ 2020-02-14 18:58 UTC (permalink / raw)
To: linux-kernel, linux-f2fs-devel; +Cc: Jaegeuk Kim
In-Reply-To: <20200214185855.217360-1-jaegeuk@kernel.org>
FG_GC needs to move entire section more quickly.
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
---
fs/f2fs/gc.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
index bbf4db3f6bb4..1676eebc8c8b 100644
--- a/fs/f2fs/gc.c
+++ b/fs/f2fs/gc.c
@@ -1203,7 +1203,7 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi,
if (get_valid_blocks(sbi, segno, false) == 0)
goto freed;
- if (__is_large_section(sbi) &&
+ if (gc_type == BG_GC && __is_large_section(sbi) &&
migrated >= sbi->migration_granularity)
goto skip;
if (!PageUptodate(sum_page) || unlikely(f2fs_cp_error(sbi)))
--
2.25.0.265.gbab2e86ba0-goog
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply related
* [f2fs-dev] [PATCH 2/3] f2fs: add migration count iff migration happens
From: Jaegeuk Kim @ 2020-02-14 18:58 UTC (permalink / raw)
To: linux-kernel, linux-f2fs-devel; +Cc: Jaegeuk Kim
In-Reply-To: <20200214185855.217360-1-jaegeuk@kernel.org>
If first segment is empty and migration_granularity is 1, we can't move this
at all.
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
---
fs/f2fs/gc.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
index 65c0687ee2bb..bbf4db3f6bb4 100644
--- a/fs/f2fs/gc.c
+++ b/fs/f2fs/gc.c
@@ -1233,12 +1233,12 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi,
segno, gc_type);
stat_inc_seg_count(sbi, type, gc_type);
+ migrated++;
freed:
if (gc_type == FG_GC &&
get_valid_blocks(sbi, segno, false) == 0)
seg_freed++;
- migrated++;
if (__is_large_section(sbi) && segno + 1 < end_segno)
sbi->next_victim_seg[gc_type] = segno + 1;
--
2.25.0.265.gbab2e86ba0-goog
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply related
* [f2fs-dev] [PATCH 1/3] f2fs: skip GC when section is full
From: Jaegeuk Kim @ 2020-02-14 18:58 UTC (permalink / raw)
To: linux-kernel, linux-f2fs-devel; +Cc: Jaegeuk Kim
This fixes skipping GC when segment is full in large section.
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
---
fs/f2fs/gc.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
index 53312d7bc78b..65c0687ee2bb 100644
--- a/fs/f2fs/gc.c
+++ b/fs/f2fs/gc.c
@@ -1018,8 +1018,8 @@ static int gc_data_segment(struct f2fs_sb_info *sbi, struct f2fs_summary *sum,
* race condition along with SSR block allocation.
*/
if ((gc_type == BG_GC && has_not_enough_free_secs(sbi, 0, 0)) ||
- get_valid_blocks(sbi, segno, false) ==
- sbi->blocks_per_seg)
+ get_valid_blocks(sbi, segno, true) ==
+ BLKS_PER_SEC(sbi))
return submitted;
if (check_valid_map(sbi, segno, off) == 0)
--
2.25.0.265.gbab2e86ba0-goog
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply related
* [PATCH 3/3] f2fs: skip migration only when BG_GC is called
From: Jaegeuk Kim @ 2020-02-14 18:58 UTC (permalink / raw)
To: linux-kernel, linux-f2fs-devel; +Cc: Jaegeuk Kim
In-Reply-To: <20200214185855.217360-1-jaegeuk@kernel.org>
FG_GC needs to move entire section more quickly.
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
---
fs/f2fs/gc.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
index bbf4db3f6bb4..1676eebc8c8b 100644
--- a/fs/f2fs/gc.c
+++ b/fs/f2fs/gc.c
@@ -1203,7 +1203,7 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi,
if (get_valid_blocks(sbi, segno, false) == 0)
goto freed;
- if (__is_large_section(sbi) &&
+ if (gc_type == BG_GC && __is_large_section(sbi) &&
migrated >= sbi->migration_granularity)
goto skip;
if (!PageUptodate(sum_page) || unlikely(f2fs_cp_error(sbi)))
--
2.25.0.265.gbab2e86ba0-goog
^ permalink raw reply related
* [PATCH 1/3] f2fs: skip GC when section is full
From: Jaegeuk Kim @ 2020-02-14 18:58 UTC (permalink / raw)
To: linux-kernel, linux-f2fs-devel; +Cc: Jaegeuk Kim
This fixes skipping GC when segment is full in large section.
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
---
fs/f2fs/gc.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
index 53312d7bc78b..65c0687ee2bb 100644
--- a/fs/f2fs/gc.c
+++ b/fs/f2fs/gc.c
@@ -1018,8 +1018,8 @@ static int gc_data_segment(struct f2fs_sb_info *sbi, struct f2fs_summary *sum,
* race condition along with SSR block allocation.
*/
if ((gc_type == BG_GC && has_not_enough_free_secs(sbi, 0, 0)) ||
- get_valid_blocks(sbi, segno, false) ==
- sbi->blocks_per_seg)
+ get_valid_blocks(sbi, segno, true) ==
+ BLKS_PER_SEC(sbi))
return submitted;
if (check_valid_map(sbi, segno, off) == 0)
--
2.25.0.265.gbab2e86ba0-goog
^ permalink raw reply related
* [PATCH] busybox: Fix typo in patch
From: Khem Raj @ 2020-02-14 18:58 UTC (permalink / raw)
To: openembedded-core
Signed-off-by: Khem Raj <raj.khem@gmail.com>
---
...1-Remove-syscall-wrappers-around-clock_gettime-closes-.patch | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/meta/recipes-core/busybox/busybox/0001-Remove-syscall-wrappers-around-clock_gettime-closes-.patch b/meta/recipes-core/busybox/busybox/0001-Remove-syscall-wrappers-around-clock_gettime-closes-.patch
index 1217daa108..0c7f9b8132 100644
--- a/meta/recipes-core/busybox/busybox/0001-Remove-syscall-wrappers-around-clock_gettime-closes-.patch
+++ b/meta/recipes-core/busybox/busybox/0001-Remove-syscall-wrappers-around-clock_gettime-closes-.patch
@@ -63,7 +63,7 @@ Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
- * typically requiring -lrt. We just skip all this mess */
- syscall(__NR_clock_gettime, CLOCK_REALTIME, &ts);
-#elif ENABLE_FEATURE_DATE_NANO && __TIMESIZE == 64
-- /* Let's only suppor the 64 suffix syscalls for 64-bit time_t.
+- /* Let's only support the 64 suffix syscalls for 64-bit time_t.
- * This simplifies the code for us as we don't need to convert
- * between 64-bit and 32-bit. We also don't have a way to
- * report overflow errors here.
--
2.25.0
^ permalink raw reply related
* Re: [PATCH 1/2] rtnl: Make IPv4 and IPv6 naming scheme consistent
From: Denis Kenzior @ 2020-02-14 18:58 UTC (permalink / raw)
To: ell
In-Reply-To: <20200214182337.11132-2-wagi@monom.org>
[-- Attachment #1: Type: text/plain, Size: 603 bytes --]
Hi Daniel,
On 2/14/20 12:23 PM, Daniel Wagner wrote:
> Add the protocol version into into the function names and drop the
> infix 'ipv6' string. This makes it more consistent with the existing
> APIs.
> ---
> ell/rtnl.c | 52 ++++++++++++++++++++++++------------------------
> ell/rtnl.h | 28 +++++++++++++-------------
> unit/test-rtnl.c | 42 +++++++++++++++++++-------------------
> 3 files changed, 61 insertions(+), 61 deletions(-)
>
Applied after splitting this patch in two. One for rtnl.[ch] changes
and one for unit/ directory changes.
Regards,
-Denis
^ permalink raw reply
* [meta-python][PATCH] python3-behave: consolidate inc and bb files into a single bb file
From: Derek Straka @ 2020-02-14 18:57 UTC (permalink / raw)
To: openembedded-devel
Signed-off-by: Derek Straka <derek@asterius.io>
---
.../recipes-devtools/python/python-behave.inc | 15 ---------------
.../python/python3-behave_1.2.6.bb | 17 +++++++++++++++--
2 files changed, 15 insertions(+), 17 deletions(-)
delete mode 100644 meta-python/recipes-devtools/python/python-behave.inc
diff --git a/meta-python/recipes-devtools/python/python-behave.inc b/meta-python/recipes-devtools/python/python-behave.inc
deleted file mode 100644
index ded75801dd..0000000000
--- a/meta-python/recipes-devtools/python/python-behave.inc
+++ /dev/null
@@ -1,15 +0,0 @@
-SUMMARY = "A behavior-driven development framework, Python style"
-HOMEPAGE = "https://github.com/behave/behave"
-LICENSE = "BSD-2-Clause"
-LIC_FILES_CHKSUM = "file://LICENSE;md5=d950439e8ea6ed233e4288f5e1a49c06"
-
-SRC_URI[md5sum] = "3f05c859a1c45f5ed33e925817ad887d"
-SRC_URI[sha256sum] = "b9662327aa53294c1351b0a9c369093ccec1d21026f050c3bd9b3e5cccf81a86"
-
-inherit pypi
-
-RDEPENDS_${PN} += " \
- ${PYTHON_PN}-parse-type \
- ${PYTHON_PN}-setuptools \
- ${PYTHON_PN}-six \
- "
diff --git a/meta-python/recipes-devtools/python/python3-behave_1.2.6.bb b/meta-python/recipes-devtools/python/python3-behave_1.2.6.bb
index 1c55871b10..a28e527315 100644
--- a/meta-python/recipes-devtools/python/python3-behave_1.2.6.bb
+++ b/meta-python/recipes-devtools/python/python3-behave_1.2.6.bb
@@ -1,2 +1,15 @@
-inherit setuptools3
-require python-behave.inc
+SUMMARY = "A behavior-driven development framework, Python style"
+HOMEPAGE = "https://github.com/behave/behave"
+LICENSE = "BSD-2-Clause"
+LIC_FILES_CHKSUM = "file://LICENSE;md5=d950439e8ea6ed233e4288f5e1a49c06"
+
+SRC_URI[md5sum] = "3f05c859a1c45f5ed33e925817ad887d"
+SRC_URI[sha256sum] = "b9662327aa53294c1351b0a9c369093ccec1d21026f050c3bd9b3e5cccf81a86"
+
+inherit pypi setuptools3
+
+RDEPENDS_${PN} += " \
+ ${PYTHON_PN}-parse-type \
+ ${PYTHON_PN}-setuptools \
+ ${PYTHON_PN}-six \
+ "
--
2.17.1
^ permalink raw reply related
* Re: [PATCH 10/12] mm: x86: Invoke hypercall when page encryption status is changed
From: Andy Lutomirski @ 2020-02-14 18:56 UTC (permalink / raw)
To: Ashish Kalra
Cc: Paolo Bonzini, Thomas Gleixner, Ingo Molnar, H. Peter Anvin,
Radim Krcmar, Joerg Roedel, Borislav Petkov, Tom Lendacky,
David Rientjes, X86 ML, kvm list, LKML
In-Reply-To: <20200213222825.GA8784@ashkalra_ubuntu_server>
On Thu, Feb 13, 2020 at 2:28 PM Ashish Kalra <ashish.kalra@amd.com> wrote:
>
> On Wed, Feb 12, 2020 at 09:42:02PM -0800, Andy Lutomirski wrote:
> >> On Wed, Feb 12, 2020 at 5:18 PM Ashish Kalra <Ashish.Kalra@amd.com> wrote:
> >> >
> >> > From: Brijesh Singh <brijesh.singh@amd.com>
> > >
> > > Invoke a hypercall when a memory region is changed from encrypted ->
> > > decrypted and vice versa. Hypervisor need to know the page encryption
> > > status during the guest migration.
> >>
> >> What happens if the guest memory status doesn't match what the
> >> hypervisor thinks it is? What happens if the guest gets migrated
> >> between the hypercall and the associated flushes?
>
> This is basically same as the dirty page tracking and logging being done
> during Live Migration. As with dirty page tracking and logging we
> maintain a page encryption bitmap in the kernel which keeps tracks of
> guest's page encrypted/decrypted state changes and this bitmap is
> sync'ed regularly from kernel to qemu and also during the live migration
> process, therefore any dirty pages whose encryption status will change
> during migration, should also have their page status updated when the
> page encryption bitmap is sync'ed.
>
> Also i think that when the amount of dirty pages reach a low threshold,
> QEMU stops the source VM and then transfers all the remaining dirty
> pages, so at that point, there will also be a final sync of the page
> encryption bitmap, there won't be any hypercalls after this as the
> source VM has been stopped and the remaining VM state gets transferred.
And have you ensured that, in the inevitable race when a guest gets
migrated part way through an encryption state change, that no data
corruption occurs?
^ permalink raw reply
* Re: [PATCH v2 5/8] serial: 8250_port: Don't use power management for kernel console
From: Andy Shevchenko @ 2020-02-14 18:56 UTC (permalink / raw)
To: Tony Lindgren
Cc: Greg Kroah-Hartman, Jiri Slaby, linux-serial,
Sebastian Andrzej Siewior, Russell King
In-Reply-To: <20200214181407.GQ16391@atomide.com>
On Fri, Feb 14, 2020 at 10:14:07AM -0800, Tony Lindgren wrote:
> * Andy Shevchenko <andriy.shevchenko@linux.intel.com> [200214 11:44]:
> > --- a/drivers/tty/serial/8250/8250_core.c
> > +++ b/drivers/tty/serial/8250/8250_core.c
> > @@ -608,6 +608,14 @@ static int univ8250_console_setup(struct console *co, char *options)
> > return retval;
> > }
> >
> > +static int univ8250_console_exit(struct console *co)
> > +{
> > + struct uart_port *port;
> > +
> > + port = &serial8250_ports[co->index].port;
> > + return serial8250_console_exit(port);
> > +}
> > +
> > /**
> > * univ8250_console_match - non-standard console matching
> > * @co: registering console
> > @@ -666,6 +674,7 @@ static struct console univ8250_console = {
> > .write = univ8250_console_write,
> > .device = uart_console_device,
> > .setup = univ8250_console_setup,
> > + .exit = univ8250_console_exit,
> > .match = univ8250_console_match,
> > .flags = CON_PRINTBUFFER | CON_ANYTIME,
> > .index = -1,
>
> You're missing adding exit to struct console or these patches
> are based on some tree I don't have. I had to add the following
> change to compile for you to fold into this patch.
In cover letter the [1] link answers to this.
Can you try again with that series being applied first?
>
> Regards,
>
> Tony
>
> 8< -------------------
> diff --git a/include/linux/console.h b/include/linux/console.h
> --- a/include/linux/console.h
> +++ b/include/linux/console.h
> @@ -148,6 +148,7 @@ struct console {
> struct tty_driver *(*device)(struct console *, int *);
> void (*unblank)(void);
> int (*setup)(struct console *, char *);
> + int (*exit)(struct console *);
> int (*match)(struct console *, char *name, int idx, char *options);
> short flags;
> short index;
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply
* [Xen-devel] [PATCH] AMD/IOMMU: Common the #732/#733 errata handling in iommu_read_log()
From: Andrew Cooper @ 2020-02-14 18:55 UTC (permalink / raw)
To: Xen-devel; +Cc: Andrew Cooper, Wei Liu, Jan Beulich, Roger Pau Monné
There is no need to have both helpers implement the same workaround. The size
and layout of the the Event and PPR logs (and others for that matter) share a
lot of commonality.
Use MASK_EXTR() to locate the code field, and use ACCESS_ONCE() rather than
barrier() to prevent hoisting of the repeated read.
Avoid unnecessary zeroing by only clobbering the 'code' field - this alone is
sufficient to spot the errata when the rings wrap.
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
CC: Jan Beulich <JBeulich@suse.com>
CC: Wei Liu <wl@xen.org>
CC: Roger Pau Monné <roger.pau@citrix.com>
---
xen/drivers/passthrough/amd/iommu_init.c | 80 ++++++++++++--------------------
1 file changed, 29 insertions(+), 51 deletions(-)
diff --git a/xen/drivers/passthrough/amd/iommu_init.c b/xen/drivers/passthrough/amd/iommu_init.c
index c42b608f07..5de5315d8b 100644
--- a/xen/drivers/passthrough/amd/iommu_init.c
+++ b/xen/drivers/passthrough/amd/iommu_init.c
@@ -300,7 +300,7 @@ static int iommu_read_log(struct amd_iommu *iommu,
unsigned int entry_size,
void (*parse_func)(struct amd_iommu *, u32 *))
{
- u32 tail, *entry, tail_offest, head_offset;
+ unsigned int tail, tail_offest, head_offset;
BUG_ON(!iommu || ((log != &iommu->event_log) && (log != &iommu->ppr_log)));
@@ -319,11 +319,36 @@ static int iommu_read_log(struct amd_iommu *iommu,
while ( tail != log->head )
{
- /* read event log entry */
- entry = log->buffer + log->head;
+ uint32_t *entry = log->buffer + log->head;
+ unsigned int count = 0;
+
+ /* Event and PPR logs have their code field in the same position. */
+ unsigned int code = MASK_EXTR(entry[1], IOMMU_EVENT_CODE_MASK);
+
+ /*
+ * Workaround for errata #732, #733:
+ *
+ * It can happen that the tail pointer is updated before the actual
+ * entry got written. As suggested by RevGuide, we initialize the
+ * buffer to all zeros and clear entries after processing them.
+ */
+ while ( unlikely(code == 0) )
+ {
+ if ( unlikely(++count == IOMMU_LOG_ENTRY_TIMEOUT) )
+ {
+ AMD_IOMMU_DEBUG("AMD-Vi: No entry written to %s Log\n",
+ log == &iommu->event_log ? "Event" : "PPR");
+ return 0;
+ }
+ udelay(1);
+ code = MASK_EXTR(ACCESS_ONCE(entry[1]), IOMMU_EVENT_CODE_MASK);
+ }
parse_func(iommu, entry);
+ /* Clear 'code' to be able to spot the erratum when the ring wraps. */
+ ACCESS_ONCE(entry[1]) = 0;
+
log->head += entry_size;
if ( log->head == log->size )
log->head = 0;
@@ -503,7 +528,6 @@ static hw_irq_controller iommu_x2apic_type = {
static void parse_event_log_entry(struct amd_iommu *iommu, u32 entry[])
{
u32 code;
- int count = 0;
static const char *const event_str[] = {
#define EVENT_STR(name) [IOMMU_EVENT_##name - 1] = #name
EVENT_STR(ILLEGAL_DEV_TABLE_ENTRY),
@@ -521,25 +545,6 @@ static void parse_event_log_entry(struct amd_iommu *iommu, u32 entry[])
code = get_field_from_reg_u32(entry[1], IOMMU_EVENT_CODE_MASK,
IOMMU_EVENT_CODE_SHIFT);
- /*
- * Workaround for erratum 732:
- * It can happen that the tail pointer is updated before the actual entry
- * got written. As suggested by RevGuide, we initialize the event log
- * buffer to all zeros and clear event log entries after processing them.
- */
- while ( code == 0 )
- {
- if ( unlikely(++count == IOMMU_LOG_ENTRY_TIMEOUT) )
- {
- AMD_IOMMU_DEBUG("AMD-Vi: No event written to log\n");
- return;
- }
- udelay(1);
- barrier(); /* Prevent hoisting of the entry[] read. */
- code = get_field_from_reg_u32(entry[1], IOMMU_EVENT_CODE_MASK,
- IOMMU_EVENT_CODE_SHIFT);
- }
-
/* Look up the symbolic name for code. */
if ( code <= ARRAY_SIZE(event_str) )
code_str = event_str[code - 1];
@@ -575,8 +580,6 @@ static void parse_event_log_entry(struct amd_iommu *iommu, u32 entry[])
else
printk(XENLOG_ERR "%s %08x %08x %08x %08x\n",
code_str, entry[0], entry[1], entry[2], entry[3]);
-
- memset(entry, 0, IOMMU_EVENT_LOG_ENTRY_SIZE);
}
static void iommu_check_event_log(struct amd_iommu *iommu)
@@ -627,31 +630,8 @@ void parse_ppr_log_entry(struct amd_iommu *iommu, u32 entry[])
{
u16 device_id;
- u8 bus, devfn, code;
+ u8 bus, devfn;
struct pci_dev *pdev;
- int count = 0;
-
- code = get_field_from_reg_u32(entry[1], IOMMU_PPR_LOG_CODE_MASK,
- IOMMU_PPR_LOG_CODE_SHIFT);
-
- /*
- * Workaround for erratum 733:
- * It can happen that the tail pointer is updated before the actual entry
- * got written. As suggested by RevGuide, we initialize the event log
- * buffer to all zeros and clear ppr log entries after processing them.
- */
- while ( code == 0 )
- {
- if ( unlikely(++count == IOMMU_LOG_ENTRY_TIMEOUT) )
- {
- AMD_IOMMU_DEBUG("AMD-Vi: No ppr written to log\n");
- return;
- }
- udelay(1);
- barrier(); /* Prevent hoisting of the entry[] read. */
- code = get_field_from_reg_u32(entry[1], IOMMU_PPR_LOG_CODE_MASK,
- IOMMU_PPR_LOG_CODE_SHIFT);
- }
/* here device_id is physical value */
device_id = iommu_get_devid_from_cmd(entry[0]);
@@ -664,8 +644,6 @@ void parse_ppr_log_entry(struct amd_iommu *iommu, u32 entry[])
if ( pdev )
guest_iommu_add_ppr_log(pdev->domain, entry);
-
- memset(entry, 0, IOMMU_PPR_LOG_ENTRY_SIZE);
}
static void iommu_check_ppr_log(struct amd_iommu *iommu)
--
2.11.0
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel
^ permalink raw reply related
* [PATCH AUTOSEL 4.19 209/252] powerpc/sriov: Remove VF eeh_dev state when disabling SR-IOV
From: Sasha Levin @ 2020-02-14 16:11 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Sam Bobroff, Oliver O'Halloran, linuxppc-dev, Sasha Levin
In-Reply-To: <20200214161147.15842-1-sashal@kernel.org>
From: Oliver O'Halloran <oohall@gmail.com>
[ Upstream commit 1fb4124ca9d456656a324f1ee29b7bf942f59ac8 ]
When disabling virtual functions on an SR-IOV adapter we currently do not
correctly remove the EEH state for the now-dead virtual functions. When
removing the pci_dn that was created for the VF when SR-IOV was enabled
we free the corresponding eeh_dev without removing it from the child device
list of the eeh_pe that contained it. This can result in crashes due to the
use-after-free.
Signed-off-by: Oliver O'Halloran <oohall@gmail.com>
Reviewed-by: Sam Bobroff <sbobroff@linux.ibm.com>
Tested-by: Sam Bobroff <sbobroff@linux.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20190821062655.19735-1-oohall@gmail.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/powerpc/kernel/pci_dn.c | 15 ++++++++++++++-
1 file changed, 14 insertions(+), 1 deletion(-)
diff --git a/arch/powerpc/kernel/pci_dn.c b/arch/powerpc/kernel/pci_dn.c
index ab147a1909c8b..7cecc3bd953b7 100644
--- a/arch/powerpc/kernel/pci_dn.c
+++ b/arch/powerpc/kernel/pci_dn.c
@@ -257,9 +257,22 @@ void remove_dev_pci_data(struct pci_dev *pdev)
continue;
#ifdef CONFIG_EEH
- /* Release EEH device for the VF */
+ /*
+ * Release EEH state for this VF. The PCI core
+ * has already torn down the pci_dev for this VF, but
+ * we're responsible to removing the eeh_dev since it
+ * has the same lifetime as the pci_dn that spawned it.
+ */
edev = pdn_to_eeh_dev(pdn);
if (edev) {
+ /*
+ * We allocate pci_dn's for the totalvfs count,
+ * but only only the vfs that were activated
+ * have a configured PE.
+ */
+ if (edev->pe)
+ eeh_rmv_from_parent_pe(edev);
+
pdn->edev = NULL;
kfree(edev);
}
--
2.20.1
^ permalink raw reply related
* Re: [PATCH v2] sched/fair: add burst to cgroup cpu bandwidth controller
From: bsegall @ 2020-02-14 18:55 UTC (permalink / raw)
To: Dave Chiluk
Cc: Konstantin Khlebnikov, Peter Zijlstra, cgroups,
Linux Kernel Mailing List, Juri Lelli, Vincent Guittot,
Steven Rostedt, Ben Segall, Ingo Molnar, Mel Gorman, Cong Wang,
Dietmar Eggemann
In-Reply-To: <CAC=E7cU8TeNHDRnrHiFxmiHUKviVU9KaDvMq-U16VRgcohg6-w@mail.gmail.com>
Dave Chiluk <chiluk+linux@indeed.com> writes:
> @Ben Segall, @Ingo Molnar, @Peter Zijlstra : This would be really
> useful, can you please voice your concerns/frustrations so they can be
> addressed? This should help increasing density of our bursty
> web-applications.
I seem to have missed this in my inbox.
>
> @Konstantin, please add a reviewed by by-line. As I don't do this
> regularly, I need all the attribution I can get.
> Reviewed-by: Dave Chiluk <chiluk+linux@indeed.com>
>
> Thanks,
> Dave
>
>
> On Tue, Nov 26, 2019 at 4:56 AM Konstantin Khlebnikov
> <khlebnikov@yandex-team.ru> wrote:
>>
>> Currently CFS bandwidth controller assigns cpu.cfs_quota_us runtime into
>> global pool every cpu.cfs_period_us. All unused runtime is expired.
>>
>> Since commit de53fd7aedb1 ("sched/fair: Fix low cpu usage with high
>> throttling by removing expiration of cpu-local slices") slice assigned
>> to cpu does not expire. This allows to serve tiny bursts (upto 1ms),
>> but this runtime pool is cpu-bound and not transferred between cpus.
>>
>> Setup for interactive workload with irregular cpu consumption have to set
>> quota according to relatively short spikes of cpu usage. This eliminates
>> possibility of control for average cpu usage. Increasing period and quota
>> proportionally for getting bigger runtime chunks is not an option because
>> if even bigger spike deplete global pool then execution will stuck until
>> end of period and next refill.
>>
>> This patch adds limited accumulation of unused runtime from past periods.
>> Accumulated runtime does not expire. It stays in global pool and could be
>> used by any cpu. Average cpu usage stays limited with quota / period,
>> but spiky workload could use more cpu power for a short period of time.
>>
>> Size of pool for burst runtime is set in attribute cpu.cfs_burst_us.
>> Default is 0, which reflects current behavior.
>>
>> Statistics for used bust runtime is shown in cpu.stat as "burst_time".
>>
>> Example setup:
>>
>> cpu.cfs_period_us = 100000
>> cpu.cfs_quota_us = 200000
>> cpu.cfs_burst_us = 300000
>>
>> Average cpu usage stays limited with 2 cpus (quota / period), but cgroup
>> could accumulate runtime (burst) and for 100ms could utilize up to 5 cpus
>> (quota / period + burst / 100ms), or 3 cpus for 300ms, an so on.
>>
>> For example, in this cgroup sample workload with bursts:
>>
>> fio --name=test --ioengine=cpuio --time_based=1 --runtime=600 \
>> --cpuload=10 --cpuchunks=100000 --numjobs=5
>>
>> has 50% average cpu usage without throttling. Without enabling bursts
>> same command can utilize only 25% cpu and 25% time will be throttled.
>>
>> Implementation is simple. All logic is in __refill_cfs_bandwidth_runtime().
>> Burst pool is kept in common pool thus runtime distribution is unchanged.
>> The rest changes are interface for cgroup and cgroup2.
>>
>> For cgroup2 burst is set as third number in attribute cpu.max:
>> cpu.max = $QUOTA $PERIOD $BURST
>>
>> At changing setup cgroup gets full charge of runtime and burst runtime.
>>
>> Signed-off-by: Konstantin Khlebnikov <khlebnikov@yandex-team.ru>
>> Cc: Dave Chiluk <chiluk+linux@indeed.com>
>> Cc: Cong Wang <xiyou.wangcong@gmail.com>
I'm not sure that starting with full burst runtime is best, though it
definitely seems likely to be one of those things where sometimes it's
what you want and sometimes it's not.
Reviewed-by: Ben Segall <bsegall@google.com>
>>
>> ---
>>
>> v2: fix spelling, add refilling burst runtime at changing setup per Dave Chiluk
>>
>> v1: https://lore.kernel.org/lkml/157312875706.707.12248531434112979828.stgit@buzz/
>>
>> Cong Wang proposed similar feature: https://lore.kernel.org/patchwork/patch/907450/
>> But with changing default behavior and without statistics.
>> ---
>> Documentation/admin-guide/cgroup-v2.rst | 15 +++--
>> Documentation/scheduler/sched-bwc.rst | 8 ++-
>> kernel/sched/core.c | 94 +++++++++++++++++++++++++------
>> kernel/sched/fair.c | 34 +++++++++--
>> kernel/sched/sched.h | 4 +
>> 5 files changed, 124 insertions(+), 31 deletions(-)
>>
>> diff --git a/Documentation/admin-guide/cgroup-v2.rst b/Documentation/admin-guide/cgroup-v2.rst
>> index 5361ebec3361..8c3cc3d882ba 100644
>> --- a/Documentation/admin-guide/cgroup-v2.rst
>> +++ b/Documentation/admin-guide/cgroup-v2.rst
>> @@ -981,11 +981,12 @@ All time durations are in microseconds.
>> - user_usec
>> - system_usec
>>
>> - and the following three when the controller is enabled:
>> + and the following four when the controller is enabled:
>>
>> - nr_periods
>> - nr_throttled
>> - throttled_usec
>> + - burst_usec
>>
>> cpu.weight
>> A read-write single value file which exists on non-root
>> @@ -1006,16 +1007,18 @@ All time durations are in microseconds.
>> the closest approximation of the current weight.
>>
>> cpu.max
>> - A read-write two value file which exists on non-root cgroups.
>> - The default is "max 100000".
>> + A read-write 1..3 values file which exists on non-root cgroups.
>> + The default is "max 100000 0".
>>
>> The maximum bandwidth limit. It's in the following format::
>>
>> - $MAX $PERIOD
>> + $MAX $PERIOD $BURST
>>
>> which indicates that the group may consume upto $MAX in each
>> - $PERIOD duration. "max" for $MAX indicates no limit. If only
>> - one number is written, $MAX is updated.
>> + $PERIOD duration and accumulates upto $BURST time for bursts.
>> +
>> + "max" for $MAX indicates no limit.
>> + If only one number is written, $MAX is updated.
Might want to change this to "Fields that aren't provided are left with
the old values" or something.
>>
>> cpu.pressure
>> A read-only nested-key file which exists on non-root cgroups.
>> diff --git a/Documentation/scheduler/sched-bwc.rst b/Documentation/scheduler/sched-bwc.rst
>> index 9801d6b284b1..59de2ebe11b3 100644
>> --- a/Documentation/scheduler/sched-bwc.rst
>> +++ b/Documentation/scheduler/sched-bwc.rst
>> @@ -27,12 +27,14 @@ Quota and period are managed within the cpu subsystem via cgroupfs.
>>
>> cpu.cfs_quota_us: the total available run-time within a period (in microseconds)
>> cpu.cfs_period_us: the length of a period (in microseconds)
>> +cpu.cfs_burst_us: the maxumum size of burst run-time pool (in microseconds)
>> cpu.stat: exports throttling statistics [explained further below]
>>
>> The default values are::
>>
>> cpu.cfs_period_us=100ms
>> - cpu.cfs_quota=-1
>> + cpu.cfs_quota_us=-1
>> + cpu.cfs_burst_us=0
>>
>> A value of -1 for cpu.cfs_quota_us indicates that the group does not have any
>> bandwidth restriction in place, such a group is described as an unconstrained
>> @@ -51,6 +53,9 @@ and return the group to an unconstrained state once more.
>> Any updates to a group's bandwidth specification will result in it becoming
>> unthrottled if it is in a constrained state.
>>
>> +Writing positive value into cpu.cfs_burst_us allows unused quota to
>> +accumulate up to this value and be used later in addition to assigned quota.
>> +
>> System wide settings
>> --------------------
>> For efficiency run-time is transferred between the global pool and CPU local
>> @@ -75,6 +80,7 @@ cpu.stat:
>> - nr_throttled: Number of times the group has been throttled/limited.
>> - throttled_time: The total time duration (in nanoseconds) for which entities
>> of the group have been throttled.
>> +- burst_time: The total running time consumed from burst pool.
>>
>> This interface is read-only.
>>
>> diff --git a/kernel/sched/core.c b/kernel/sched/core.c
>> index 44123b4d14e8..c4c8ef521e7c 100644
>> --- a/kernel/sched/core.c
>> +++ b/kernel/sched/core.c
>> @@ -7364,7 +7364,8 @@ static const u64 min_cfs_quota_period = 1 * NSEC_PER_MSEC; /* 1ms */
>>
>> static int __cfs_schedulable(struct task_group *tg, u64 period, u64 runtime);
>>
>> -static int tg_set_cfs_bandwidth(struct task_group *tg, u64 period, u64 quota)
>> +static int tg_set_cfs_bandwidth(struct task_group *tg, u64 period, u64 quota,
>> + u64 burst)
>> {
>> int i, ret = 0, runtime_enabled, runtime_was_enabled;
>> struct cfs_bandwidth *cfs_b = &tg->cfs_bandwidth;
>> @@ -7409,12 +7410,17 @@ static int tg_set_cfs_bandwidth(struct task_group *tg, u64 period, u64 quota)
>> raw_spin_lock_irq(&cfs_b->lock);
>> cfs_b->period = ns_to_ktime(period);
>> cfs_b->quota = quota;
>> + cfs_b->burst = burst;
>>
>> - __refill_cfs_bandwidth_runtime(cfs_b);
>> -
>> - /* Restart the period timer (if active) to handle new period expiry: */
>> - if (runtime_enabled)
>> + /*
>> + * Restart the period timer (if active) to handle new period expiry.
>> + * And refill runtime and burst-runtime to full charge.
>> + */
>> + if (runtime_enabled) {
>> + cfs_b->burst_runtime = burst;
>> + cfs_b->runtime = quota + burst;
>> start_cfs_bandwidth(cfs_b);
>> + }
>>
>> raw_spin_unlock_irq(&cfs_b->lock);
>>
>> @@ -7442,9 +7448,10 @@ static int tg_set_cfs_bandwidth(struct task_group *tg, u64 period, u64 quota)
>>
>> static int tg_set_cfs_quota(struct task_group *tg, long cfs_quota_us)
>> {
>> - u64 quota, period;
>> + u64 quota, period, burst;
>>
>> period = ktime_to_ns(tg->cfs_bandwidth.period);
>> + burst = tg->cfs_bandwidth.burst;
>> if (cfs_quota_us < 0)
>> quota = RUNTIME_INF;
>> else if ((u64)cfs_quota_us <= U64_MAX / NSEC_PER_USEC)
>> @@ -7452,7 +7459,7 @@ static int tg_set_cfs_quota(struct task_group *tg, long cfs_quota_us)
>> else
>> return -EINVAL;
>>
>> - return tg_set_cfs_bandwidth(tg, period, quota);
>> + return tg_set_cfs_bandwidth(tg, period, quota, burst);
>> }
>>
>> static long tg_get_cfs_quota(struct task_group *tg)
>> @@ -7470,15 +7477,16 @@ static long tg_get_cfs_quota(struct task_group *tg)
>>
>> static int tg_set_cfs_period(struct task_group *tg, long cfs_period_us)
>> {
>> - u64 quota, period;
>> + u64 quota, period, burst;
>>
>> if ((u64)cfs_period_us > U64_MAX / NSEC_PER_USEC)
>> return -EINVAL;
>>
>> period = (u64)cfs_period_us * NSEC_PER_USEC;
>> quota = tg->cfs_bandwidth.quota;
>> + burst = tg->cfs_bandwidth.burst;
>>
>> - return tg_set_cfs_bandwidth(tg, period, quota);
>> + return tg_set_cfs_bandwidth(tg, period, quota, burst);
>> }
>>
>> static long tg_get_cfs_period(struct task_group *tg)
>> @@ -7491,6 +7499,28 @@ static long tg_get_cfs_period(struct task_group *tg)
>> return cfs_period_us;
>> }
>>
>> +static long tg_get_cfs_burst(struct task_group *tg)
>> +{
>> + u64 cfs_burst_us = tg->cfs_bandwidth.burst;
>> +
>> + do_div(cfs_burst_us, NSEC_PER_USEC);
>> + return cfs_burst_us;
>> +}
>> +
>> +static int tg_set_cfs_burst(struct task_group *tg, long cfs_burst_us)
>> +{
>> + u64 quota, period, burst;
>> +
>> + if ((u64)cfs_burst_us > U64_MAX / NSEC_PER_USEC)
>> + return -EINVAL;
>> +
>> + period = ktime_to_ns(tg->cfs_bandwidth.period);
>> + quota = tg->cfs_bandwidth.quota;
>> + burst = (u64)cfs_burst_us * NSEC_PER_USEC;
>> +
>> + return tg_set_cfs_bandwidth(tg, period, quota, burst);
>> +}
>> +
>> static s64 cpu_cfs_quota_read_s64(struct cgroup_subsys_state *css,
>> struct cftype *cft)
>> {
>> @@ -7515,6 +7545,18 @@ static int cpu_cfs_period_write_u64(struct cgroup_subsys_state *css,
>> return tg_set_cfs_period(css_tg(css), cfs_period_us);
>> }
>>
>> +static u64 cpu_cfs_burst_read_u64(struct cgroup_subsys_state *css,
>> + struct cftype *cft)
>> +{
>> + return tg_get_cfs_burst(css_tg(css));
>> +}
>> +
>> +static int cpu_cfs_burst_write_u64(struct cgroup_subsys_state *css,
>> + struct cftype *cftype, u64 cfs_burst_us)
>> +{
>> + return tg_set_cfs_burst(css_tg(css), cfs_burst_us);
>> +}
>> +
>> struct cfs_schedulable_data {
>> struct task_group *tg;
>> u64 period, quota;
>> @@ -7606,6 +7648,7 @@ static int cpu_cfs_stat_show(struct seq_file *sf, void *v)
>> seq_printf(sf, "nr_periods %d\n", cfs_b->nr_periods);
>> seq_printf(sf, "nr_throttled %d\n", cfs_b->nr_throttled);
>> seq_printf(sf, "throttled_time %llu\n", cfs_b->throttled_time);
>> + seq_printf(sf, "burst_time %llu\n", cfs_b->burst_time);
>>
>> if (schedstat_enabled() && tg != &root_task_group) {
>> u64 ws = 0;
>> @@ -7667,6 +7710,11 @@ static struct cftype cpu_legacy_files[] = {
>> .read_u64 = cpu_cfs_period_read_u64,
>> .write_u64 = cpu_cfs_period_write_u64,
>> },
>> + {
>> + .name = "cfs_burst_us",
>> + .read_u64 = cpu_cfs_burst_read_u64,
>> + .write_u64 = cpu_cfs_burst_write_u64,
>> + },
>> {
>> .name = "stat",
>> .seq_show = cpu_cfs_stat_show,
>> @@ -7709,15 +7757,20 @@ static int cpu_extra_stat_show(struct seq_file *sf,
>> struct task_group *tg = css_tg(css);
>> struct cfs_bandwidth *cfs_b = &tg->cfs_bandwidth;
>> u64 throttled_usec;
>> + u64 burst_usec;
>>
>> throttled_usec = cfs_b->throttled_time;
>> do_div(throttled_usec, NSEC_PER_USEC);
>>
>> + burst_usec = cfs_b->burst_time;
>> + do_div(burst_usec, NSEC_PER_USEC);
>> +
>> seq_printf(sf, "nr_periods %d\n"
>> "nr_throttled %d\n"
>> - "throttled_usec %llu\n",
>> + "throttled_usec %llu\n"
>> + "burst_usec %llu\n",
>> cfs_b->nr_periods, cfs_b->nr_throttled,
>> - throttled_usec);
>> + throttled_usec, burst_usec);
>> }
>> #endif
>> return 0;
>> @@ -7787,26 +7840,29 @@ static int cpu_weight_nice_write_s64(struct cgroup_subsys_state *css,
>> #endif
>>
>> static void __maybe_unused cpu_period_quota_print(struct seq_file *sf,
>> - long period, long quota)
>> + long period, long quota,
>> + long burst)
>> {
>> if (quota < 0)
>> seq_puts(sf, "max");
>> else
>> seq_printf(sf, "%ld", quota);
>>
>> - seq_printf(sf, " %ld\n", period);
>> + seq_printf(sf, " %ld %ld\n", period, burst);
>> }
>>
>> /* caller should put the current value in *@periodp before calling */
>> static int __maybe_unused cpu_period_quota_parse(char *buf,
>> - u64 *periodp, u64 *quotap)
>> + u64 *periodp, u64 *quotap,
>> + s64 *burstp)
>> {
>> char tok[21]; /* U64_MAX */
>>
>> - if (sscanf(buf, "%20s %llu", tok, periodp) < 1)
>> + if (sscanf(buf, "%20s %llu %llu", tok, periodp, burstp) < 1)
>> return -EINVAL;
>>
>> *periodp *= NSEC_PER_USEC;
>> + *burstp *= NSEC_PER_USEC;
>>
>> if (sscanf(tok, "%llu", quotap))
>> *quotap *= NSEC_PER_USEC;
>> @@ -7823,7 +7879,8 @@ static int cpu_max_show(struct seq_file *sf, void *v)
>> {
>> struct task_group *tg = css_tg(seq_css(sf));
>>
>> - cpu_period_quota_print(sf, tg_get_cfs_period(tg), tg_get_cfs_quota(tg));
>> + cpu_period_quota_print(sf, tg_get_cfs_period(tg), tg_get_cfs_quota(tg),
>> + tg_get_cfs_burst(tg));
>> return 0;
>> }
>>
>> @@ -7832,12 +7889,13 @@ static ssize_t cpu_max_write(struct kernfs_open_file *of,
>> {
>> struct task_group *tg = css_tg(of_css(of));
>> u64 period = tg_get_cfs_period(tg);
>> + s64 burst = tg_get_cfs_burst(tg);
>> u64 quota;
>> int ret;
>>
>> - ret = cpu_period_quota_parse(buf, &period, "a);
>> + ret = cpu_period_quota_parse(buf, &period, "a, &burst);
>> if (!ret)
>> - ret = tg_set_cfs_bandwidth(tg, period, quota);
>> + ret = tg_set_cfs_bandwidth(tg, period, quota, burst);
>> return ret ?: nbytes;
>> }
>> #endif
>> diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
>> index 69a81a5709ff..f32b72496932 100644
>> --- a/kernel/sched/fair.c
>> +++ b/kernel/sched/fair.c
>> @@ -4353,16 +4353,26 @@ static inline u64 sched_cfs_bandwidth_slice(void)
>> }
>>
>> /*
>> - * Replenish runtime according to assigned quota. We use sched_clock_cpu
>> - * directly instead of rq->clock to avoid adding additional synchronization
>> - * around rq->lock.
>> + * Replenish runtime according to assigned quota.
>> + * Called only if quota != RUNTIME_INF.
>> *
>> * requires cfs_b->lock
>> */
>> void __refill_cfs_bandwidth_runtime(struct cfs_bandwidth *cfs_b)
>> {
>> - if (cfs_b->quota != RUNTIME_INF)
>> - cfs_b->runtime = cfs_b->quota;
>> + u64 runtime = cfs_b->runtime;
>> +
>> + /*
>> + * Preserve past runtime up to burst size. If remaining runtime lower
>> + * than previous burst runtime then account delta as used burst time.
>> + */
>> + if (runtime > cfs_b->burst)
>> + runtime = cfs_b->burst;
>> + else if (runtime < cfs_b->burst_runtime)
>> + cfs_b->burst_time += cfs_b->burst_runtime - runtime;
>> +
>> + cfs_b->burst_runtime = runtime;
>> + cfs_b->runtime = runtime + cfs_b->quota;
>> }
>>
>> static inline struct cfs_bandwidth *tg_cfs_bandwidth(struct task_group *tg)
>> @@ -4968,6 +4978,9 @@ void init_cfs_bandwidth(struct cfs_bandwidth *cfs_b)
>> cfs_b->runtime = 0;
>> cfs_b->quota = RUNTIME_INF;
>> cfs_b->period = ns_to_ktime(default_cfs_period());
>> + cfs_b->burst = 0;
>> + cfs_b->burst_runtime = 0;
>> + cfs_b->burst_time = 0;
>>
>> INIT_LIST_HEAD(&cfs_b->throttled_cfs_rq);
>> hrtimer_init(&cfs_b->period_timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS_PINNED);
>> @@ -4986,14 +4999,23 @@ static void init_cfs_rq_runtime(struct cfs_rq *cfs_rq)
>>
>> void start_cfs_bandwidth(struct cfs_bandwidth *cfs_b)
>> {
>> + u64 overrun;
>> +
>> lockdep_assert_held(&cfs_b->lock);
>>
>> if (cfs_b->period_active)
>> return;
>>
>> cfs_b->period_active = 1;
>> - hrtimer_forward_now(&cfs_b->period_timer, cfs_b->period);
>> + overrun = hrtimer_forward_now(&cfs_b->period_timer, cfs_b->period);
>> hrtimer_start_expires(&cfs_b->period_timer, HRTIMER_MODE_ABS_PINNED);
>> +
>> + /*
>> + * Refill runtime for periods of inactivity and current.
>> + * __refill_cfs_bandwidth_runtime() will cut excess.
>> + */
>> + cfs_b->runtime += cfs_b->quota * overrun;
Overflow in 584 years, even cpu-years, is probably fine. And we skip
refill on the period we stop the timer, so this isn't off by one, though
it might be worth mentioning that in the comment.
>> + __refill_cfs_bandwidth_runtime(cfs_b);
>> }
>>
>> static void destroy_cfs_bandwidth(struct cfs_bandwidth *cfs_b)
>> diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h
>> index c8870c5bd7df..6edf6155e4f6 100644
>> --- a/kernel/sched/sched.h
>> +++ b/kernel/sched/sched.h
>> @@ -344,10 +344,14 @@ struct cfs_bandwidth {
>> struct hrtimer slack_timer;
>> struct list_head throttled_cfs_rq;
>>
>> + u64 burst;
>> + u64 burst_runtime;
>> +
>> /* Statistics: */
>> int nr_periods;
>> int nr_throttled;
>> u64 throttled_time;
>> + u64 burst_time;
>> #endif
>> };
>>
>>
^ permalink raw reply
* Re: [RFC v2 1/6] tpm: rename TPM_TIS into TPM_TIS_ISA
From: Philippe Mathieu-Daudé @ 2020-02-14 18:55 UTC (permalink / raw)
To: Eric Auger, eric.auger.pro, stefanb, qemu-devel, qemu-arm,
peter.maydell
Cc: marcandre.lureau, lersek, ardb
In-Reply-To: <20200214183704.14389-2-eric.auger@redhat.com>
On 2/14/20 7:36 PM, Eric Auger wrote:
> As we plan to introduce a sysbus TPM_TIS, let's rename
> TPM_TIS into TPM_TIS_ISA.
>
> Signed-off-by: Eric Auger <eric.auger@redhat.com>
> ---
> hw/i386/acpi-build.c | 6 +++---
> hw/tpm/tpm_tis.c | 4 ++--
> include/sysemu/tpm.h | 6 +++---
> 3 files changed, 8 insertions(+), 8 deletions(-)
>
> diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> index 9c4e46fa74..26777f8828 100644
> --- a/hw/i386/acpi-build.c
> +++ b/hw/i386/acpi-build.c
> @@ -2026,7 +2026,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
> }
> }
>
> - if (TPM_IS_TIS(tpm_find())) {
> + if (TPM_IS_TIS_ISA(tpm_find())) {
> aml_append(crs, aml_memory32_fixed(TPM_TIS_ADDR_BASE,
> TPM_TIS_ADDR_SIZE, AML_READ_WRITE));
> }
> @@ -2197,7 +2197,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
> /* Scan all PCI buses. Generate tables to support hotplug. */
> build_append_pci_bus_devices(scope, bus, pm->pcihp_bridge_en);
>
> - if (TPM_IS_TIS(tpm)) {
> + if (TPM_IS_TIS_ISA(tpm)) {
> if (misc->tpm_version == TPM_VERSION_2_0) {
> dev = aml_device("TPM");
> aml_append(dev, aml_name_decl("_HID",
> @@ -2304,7 +2304,7 @@ build_tpm2(GArray *table_data, BIOSLinker *linker, GArray *tcpalog)
> (char *)&tpm2_ptr->log_area_start_address - table_data->data;
>
> tpm2_ptr->platform_class = cpu_to_le16(TPM2_ACPI_CLASS_CLIENT);
> - if (TPM_IS_TIS(tpm_find())) {
> + if (TPM_IS_TIS_ISA(tpm_find())) {
> tpm2_ptr->control_area_address = cpu_to_le64(0);
> tpm2_ptr->start_method = cpu_to_le32(TPM2_START_METHOD_MMIO);
> } else if (TPM_IS_CRB(tpm_find())) {
> diff --git a/hw/tpm/tpm_tis.c b/hw/tpm/tpm_tis.c
> index 31facb896d..c609737272 100644
> --- a/hw/tpm/tpm_tis.c
> +++ b/hw/tpm/tpm_tis.c
> @@ -91,7 +91,7 @@ typedef struct TPMState {
> TPMPPI ppi;
> } TPMState;
>
> -#define TPM(obj) OBJECT_CHECK(TPMState, (obj), TYPE_TPM_TIS)
> +#define TPM(obj) OBJECT_CHECK(TPMState, (obj), TYPE_TPM_TIS_ISA)
>
> #define DEBUG_TIS 0
>
> @@ -1008,7 +1008,7 @@ static void tpm_tis_class_init(ObjectClass *klass, void *data)
> }
>
> static const TypeInfo tpm_tis_info = {
> - .name = TYPE_TPM_TIS,
> + .name = TYPE_TPM_TIS_ISA,
> .parent = TYPE_ISA_DEVICE,
> .instance_size = sizeof(TPMState),
> .instance_init = tpm_tis_initfn,
> diff --git a/include/sysemu/tpm.h b/include/sysemu/tpm.h
> index 15979a3647..1691b92c28 100644
> --- a/include/sysemu/tpm.h
> +++ b/include/sysemu/tpm.h
> @@ -43,12 +43,12 @@ typedef struct TPMIfClass {
> enum TPMVersion (*get_version)(TPMIf *obj);
> } TPMIfClass;
>
> -#define TYPE_TPM_TIS "tpm-tis"
> +#define TYPE_TPM_TIS_ISA "tpm-tis"
It should be safe to rename this "tpm-tis-isa" in this patch.
Regardless:
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
> #define TYPE_TPM_CRB "tpm-crb"
> #define TYPE_TPM_SPAPR "tpm-spapr"
>
> -#define TPM_IS_TIS(chr) \
> - object_dynamic_cast(OBJECT(chr), TYPE_TPM_TIS)
> +#define TPM_IS_TIS_ISA(chr) \
> + object_dynamic_cast(OBJECT(chr), TYPE_TPM_TIS_ISA)
> #define TPM_IS_CRB(chr) \
> object_dynamic_cast(OBJECT(chr), TYPE_TPM_CRB)
> #define TPM_IS_SPAPR(chr) \
>
^ permalink raw reply
* Re: [PATCH AUTOSEL 5.5 487/542] ceph: remove the extra slashes in the server path
From: Sasha Levin @ 2020-02-14 18:55 UTC (permalink / raw)
To: Ilya Dryomov; +Cc: LKML, stable, Xiubo Li, Jeff Layton, Ceph Development
In-Reply-To: <CAOi1vP9h-Wx16AuUp4AZaF1THnFan0VFFQhx_r05+2CcyDyKAQ@mail.gmail.com>
On Fri, Feb 14, 2020 at 05:13:21PM +0100, Ilya Dryomov wrote:
>On Fri, Feb 14, 2020 at 4:59 PM Sasha Levin <sashal@kernel.org> wrote:
>>
>> From: Xiubo Li <xiubli@redhat.com>
>>
>> [ Upstream commit 4fbc0c711b2464ee1551850b85002faae0b775d5 ]
>>
>> It's possible to pass the mount helper a server path that has more
>> than one contiguous slash character. For example:
>>
>> $ mount -t ceph 192.168.195.165:40176:/// /mnt/cephfs/
>>
>> In the MDS server side the extra slashes of the server path will be
>> treated as snap dir, and then we can get the following debug logs:
>>
>> ceph: mount opening path //
>> ceph: open_root_inode opening '//'
>> ceph: fill_trace 0000000059b8a3bc is_dentry 0 is_target 1
>> ceph: alloc_inode 00000000dc4ca00b
>> ceph: get_inode created new inode 00000000dc4ca00b 1.ffffffffffffffff ino 1
>> ceph: get_inode on 1=1.ffffffffffffffff got 00000000dc4ca00b
>>
>> And then when creating any new file or directory under the mount
>> point, we can hit the following BUG_ON in ceph_fill_trace():
>>
>> BUG_ON(ceph_snap(dir) != dvino.snap);
>>
>> Have the client ignore the extra slashes in the server path when
>> mounting. This will also canonicalize the path, so that identical mounts
>> can be consilidated.
>>
>> 1) "//mydir1///mydir//"
>> 2) "/mydir1/mydir"
>> 3) "/mydir1/mydir/"
>>
>> Regardless of the internal treatment of these paths, the kernel still
>> stores the original string including the leading '/' for presentation
>> to userland.
>>
>> URL: https://tracker.ceph.com/issues/42771
>> Signed-off-by: Xiubo Li <xiubli@redhat.com>
>> Reviewed-by: Jeff Layton <jlayton@kernel.org>
>> Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
>> Signed-off-by: Sasha Levin <sashal@kernel.org>
>> ---
>> fs/ceph/super.c | 122 ++++++++++++++++++++++++++++++++++++++++--------
>> 1 file changed, 102 insertions(+), 20 deletions(-)
>>
>> diff --git a/fs/ceph/super.c b/fs/ceph/super.c
>> index 430dcf329723a..112927dbd2f20 100644
>> --- a/fs/ceph/super.c
>> +++ b/fs/ceph/super.c
>> @@ -107,7 +107,6 @@ static int ceph_statfs(struct dentry *dentry, struct kstatfs *buf)
>> return 0;
>> }
>>
>> -
>> static int ceph_sync_fs(struct super_block *sb, int wait)
>> {
>> struct ceph_fs_client *fsc = ceph_sb_to_client(sb);
>> @@ -211,7 +210,6 @@ struct ceph_parse_opts_ctx {
>>
>> /*
>> * Parse the source parameter. Distinguish the server list from the path.
>> - * Internally we do not include the leading '/' in the path.
>> *
>> * The source will look like:
>> * <server_spec>[,<server_spec>...]:[<path>]
>> @@ -232,12 +230,15 @@ static int ceph_parse_source(struct fs_parameter *param, struct fs_context *fc)
>>
>> dev_name_end = strchr(dev_name, '/');
>> if (dev_name_end) {
>> - if (strlen(dev_name_end) > 1) {
>> - kfree(fsopt->server_path);
>> - fsopt->server_path = kstrdup(dev_name_end, GFP_KERNEL);
>> - if (!fsopt->server_path)
>> - return -ENOMEM;
>> - }
>> + kfree(fsopt->server_path);
>> +
>> + /*
>> + * The server_path will include the whole chars from userland
>> + * including the leading '/'.
>> + */
>> + fsopt->server_path = kstrdup(dev_name_end, GFP_KERNEL);
>> + if (!fsopt->server_path)
>> + return -ENOMEM;
>> } else {
>> dev_name_end = dev_name + strlen(dev_name);
>> }
>> @@ -461,6 +462,73 @@ static int strcmp_null(const char *s1, const char *s2)
>> return strcmp(s1, s2);
>> }
>>
>> +/**
>> + * path_remove_extra_slash - Remove the extra slashes in the server path
>> + * @server_path: the server path and could be NULL
>> + *
>> + * Return NULL if the path is NULL or only consists of "/", or a string
>> + * without any extra slashes including the leading slash(es) and the
>> + * slash(es) at the end of the server path, such as:
>> + * "//dir1////dir2///" --> "dir1/dir2"
>> + */
>> +static char *path_remove_extra_slash(const char *server_path)
>> +{
>> + const char *path = server_path;
>> + const char *cur, *end;
>> + char *buf, *p;
>> + int len;
>> +
>> + /* if the server path is omitted */
>> + if (!path)
>> + return NULL;
>> +
>> + /* remove all the leading slashes */
>> + while (*path == '/')
>> + path++;
>> +
>> + /* if the server path only consists of slashes */
>> + if (*path == '\0')
>> + return NULL;
>> +
>> + len = strlen(path);
>> +
>> + buf = kmalloc(len + 1, GFP_KERNEL);
>> + if (!buf)
>> + return ERR_PTR(-ENOMEM);
>> +
>> + end = path + len;
>> + p = buf;
>> + do {
>> + cur = strchr(path, '/');
>> + if (!cur)
>> + cur = end;
>> +
>> + len = cur - path;
>> +
>> + /* including one '/' */
>> + if (cur != end)
>> + len += 1;
>> +
>> + memcpy(p, path, len);
>> + p += len;
>> +
>> + while (cur <= end && *cur == '/')
>> + cur++;
>> + path = cur;
>> + } while (path < end);
>> +
>> + *p = '\0';
>> +
>> + /*
>> + * remove the last slash if there has and just to make sure that
>> + * we will get something like "dir1/dir2"
>> + */
>> + if (*(--p) == '/')
>> + *p = '\0';
>> +
>> + return buf;
>> +}
>> +
>> static int compare_mount_options(struct ceph_mount_options *new_fsopt,
>> struct ceph_options *new_opt,
>> struct ceph_fs_client *fsc)
>> @@ -468,6 +536,7 @@ static int compare_mount_options(struct ceph_mount_options *new_fsopt,
>> struct ceph_mount_options *fsopt1 = new_fsopt;
>> struct ceph_mount_options *fsopt2 = fsc->mount_options;
>> int ofs = offsetof(struct ceph_mount_options, snapdir_name);
>> + char *p1, *p2;
>> int ret;
>>
>> ret = memcmp(fsopt1, fsopt2, ofs);
>> @@ -480,9 +549,21 @@ static int compare_mount_options(struct ceph_mount_options *new_fsopt,
>> ret = strcmp_null(fsopt1->mds_namespace, fsopt2->mds_namespace);
>> if (ret)
>> return ret;
>> - ret = strcmp_null(fsopt1->server_path, fsopt2->server_path);
>> +
>> + p1 = path_remove_extra_slash(fsopt1->server_path);
>> + if (IS_ERR(p1))
>> + return PTR_ERR(p1);
>> + p2 = path_remove_extra_slash(fsopt2->server_path);
>> + if (IS_ERR(p2)) {
>> + kfree(p1);
>> + return PTR_ERR(p2);
>> + }
>> + ret = strcmp_null(p1, p2);
>> + kfree(p1);
>> + kfree(p2);
>> if (ret)
>> return ret;
>> +
>> ret = strcmp_null(fsopt1->fscache_uniq, fsopt2->fscache_uniq);
>> if (ret)
>> return ret;
>> @@ -788,7 +869,6 @@ static void destroy_caches(void)
>> ceph_fscache_unregister();
>> }
>>
>> -
>> /*
>> * ceph_umount_begin - initiate forced umount. Tear down down the
>> * mount, skipping steps that may hang while waiting for server(s).
>> @@ -868,9 +948,6 @@ static struct dentry *open_root_dentry(struct ceph_fs_client *fsc,
>> return root;
>> }
>>
>> -
>> -
>> -
>> /*
>> * mount: join the ceph cluster, and open root directory.
>> */
>> @@ -885,7 +962,7 @@ static struct dentry *ceph_real_mount(struct ceph_fs_client *fsc,
>> mutex_lock(&fsc->client->mount_mutex);
>>
>> if (!fsc->sb->s_root) {
>> - const char *path;
>> + const char *path, *p;
>> err = __ceph_open_session(fsc->client, started);
>> if (err < 0)
>> goto out;
>> @@ -897,17 +974,22 @@ static struct dentry *ceph_real_mount(struct ceph_fs_client *fsc,
>> goto out;
>> }
>>
>> - if (!fsc->mount_options->server_path) {
>> - path = "";
>> - dout("mount opening path \\t\n");
>> - } else {
>> - path = fsc->mount_options->server_path + 1;
>> - dout("mount opening path %s\n", path);
>> + p = path_remove_extra_slash(fsc->mount_options->server_path);
>> + if (IS_ERR(p)) {
>> + err = PTR_ERR(p);
>> + goto out;
>> }
>> + /* if the server path is omitted or just consists of '/' */
>> + if (!p)
>> + path = "";
>> + else
>> + path = p;
>> + dout("mount opening path '%s'\n", path);
>>
>> ceph_fs_debugfs_init(fsc);
>>
>> root = open_root_dentry(fsc, path, started);
>> + kfree(p);
>> if (IS_ERR(root)) {
>> err = PTR_ERR(root);
>> goto out;
>
>Hi Sasha,
>
>This commit is buggy, the fix should land in 5.6-rc2. Please drop it
>for now -- it would need to be taken together with "ceph: canonicalize
>server path in place" or not backported at all.
I'll try and queue up the fix when it's upstream. This series will
probably be queued closer to -rc3 anyways.
--
Thanks,
Sasha
^ permalink raw reply
* Re: [PATCH v2] sched/fair: add burst to cgroup cpu bandwidth controller
From: bsegall-hpIqsD4AKlfQT0dZR+AlfA @ 2020-02-14 18:55 UTC (permalink / raw)
To: Dave Chiluk
Cc: Konstantin Khlebnikov, Peter Zijlstra,
cgroups-u79uwXL29TY76Z2rM5mHXA, Linux Kernel Mailing List,
Juri Lelli, Vincent Guittot, Steven Rostedt, Ben Segall,
Ingo Molnar, Mel Gorman, Cong Wang, Dietmar Eggemann
In-Reply-To: <CAC=E7cU8TeNHDRnrHiFxmiHUKviVU9KaDvMq-U16VRgcohg6-w-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
Dave Chiluk <chiluk+linux-Ad+Cokg7I4LQT0dZR+AlfA@public.gmane.org> writes:
> @Ben Segall, @Ingo Molnar, @Peter Zijlstra : This would be really
> useful, can you please voice your concerns/frustrations so they can be
> addressed? This should help increasing density of our bursty
> web-applications.
I seem to have missed this in my inbox.
>
> @Konstantin, please add a reviewed by by-line. As I don't do this
> regularly, I need all the attribution I can get.
> Reviewed-by: Dave Chiluk <chiluk+linux-Ad+Cokg7I4LQT0dZR+AlfA@public.gmane.org>
>
> Thanks,
> Dave
>
>
> On Tue, Nov 26, 2019 at 4:56 AM Konstantin Khlebnikov
> <khlebnikov-XoJtRXgx1JseBXzfvpsJ4g@public.gmane.org> wrote:
>>
>> Currently CFS bandwidth controller assigns cpu.cfs_quota_us runtime into
>> global pool every cpu.cfs_period_us. All unused runtime is expired.
>>
>> Since commit de53fd7aedb1 ("sched/fair: Fix low cpu usage with high
>> throttling by removing expiration of cpu-local slices") slice assigned
>> to cpu does not expire. This allows to serve tiny bursts (upto 1ms),
>> but this runtime pool is cpu-bound and not transferred between cpus.
>>
>> Setup for interactive workload with irregular cpu consumption have to set
>> quota according to relatively short spikes of cpu usage. This eliminates
>> possibility of control for average cpu usage. Increasing period and quota
>> proportionally for getting bigger runtime chunks is not an option because
>> if even bigger spike deplete global pool then execution will stuck until
>> end of period and next refill.
>>
>> This patch adds limited accumulation of unused runtime from past periods.
>> Accumulated runtime does not expire. It stays in global pool and could be
>> used by any cpu. Average cpu usage stays limited with quota / period,
>> but spiky workload could use more cpu power for a short period of time.
>>
>> Size of pool for burst runtime is set in attribute cpu.cfs_burst_us.
>> Default is 0, which reflects current behavior.
>>
>> Statistics for used bust runtime is shown in cpu.stat as "burst_time".
>>
>> Example setup:
>>
>> cpu.cfs_period_us = 100000
>> cpu.cfs_quota_us = 200000
>> cpu.cfs_burst_us = 300000
>>
>> Average cpu usage stays limited with 2 cpus (quota / period), but cgroup
>> could accumulate runtime (burst) and for 100ms could utilize up to 5 cpus
>> (quota / period + burst / 100ms), or 3 cpus for 300ms, an so on.
>>
>> For example, in this cgroup sample workload with bursts:
>>
>> fio --name=test --ioengine=cpuio --time_based=1 --runtime=600 \
>> --cpuload=10 --cpuchunks=100000 --numjobs=5
>>
>> has 50% average cpu usage without throttling. Without enabling bursts
>> same command can utilize only 25% cpu and 25% time will be throttled.
>>
>> Implementation is simple. All logic is in __refill_cfs_bandwidth_runtime().
>> Burst pool is kept in common pool thus runtime distribution is unchanged.
>> The rest changes are interface for cgroup and cgroup2.
>>
>> For cgroup2 burst is set as third number in attribute cpu.max:
>> cpu.max = $QUOTA $PERIOD $BURST
>>
>> At changing setup cgroup gets full charge of runtime and burst runtime.
>>
>> Signed-off-by: Konstantin Khlebnikov <khlebnikov-XoJtRXgx1JseBXzfvpsJ4g@public.gmane.org>
>> Cc: Dave Chiluk <chiluk+linux-Ad+Cokg7I4LQT0dZR+AlfA@public.gmane.org>
>> Cc: Cong Wang <xiyou.wangcong-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
I'm not sure that starting with full burst runtime is best, though it
definitely seems likely to be one of those things where sometimes it's
what you want and sometimes it's not.
Reviewed-by: Ben Segall <bsegall-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org>
>>
>> ---
>>
>> v2: fix spelling, add refilling burst runtime at changing setup per Dave Chiluk
>>
>> v1: https://lore.kernel.org/lkml/157312875706.707.12248531434112979828.stgit@buzz/
>>
>> Cong Wang proposed similar feature: https://lore.kernel.org/patchwork/patch/907450/
>> But with changing default behavior and without statistics.
>> ---
>> Documentation/admin-guide/cgroup-v2.rst | 15 +++--
>> Documentation/scheduler/sched-bwc.rst | 8 ++-
>> kernel/sched/core.c | 94 +++++++++++++++++++++++++------
>> kernel/sched/fair.c | 34 +++++++++--
>> kernel/sched/sched.h | 4 +
>> 5 files changed, 124 insertions(+), 31 deletions(-)
>>
>> diff --git a/Documentation/admin-guide/cgroup-v2.rst b/Documentation/admin-guide/cgroup-v2.rst
>> index 5361ebec3361..8c3cc3d882ba 100644
>> --- a/Documentation/admin-guide/cgroup-v2.rst
>> +++ b/Documentation/admin-guide/cgroup-v2.rst
>> @@ -981,11 +981,12 @@ All time durations are in microseconds.
>> - user_usec
>> - system_usec
>>
>> - and the following three when the controller is enabled:
>> + and the following four when the controller is enabled:
>>
>> - nr_periods
>> - nr_throttled
>> - throttled_usec
>> + - burst_usec
>>
>> cpu.weight
>> A read-write single value file which exists on non-root
>> @@ -1006,16 +1007,18 @@ All time durations are in microseconds.
>> the closest approximation of the current weight.
>>
>> cpu.max
>> - A read-write two value file which exists on non-root cgroups.
>> - The default is "max 100000".
>> + A read-write 1..3 values file which exists on non-root cgroups.
>> + The default is "max 100000 0".
>>
>> The maximum bandwidth limit. It's in the following format::
>>
>> - $MAX $PERIOD
>> + $MAX $PERIOD $BURST
>>
>> which indicates that the group may consume upto $MAX in each
>> - $PERIOD duration. "max" for $MAX indicates no limit. If only
>> - one number is written, $MAX is updated.
>> + $PERIOD duration and accumulates upto $BURST time for bursts.
>> +
>> + "max" for $MAX indicates no limit.
>> + If only one number is written, $MAX is updated.
Might want to change this to "Fields that aren't provided are left with
the old values" or something.
>>
>> cpu.pressure
>> A read-only nested-key file which exists on non-root cgroups.
>> diff --git a/Documentation/scheduler/sched-bwc.rst b/Documentation/scheduler/sched-bwc.rst
>> index 9801d6b284b1..59de2ebe11b3 100644
>> --- a/Documentation/scheduler/sched-bwc.rst
>> +++ b/Documentation/scheduler/sched-bwc.rst
>> @@ -27,12 +27,14 @@ Quota and period are managed within the cpu subsystem via cgroupfs.
>>
>> cpu.cfs_quota_us: the total available run-time within a period (in microseconds)
>> cpu.cfs_period_us: the length of a period (in microseconds)
>> +cpu.cfs_burst_us: the maxumum size of burst run-time pool (in microseconds)
>> cpu.stat: exports throttling statistics [explained further below]
>>
>> The default values are::
>>
>> cpu.cfs_period_us=100ms
>> - cpu.cfs_quota=-1
>> + cpu.cfs_quota_us=-1
>> + cpu.cfs_burst_us=0
>>
>> A value of -1 for cpu.cfs_quota_us indicates that the group does not have any
>> bandwidth restriction in place, such a group is described as an unconstrained
>> @@ -51,6 +53,9 @@ and return the group to an unconstrained state once more.
>> Any updates to a group's bandwidth specification will result in it becoming
>> unthrottled if it is in a constrained state.
>>
>> +Writing positive value into cpu.cfs_burst_us allows unused quota to
>> +accumulate up to this value and be used later in addition to assigned quota.
>> +
>> System wide settings
>> --------------------
>> For efficiency run-time is transferred between the global pool and CPU local
>> @@ -75,6 +80,7 @@ cpu.stat:
>> - nr_throttled: Number of times the group has been throttled/limited.
>> - throttled_time: The total time duration (in nanoseconds) for which entities
>> of the group have been throttled.
>> +- burst_time: The total running time consumed from burst pool.
>>
>> This interface is read-only.
>>
>> diff --git a/kernel/sched/core.c b/kernel/sched/core.c
>> index 44123b4d14e8..c4c8ef521e7c 100644
>> --- a/kernel/sched/core.c
>> +++ b/kernel/sched/core.c
>> @@ -7364,7 +7364,8 @@ static const u64 min_cfs_quota_period = 1 * NSEC_PER_MSEC; /* 1ms */
>>
>> static int __cfs_schedulable(struct task_group *tg, u64 period, u64 runtime);
>>
>> -static int tg_set_cfs_bandwidth(struct task_group *tg, u64 period, u64 quota)
>> +static int tg_set_cfs_bandwidth(struct task_group *tg, u64 period, u64 quota,
>> + u64 burst)
>> {
>> int i, ret = 0, runtime_enabled, runtime_was_enabled;
>> struct cfs_bandwidth *cfs_b = &tg->cfs_bandwidth;
>> @@ -7409,12 +7410,17 @@ static int tg_set_cfs_bandwidth(struct task_group *tg, u64 period, u64 quota)
>> raw_spin_lock_irq(&cfs_b->lock);
>> cfs_b->period = ns_to_ktime(period);
>> cfs_b->quota = quota;
>> + cfs_b->burst = burst;
>>
>> - __refill_cfs_bandwidth_runtime(cfs_b);
>> -
>> - /* Restart the period timer (if active) to handle new period expiry: */
>> - if (runtime_enabled)
>> + /*
>> + * Restart the period timer (if active) to handle new period expiry.
>> + * And refill runtime and burst-runtime to full charge.
>> + */
>> + if (runtime_enabled) {
>> + cfs_b->burst_runtime = burst;
>> + cfs_b->runtime = quota + burst;
>> start_cfs_bandwidth(cfs_b);
>> + }
>>
>> raw_spin_unlock_irq(&cfs_b->lock);
>>
>> @@ -7442,9 +7448,10 @@ static int tg_set_cfs_bandwidth(struct task_group *tg, u64 period, u64 quota)
>>
>> static int tg_set_cfs_quota(struct task_group *tg, long cfs_quota_us)
>> {
>> - u64 quota, period;
>> + u64 quota, period, burst;
>>
>> period = ktime_to_ns(tg->cfs_bandwidth.period);
>> + burst = tg->cfs_bandwidth.burst;
>> if (cfs_quota_us < 0)
>> quota = RUNTIME_INF;
>> else if ((u64)cfs_quota_us <= U64_MAX / NSEC_PER_USEC)
>> @@ -7452,7 +7459,7 @@ static int tg_set_cfs_quota(struct task_group *tg, long cfs_quota_us)
>> else
>> return -EINVAL;
>>
>> - return tg_set_cfs_bandwidth(tg, period, quota);
>> + return tg_set_cfs_bandwidth(tg, period, quota, burst);
>> }
>>
>> static long tg_get_cfs_quota(struct task_group *tg)
>> @@ -7470,15 +7477,16 @@ static long tg_get_cfs_quota(struct task_group *tg)
>>
>> static int tg_set_cfs_period(struct task_group *tg, long cfs_period_us)
>> {
>> - u64 quota, period;
>> + u64 quota, period, burst;
>>
>> if ((u64)cfs_period_us > U64_MAX / NSEC_PER_USEC)
>> return -EINVAL;
>>
>> period = (u64)cfs_period_us * NSEC_PER_USEC;
>> quota = tg->cfs_bandwidth.quota;
>> + burst = tg->cfs_bandwidth.burst;
>>
>> - return tg_set_cfs_bandwidth(tg, period, quota);
>> + return tg_set_cfs_bandwidth(tg, period, quota, burst);
>> }
>>
>> static long tg_get_cfs_period(struct task_group *tg)
>> @@ -7491,6 +7499,28 @@ static long tg_get_cfs_period(struct task_group *tg)
>> return cfs_period_us;
>> }
>>
>> +static long tg_get_cfs_burst(struct task_group *tg)
>> +{
>> + u64 cfs_burst_us = tg->cfs_bandwidth.burst;
>> +
>> + do_div(cfs_burst_us, NSEC_PER_USEC);
>> + return cfs_burst_us;
>> +}
>> +
>> +static int tg_set_cfs_burst(struct task_group *tg, long cfs_burst_us)
>> +{
>> + u64 quota, period, burst;
>> +
>> + if ((u64)cfs_burst_us > U64_MAX / NSEC_PER_USEC)
>> + return -EINVAL;
>> +
>> + period = ktime_to_ns(tg->cfs_bandwidth.period);
>> + quota = tg->cfs_bandwidth.quota;
>> + burst = (u64)cfs_burst_us * NSEC_PER_USEC;
>> +
>> + return tg_set_cfs_bandwidth(tg, period, quota, burst);
>> +}
>> +
>> static s64 cpu_cfs_quota_read_s64(struct cgroup_subsys_state *css,
>> struct cftype *cft)
>> {
>> @@ -7515,6 +7545,18 @@ static int cpu_cfs_period_write_u64(struct cgroup_subsys_state *css,
>> return tg_set_cfs_period(css_tg(css), cfs_period_us);
>> }
>>
>> +static u64 cpu_cfs_burst_read_u64(struct cgroup_subsys_state *css,
>> + struct cftype *cft)
>> +{
>> + return tg_get_cfs_burst(css_tg(css));
>> +}
>> +
>> +static int cpu_cfs_burst_write_u64(struct cgroup_subsys_state *css,
>> + struct cftype *cftype, u64 cfs_burst_us)
>> +{
>> + return tg_set_cfs_burst(css_tg(css), cfs_burst_us);
>> +}
>> +
>> struct cfs_schedulable_data {
>> struct task_group *tg;
>> u64 period, quota;
>> @@ -7606,6 +7648,7 @@ static int cpu_cfs_stat_show(struct seq_file *sf, void *v)
>> seq_printf(sf, "nr_periods %d\n", cfs_b->nr_periods);
>> seq_printf(sf, "nr_throttled %d\n", cfs_b->nr_throttled);
>> seq_printf(sf, "throttled_time %llu\n", cfs_b->throttled_time);
>> + seq_printf(sf, "burst_time %llu\n", cfs_b->burst_time);
>>
>> if (schedstat_enabled() && tg != &root_task_group) {
>> u64 ws = 0;
>> @@ -7667,6 +7710,11 @@ static struct cftype cpu_legacy_files[] = {
>> .read_u64 = cpu_cfs_period_read_u64,
>> .write_u64 = cpu_cfs_period_write_u64,
>> },
>> + {
>> + .name = "cfs_burst_us",
>> + .read_u64 = cpu_cfs_burst_read_u64,
>> + .write_u64 = cpu_cfs_burst_write_u64,
>> + },
>> {
>> .name = "stat",
>> .seq_show = cpu_cfs_stat_show,
>> @@ -7709,15 +7757,20 @@ static int cpu_extra_stat_show(struct seq_file *sf,
>> struct task_group *tg = css_tg(css);
>> struct cfs_bandwidth *cfs_b = &tg->cfs_bandwidth;
>> u64 throttled_usec;
>> + u64 burst_usec;
>>
>> throttled_usec = cfs_b->throttled_time;
>> do_div(throttled_usec, NSEC_PER_USEC);
>>
>> + burst_usec = cfs_b->burst_time;
>> + do_div(burst_usec, NSEC_PER_USEC);
>> +
>> seq_printf(sf, "nr_periods %d\n"
>> "nr_throttled %d\n"
>> - "throttled_usec %llu\n",
>> + "throttled_usec %llu\n"
>> + "burst_usec %llu\n",
>> cfs_b->nr_periods, cfs_b->nr_throttled,
>> - throttled_usec);
>> + throttled_usec, burst_usec);
>> }
>> #endif
>> return 0;
>> @@ -7787,26 +7840,29 @@ static int cpu_weight_nice_write_s64(struct cgroup_subsys_state *css,
>> #endif
>>
>> static void __maybe_unused cpu_period_quota_print(struct seq_file *sf,
>> - long period, long quota)
>> + long period, long quota,
>> + long burst)
>> {
>> if (quota < 0)
>> seq_puts(sf, "max");
>> else
>> seq_printf(sf, "%ld", quota);
>>
>> - seq_printf(sf, " %ld\n", period);
>> + seq_printf(sf, " %ld %ld\n", period, burst);
>> }
>>
>> /* caller should put the current value in *@periodp before calling */
>> static int __maybe_unused cpu_period_quota_parse(char *buf,
>> - u64 *periodp, u64 *quotap)
>> + u64 *periodp, u64 *quotap,
>> + s64 *burstp)
>> {
>> char tok[21]; /* U64_MAX */
>>
>> - if (sscanf(buf, "%20s %llu", tok, periodp) < 1)
>> + if (sscanf(buf, "%20s %llu %llu", tok, periodp, burstp) < 1)
>> return -EINVAL;
>>
>> *periodp *= NSEC_PER_USEC;
>> + *burstp *= NSEC_PER_USEC;
>>
>> if (sscanf(tok, "%llu", quotap))
>> *quotap *= NSEC_PER_USEC;
>> @@ -7823,7 +7879,8 @@ static int cpu_max_show(struct seq_file *sf, void *v)
>> {
>> struct task_group *tg = css_tg(seq_css(sf));
>>
>> - cpu_period_quota_print(sf, tg_get_cfs_period(tg), tg_get_cfs_quota(tg));
>> + cpu_period_quota_print(sf, tg_get_cfs_period(tg), tg_get_cfs_quota(tg),
>> + tg_get_cfs_burst(tg));
>> return 0;
>> }
>>
>> @@ -7832,12 +7889,13 @@ static ssize_t cpu_max_write(struct kernfs_open_file *of,
>> {
>> struct task_group *tg = css_tg(of_css(of));
>> u64 period = tg_get_cfs_period(tg);
>> + s64 burst = tg_get_cfs_burst(tg);
>> u64 quota;
>> int ret;
>>
>> - ret = cpu_period_quota_parse(buf, &period, "a);
>> + ret = cpu_period_quota_parse(buf, &period, "a, &burst);
>> if (!ret)
>> - ret = tg_set_cfs_bandwidth(tg, period, quota);
>> + ret = tg_set_cfs_bandwidth(tg, period, quota, burst);
>> return ret ?: nbytes;
>> }
>> #endif
>> diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
>> index 69a81a5709ff..f32b72496932 100644
>> --- a/kernel/sched/fair.c
>> +++ b/kernel/sched/fair.c
>> @@ -4353,16 +4353,26 @@ static inline u64 sched_cfs_bandwidth_slice(void)
>> }
>>
>> /*
>> - * Replenish runtime according to assigned quota. We use sched_clock_cpu
>> - * directly instead of rq->clock to avoid adding additional synchronization
>> - * around rq->lock.
>> + * Replenish runtime according to assigned quota.
>> + * Called only if quota != RUNTIME_INF.
>> *
>> * requires cfs_b->lock
>> */
>> void __refill_cfs_bandwidth_runtime(struct cfs_bandwidth *cfs_b)
>> {
>> - if (cfs_b->quota != RUNTIME_INF)
>> - cfs_b->runtime = cfs_b->quota;
>> + u64 runtime = cfs_b->runtime;
>> +
>> + /*
>> + * Preserve past runtime up to burst size. If remaining runtime lower
>> + * than previous burst runtime then account delta as used burst time.
>> + */
>> + if (runtime > cfs_b->burst)
>> + runtime = cfs_b->burst;
>> + else if (runtime < cfs_b->burst_runtime)
>> + cfs_b->burst_time += cfs_b->burst_runtime - runtime;
>> +
>> + cfs_b->burst_runtime = runtime;
>> + cfs_b->runtime = runtime + cfs_b->quota;
>> }
>>
>> static inline struct cfs_bandwidth *tg_cfs_bandwidth(struct task_group *tg)
>> @@ -4968,6 +4978,9 @@ void init_cfs_bandwidth(struct cfs_bandwidth *cfs_b)
>> cfs_b->runtime = 0;
>> cfs_b->quota = RUNTIME_INF;
>> cfs_b->period = ns_to_ktime(default_cfs_period());
>> + cfs_b->burst = 0;
>> + cfs_b->burst_runtime = 0;
>> + cfs_b->burst_time = 0;
>>
>> INIT_LIST_HEAD(&cfs_b->throttled_cfs_rq);
>> hrtimer_init(&cfs_b->period_timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS_PINNED);
>> @@ -4986,14 +4999,23 @@ static void init_cfs_rq_runtime(struct cfs_rq *cfs_rq)
>>
>> void start_cfs_bandwidth(struct cfs_bandwidth *cfs_b)
>> {
>> + u64 overrun;
>> +
>> lockdep_assert_held(&cfs_b->lock);
>>
>> if (cfs_b->period_active)
>> return;
>>
>> cfs_b->period_active = 1;
>> - hrtimer_forward_now(&cfs_b->period_timer, cfs_b->period);
>> + overrun = hrtimer_forward_now(&cfs_b->period_timer, cfs_b->period);
>> hrtimer_start_expires(&cfs_b->period_timer, HRTIMER_MODE_ABS_PINNED);
>> +
>> + /*
>> + * Refill runtime for periods of inactivity and current.
>> + * __refill_cfs_bandwidth_runtime() will cut excess.
>> + */
>> + cfs_b->runtime += cfs_b->quota * overrun;
Overflow in 584 years, even cpu-years, is probably fine. And we skip
refill on the period we stop the timer, so this isn't off by one, though
it might be worth mentioning that in the comment.
>> + __refill_cfs_bandwidth_runtime(cfs_b);
>> }
>>
>> static void destroy_cfs_bandwidth(struct cfs_bandwidth *cfs_b)
>> diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h
>> index c8870c5bd7df..6edf6155e4f6 100644
>> --- a/kernel/sched/sched.h
>> +++ b/kernel/sched/sched.h
>> @@ -344,10 +344,14 @@ struct cfs_bandwidth {
>> struct hrtimer slack_timer;
>> struct list_head throttled_cfs_rq;
>>
>> + u64 burst;
>> + u64 burst_runtime;
>> +
>> /* Statistics: */
>> int nr_periods;
>> int nr_throttled;
>> u64 throttled_time;
>> + u64 burst_time;
>> #endif
>> };
>>
>>
^ permalink raw reply
* [PATCH] doc: move credential helper info into gitcredentials(7)
From: Jeff King @ 2020-02-14 18:54 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: git, Nikita Leonov
On Fri, Feb 14, 2020 at 01:32:00PM -0500, Jeff King wrote:
> This is talking about the git-credential tool itself, but the actual
> helper protocol documentation links to this. (As an aside, I notice that
> the protocol documentation recently got moved into credential.h along
> with the C API bits. Yuck. That probably should be in
> gitcredentials(7)).
I've been meaning to fix this for years, so let's do it while we're
thinking about it (this is orthogonal both semantically and textually to
the patch I was replying to, so it can be handled separately).
-- >8 --
Subject: doc: move credential helper info into gitcredentials(7)
The details of how credential helpers can be called or implemented were
originally covered in Documentation/technical/. Those are topics that
end users might care about (and we even referenced them in the
credentials manpage), but those docs typically don't ship as part of the
end user documentation, making them less useful.
This situation got slightly worse recently in f3b9055624 (credential:
move doc to credential.h, 2019-11-17), where we moved them into the C
header file, making them even harder to find.
So let's move put this information into the gitcredentials(7)
documentation, which is meant to describe the overall concepts of our
credential handling. This was already pointing to the API docs for these
concepts, so we can just include it inline instead.
Signed-off-by: Jeff King <peff@peff.net>
---
Documentation/gitcredentials.txt | 89 ++++++++++++++++++++++++++++++-
credential.h | 90 --------------------------------
2 files changed, 88 insertions(+), 91 deletions(-)
diff --git a/Documentation/gitcredentials.txt b/Documentation/gitcredentials.txt
index ea759fdee5..5b9d14fb1f 100644
--- a/Documentation/gitcredentials.txt
+++ b/Documentation/gitcredentials.txt
@@ -186,7 +186,94 @@ CUSTOM HELPERS
--------------
You can write your own custom helpers to interface with any system in
-which you keep credentials. See credential.h for details.
+which you keep credentials.
+
+Credential helpers are programs executed by Git to fetch or save
+credentials from and to long-term storage (where "long-term" is simply
+longer than a single Git process; e.g., credentials may be stored
+in-memory for a few minutes, or indefinitely on disk).
+
+Each helper is specified by a single string in the configuration
+variable `credential.helper` (and others, see linkgit:git-config[1]).
+The string is transformed by Git into a command to be executed using
+these rules:
+
+ 1. If the helper string begins with "!", it is considered a shell
+ snippet, and everything after the "!" becomes the command.
+
+ 2. Otherwise, if the helper string begins with an absolute path, the
+ verbatim helper string becomes the command.
+
+ 3. Otherwise, the string "git credential-" is prepended to the helper
+ string, and the result becomes the command.
+
+The resulting command then has an "operation" argument appended to it
+(see below for details), and the result is executed by the shell.
+
+Here are some example specifications:
+
+----------------------------------------------------
+# run "git credential-foo"
+foo
+
+# same as above, but pass an argument to the helper
+foo --bar=baz
+
+# the arguments are parsed by the shell, so use shell
+# quoting if necessary
+foo --bar="whitespace arg"
+
+# you can also use an absolute path, which will not use the git wrapper
+/path/to/my/helper --with-arguments
+
+# or you can specify your own shell snippet
+!f() { echo "password=`cat $HOME/.secret`"; }; f
+----------------------------------------------------
+
+Generally speaking, rule (3) above is the simplest for users to specify.
+Authors of credential helpers should make an effort to assist their
+users by naming their program "git-credential-$NAME", and putting it in
+the `$PATH` or `$GIT_EXEC_PATH` during installation, which will allow a
+user to enable it with `git config credential.helper $NAME`.
+
+When a helper is executed, it will have one "operation" argument
+appended to its command line, which is one of:
+
+`get`::
+
+ Return a matching credential, if any exists.
+
+`store`::
+
+ Store the credential, if applicable to the helper.
+
+`erase`::
+
+ Remove a matching credential, if any, from the helper's storage.
+
+The details of the credential will be provided on the helper's stdin
+stream. The exact format is the same as the input/output format of the
+`git credential` plumbing command (see the section `INPUT/OUTPUT
+FORMAT` in linkgit:git-credential[1] for a detailed specification).
+
+For a `get` operation, the helper should produce a list of attributes on
+stdout in the same format (see linkgit:git-credential[1] for common
+attributes). A helper is free to produce a subset, or even no values at
+all if it has nothing useful to provide. Any provided attributes will
+overwrite those already known about by Git. If a helper outputs a
+`quit` attribute with a value of `true` or `1`, no further helpers will
+be consulted, nor will the user be prompted (if no credential has been
+provided, the operation will then fail).
+
+For a `store` or `erase` operation, the helper's output is ignored.
+If it fails to perform the requested operation, it may complain to
+stderr to inform the user. If it does not support the requested
+operation (e.g., a read-only store), it should silently ignore the
+request.
+
+If a helper receives any other operation, it should silently ignore the
+request. This leaves room for future operations to be added (older
+helpers will just ignore the new requests).
GIT
---
diff --git a/credential.h b/credential.h
index 5772d50577..a5a3ee9bb8 100644
--- a/credential.h
+++ b/credential.h
@@ -90,96 +90,6 @@
* return status;
* }
* -----------------------------------------------------------------------
- *
- * Credential Helpers
- * ------------------
- *
- * Credential helpers are programs executed by Git to fetch or save
- * credentials from and to long-term storage (where "long-term" is simply
- * longer than a single Git process; e.g., credentials may be stored
- * in-memory for a few minutes, or indefinitely on disk).
- *
- * Each helper is specified by a single string in the configuration
- * variable `credential.helper` (and others, see Documentation/git-config.txt).
- * The string is transformed by Git into a command to be executed using
- * these rules:
- *
- * 1. If the helper string begins with "!", it is considered a shell
- * snippet, and everything after the "!" becomes the command.
- *
- * 2. Otherwise, if the helper string begins with an absolute path, the
- * verbatim helper string becomes the command.
- *
- * 3. Otherwise, the string "git credential-" is prepended to the helper
- * string, and the result becomes the command.
- *
- * The resulting command then has an "operation" argument appended to it
- * (see below for details), and the result is executed by the shell.
- *
- * Here are some example specifications:
- *
- * ----------------------------------------------------
- * # run "git credential-foo"
- * foo
- *
- * # same as above, but pass an argument to the helper
- * foo --bar=baz
- *
- * # the arguments are parsed by the shell, so use shell
- * # quoting if necessary
- * foo --bar="whitespace arg"
- *
- * # you can also use an absolute path, which will not use the git wrapper
- * /path/to/my/helper --with-arguments
- *
- * # or you can specify your own shell snippet
- * !f() { echo "password=`cat $HOME/.secret`"; }; f
- * ----------------------------------------------------
- *
- * Generally speaking, rule (3) above is the simplest for users to specify.
- * Authors of credential helpers should make an effort to assist their
- * users by naming their program "git-credential-$NAME", and putting it in
- * the $PATH or $GIT_EXEC_PATH during installation, which will allow a user
- * to enable it with `git config credential.helper $NAME`.
- *
- * When a helper is executed, it will have one "operation" argument
- * appended to its command line, which is one of:
- *
- * `get`::
- *
- * Return a matching credential, if any exists.
- *
- * `store`::
- *
- * Store the credential, if applicable to the helper.
- *
- * `erase`::
- *
- * Remove a matching credential, if any, from the helper's storage.
- *
- * The details of the credential will be provided on the helper's stdin
- * stream. The exact format is the same as the input/output format of the
- * `git credential` plumbing command (see the section `INPUT/OUTPUT
- * FORMAT` in Documentation/git-credential.txt for a detailed specification).
- *
- * For a `get` operation, the helper should produce a list of attributes
- * on stdout in the same format. A helper is free to produce a subset, or
- * even no values at all if it has nothing useful to provide. Any provided
- * attributes will overwrite those already known about by Git. If a helper
- * outputs a `quit` attribute with a value of `true` or `1`, no further
- * helpers will be consulted, nor will the user be prompted (if no
- * credential has been provided, the operation will then fail).
- *
- * For a `store` or `erase` operation, the helper's output is ignored.
- * If it fails to perform the requested operation, it may complain to
- * stderr to inform the user. If it does not support the requested
- * operation (e.g., a read-only store), it should silently ignore the
- * request.
- *
- * If a helper receives any other operation, it should silently ignore the
- * request. This leaves room for future operations to be added (older
- * helpers will just ignore the new requests).
- *
*/
--
2.25.0.796.gcc29325708
^ permalink raw reply related
* Re: [Intel-gfx] [PATCH i-g-t] lib/i915/gem_engine_topology.c - intel_get_current_engine invalid result
From: Chris Wilson @ 2020-02-14 18:54 UTC (permalink / raw)
To: Antonio Argenziano, Dale B Stimson, igt-dev, intel-gfx
In-Reply-To: <158170587922.15393.4799274587942949539@skylake-alporthouse-com>
+static void libapi(int i915)
+{
+ I915_DEFINE_CONTEXT_PARAM_ENGINES(engines, 0);
+ struct drm_i915_gem_context_param p = {
+ .ctx_id = gem_context_create(i915),
+ .param = I915_CONTEXT_PARAM_ENGINES,
+ .value = to_user_pointer(&engines),
+ .size = sizeof(engines),
+ };
+ const struct intel_execution_engine2 *e;
+ unsigned int count = 0;
+
+ gem_context_set_param(i915, &p);
+
+ for_each_context_engine(i915, p.ctx_id, e)
+ count++;
+ igt_assert_eq(count, 0);
+
+ ____for_each_physical_engine(i915, p.ctx_id, e)
+ count++;
+ igt_assert_eq(count, 0);
+
+ gem_context_destroy(i915, p.ctx_id);
+}
I leave find a home and correcting the whitespace to the reader.
-Chris
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply
* Re: [igt-dev] [PATCH i-g-t] lib/i915/gem_engine_topology.c - intel_get_current_engine invalid result
From: Chris Wilson @ 2020-02-14 18:54 UTC (permalink / raw)
To: Antonio Argenziano, Dale B Stimson, igt-dev, intel-gfx; +Cc: Petri Latvala
In-Reply-To: <158170587922.15393.4799274587942949539@skylake-alporthouse-com>
+static void libapi(int i915)
+{
+ I915_DEFINE_CONTEXT_PARAM_ENGINES(engines, 0);
+ struct drm_i915_gem_context_param p = {
+ .ctx_id = gem_context_create(i915),
+ .param = I915_CONTEXT_PARAM_ENGINES,
+ .value = to_user_pointer(&engines),
+ .size = sizeof(engines),
+ };
+ const struct intel_execution_engine2 *e;
+ unsigned int count = 0;
+
+ gem_context_set_param(i915, &p);
+
+ for_each_context_engine(i915, p.ctx_id, e)
+ count++;
+ igt_assert_eq(count, 0);
+
+ ____for_each_physical_engine(i915, p.ctx_id, e)
+ count++;
+ igt_assert_eq(count, 0);
+
+ gem_context_destroy(i915, p.ctx_id);
+}
I leave find a home and correcting the whitespace to the reader.
-Chris
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev
^ permalink raw reply
* [meta-python][PATCH] python-beautifulsoup4: consolidate inc and bb files into a single bb file
From: Derek Straka @ 2020-02-14 18:53 UTC (permalink / raw)
To: openembedded-devel
Signed-off-by: Derek Straka <derek@asterius.io>
---
.../python/python-beautifulsoup4.inc | 17 -----------------
.../python/python3-beautifulsoup4_4.8.2.bb | 19 +++++++++++++++++--
2 files changed, 17 insertions(+), 19 deletions(-)
delete mode 100644 meta-python/recipes-devtools/python/python-beautifulsoup4.inc
diff --git a/meta-python/recipes-devtools/python/python-beautifulsoup4.inc b/meta-python/recipes-devtools/python/python-beautifulsoup4.inc
deleted file mode 100644
index 3e95bb7f21..0000000000
--- a/meta-python/recipes-devtools/python/python-beautifulsoup4.inc
+++ /dev/null
@@ -1,17 +0,0 @@
-SUMMARY = "Screen-scraping library"
-HOMEPAGE = " https://www.crummy.com/software/BeautifulSoup/bs4"
-LICENSE = "MIT"
-LIC_FILES_CHKSUM = "file://COPYING.txt;md5=f2d38d8a40bf73fd4b3d16ca2e5882d1"
-
-SRC_URI[md5sum] = "5dbdb56c009e4632bae7bed1b385804b"
-SRC_URI[sha256sum] = "05fd825eb01c290877657a56df4c6e4c311b3965bda790c613a3d6fb01a5462a"
-
-inherit pypi
-
-RDEPENDS_${PN} = "\
- ${PYTHON_PN}-html5lib \
- ${PYTHON_PN}-lxml \
- ${PYTHON_PN}-soupsieve \
-"
-
-BBCLASSEXTEND = "native nativesdk"
diff --git a/meta-python/recipes-devtools/python/python3-beautifulsoup4_4.8.2.bb b/meta-python/recipes-devtools/python/python3-beautifulsoup4_4.8.2.bb
index d98df11e3d..63fbd09582 100644
--- a/meta-python/recipes-devtools/python/python3-beautifulsoup4_4.8.2.bb
+++ b/meta-python/recipes-devtools/python/python3-beautifulsoup4_4.8.2.bb
@@ -1,2 +1,17 @@
-inherit setuptools3
-require python-beautifulsoup4.inc
+SUMMARY = "Screen-scraping library"
+HOMEPAGE = " https://www.crummy.com/software/BeautifulSoup/bs4"
+LICENSE = "MIT"
+LIC_FILES_CHKSUM = "file://COPYING.txt;md5=f2d38d8a40bf73fd4b3d16ca2e5882d1"
+
+SRC_URI[md5sum] = "5dbdb56c009e4632bae7bed1b385804b"
+SRC_URI[sha256sum] = "05fd825eb01c290877657a56df4c6e4c311b3965bda790c613a3d6fb01a5462a"
+
+inherit pypi setuptools3
+
+RDEPENDS_${PN} = "\
+ ${PYTHON_PN}-html5lib \
+ ${PYTHON_PN}-lxml \
+ ${PYTHON_PN}-soupsieve \
+"
+
+BBCLASSEXTEND = "native nativesdk"
--
2.17.1
^ permalink raw reply related
* Re: [PATCH v2 net 3/3] wireguard: send: account for mtu=0 devices
From: Eric Dumazet @ 2020-02-14 18:53 UTC (permalink / raw)
To: Jason A. Donenfeld; +Cc: David Miller, Netdev, Eric Dumazet
In-Reply-To: <CAHmME9oXfDCGmsCJJEuaPmgj7_U4yfrBoqi0wRZrOD9SdWny_w@mail.gmail.com>
On 2/14/20 10:37 AM, Jason A. Donenfeld wrote:
> On 2/14/20, Eric Dumazet <eric.dumazet@gmail.com> wrote:
>>
>>
>> On 2/14/20 10:15 AM, Jason A. Donenfeld wrote:
>>> On Fri, Feb 14, 2020 at 6:56 PM Eric Dumazet <eric.dumazet@gmail.com>
>>> wrote:
>>>> Oh dear, can you describe what do you expect of a wireguard device with
>>>> mtu == 0 or mtu == 1
>>>>
>>>> Why simply not allowing silly configurations, instead of convoluted tests
>>>> in fast path ?
>>>>
>>>> We are speaking of tunnels adding quite a lot of headers, so we better
>>>> not try to make them
>>>> work on networks with tiny mtu. Just say no to syzbot.
>>>
>>> The idea was that wireguard might still be useful for the persistent
>>> keepalive stuff. This branch becomes very cold very fast, so I don't
>>> think it makes a difference performance wise, but if you feel strongly
>>> about it, I can get rid of it and set a non-zero min_mtu that's the
>>> smallest thing wireguard's xmit semantics will accept. It sounds like
>>> you'd prefer that?
>>>
>> Well, if you believe that wireguard in persistent keepalive
>> has some value on its own, I guess that we will have to support this mode.
>
> Alright.
>
>>
>> Some legacy devices can have arbitrary mtu, and this has caused headaches.
>> I was hoping that for brand new devices, we could have saner limits.
>>
>> About setting max_mtu to ~MAX_INT, does it mean wireguard will attempt
>> to send UDP datagrams bigger than 64K ? Where is the segmentation done ?
>
> The before passings off to the udp tunnel api, we indicate that we
> support ip segmentation, and then it gets handled and fragmented
> deeper down. Check out socket.c.
Okay. Speaking of socket.c, I found this wg_socket_reinit() snippet :
synchronize_rcu();
synchronize_net();
Which makes little sense. Please add a comment explaining why these two
calls are needed.
^ permalink raw reply
* Re: [PATCH 06/19] target/arm: Rename isar_feature_aa32_fpdp_v2
From: Philippe Mathieu-Daudé @ 2020-02-14 18:51 UTC (permalink / raw)
To: Richard Henderson, qemu-devel; +Cc: peter.maydell
In-Reply-To: <20200214181547.21408-7-richard.henderson@linaro.org>
On 2/14/20 7:15 PM, Richard Henderson wrote:
> The old name, isar_feature_aa32_fpdp, does not reflect
> that the test includes VFPv2. We will introduce another
> feature tests for VFPv3.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
> target/arm/cpu.h | 4 ++--
> target/arm/translate-vfp.inc.c | 40 +++++++++++++++++-----------------
> 2 files changed, 22 insertions(+), 22 deletions(-)
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
^ permalink raw reply
* [PATCH AUTOSEL 4.19 190/252] ide: remove set but not used variable 'hwif'
From: Sasha Levin @ 2020-02-14 16:10 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Sasha Levin, Wang Hai, linux-ide, Hulk Robot, linuxppc-dev,
David S . Miller
In-Reply-To: <20200214161147.15842-1-sashal@kernel.org>
From: Wang Hai <wanghai38@huawei.com>
[ Upstream commit 98949a1946d70771789def0c9dbc239497f9f138 ]
Fix the following gcc warning:
drivers/ide/pmac.c: In function pmac_ide_setup_device:
drivers/ide/pmac.c:1027:14: warning: variable hwif set but not used
[-Wunused-but-set-variable]
Fixes: d58b0c39e32f ("powerpc/macio: Rework hotplug media bay support")
Reported-by: Hulk Robot <hulkci@huawei.com>
Signed-off-by: Wang Hai <wanghai38@huawei.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/ide/pmac.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/ide/pmac.c b/drivers/ide/pmac.c
index 203ed4adc04ae..7db083ec5ee06 100644
--- a/drivers/ide/pmac.c
+++ b/drivers/ide/pmac.c
@@ -1024,7 +1024,6 @@ static int pmac_ide_setup_device(pmac_ide_hwif_t *pmif, struct ide_hw *hw)
struct device_node *np = pmif->node;
const int *bidp;
struct ide_host *host;
- ide_hwif_t *hwif;
struct ide_hw *hws[] = { hw };
struct ide_port_info d = pmac_port_info;
int rc;
@@ -1080,7 +1079,7 @@ static int pmac_ide_setup_device(pmac_ide_hwif_t *pmif, struct ide_hw *hw)
rc = -ENOMEM;
goto bail;
}
- hwif = pmif->hwif = host->ports[0];
+ pmif->hwif = host->ports[0];
if (on_media_bay(pmif)) {
/* Fixup bus ID for media bay */
--
2.20.1
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.