* Re: [PATCH v5 06/11] nvmem: Add bindings for simple nvmem framework
From: Stephen Boyd @ 2015-06-16 22:53 UTC (permalink / raw)
To: Srinivas Kandagatla, linux-arm-kernel
Cc: Maxime Ripard, Rob Herring, Kumar Gala, Mark Brown, s.hauer,
Greg Kroah-Hartman, linux-api, linux-kernel, devicetree,
linux-arm-msm, arnd, pantelis.antoniou, mporter
In-Reply-To: <1432226652-8947-1-git-send-email-srinivas.kandagatla@linaro.org>
On 05/21/2015 09:44 AM, Srinivas Kandagatla wrote:
> diff --git a/Documentation/devicetree/bindings/nvmem/nvmem.txt b/Documentation/devicetree/bindings/nvmem/nvmem.txt
> new file mode 100644
> index 0000000..ecea654
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/nvmem/nvmem.txt
> @@ -0,0 +1,84 @@
> += NVMEM Data Device Tree Bindings =
> +
> +This binding is intended to represent the location of hardware
> +configuration data stored in NVMEMs.
It would be worthwhile spelling out what NVMEM stands for.
> +
> +On a significant proportion of boards, the manufacturer has stored
> +some data on NVMEM, for the OS to be able to retrieve these information
> +and act upon it. Obviously, the OS has to know about where to retrieve
> +these data from, and where they are stored on the storage device.
> +
> +This document is here to document this.
> +
> += Data providers =
> +Contains bindings specific to provider drivers and data cells as children
> +to this node.
children of this node?
> +
> +Optional properties:
> + read-only: Mark the provider as read only.
> +
> += Data cells =
> +These are the child nodes of the provider which contain data cell
> +information like offset and size in nvmem provider.
> +
> +Required properties:
> +reg: specifies the offset in byte within that storage device, start bit
> + in the byte and the length in bits of the data we care about.
> + There could be more then one offset-length pairs in this property.
s/then/than/
> +
> +Optional properties:
> +
> +bit-offset: specifies the offset in bit within the address range specified
> + by reg property. Can take values from 0-7.
> +nbits: specifies number of bits this cell occupies starting from bit-offset.
> +
Hopefully the consumer knows the endianness of the data stored.
> +For example:
> +
> + /* Provider */
> + qfprom: qfprom@00700000 {
> + ...
> +
> + /* Data cells */
> + tsens_calibration: calib@404 {
> + reg = <0x404 0x10>;
> + };
> +
> + tsens_calibration_bckp: calib_bckp@504 {
> + reg = <0x504 0x11>;
> + bit-offset = 6;
> + nbits = 128;
> + };
> +
> + pvs_version: pvs-version@6 {
> + reg = <0x6 0x2>
> + bit-offset = 7;
> + nbits = 2;
> + };
> +
> + speed_bin: speed-bin@c{
> + reg = <0xc 0x1>;
> + bit-offset = 2;
> + nbits = 3;
> +
> + };
> + ...
> + };
> +
> += Data consumers =
> +Are device nodes which consume nvmem data cells/providers.
> +
> +Required-properties:
> +nvmem-cell: list of phandle to the nvmem data cells.
> +nvmem-cell-names: names for the each nvmem-cell specified
> +
> +Optional-properties:
> +nvmem : list of phandles to nvmem providers.
> +nvmem-names: names for the each nvmem provider.
Is nvmem-names required if nvmem is used?
--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
^ permalink raw reply
* Re: [PATCH v5 07/11] nvmem: Add simple nvmem-mmio consumer helper functions.
From: Stephen Boyd @ 2015-06-16 22:58 UTC (permalink / raw)
To: Srinivas Kandagatla,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
Cc: Maxime Ripard, Rob Herring, Kumar Gala, Mark Brown,
s.hauer-bIcnvbaLZ9MEGnE8C9+IrQ, Greg Kroah-Hartman,
linux-api-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-msm-u79uwXL29TY76Z2rM5mHXA, arnd-r2nGTMty4D4,
pantelis.antoniou-OWPKS81ov/FWk0Htik3J/w,
mporter-OWPKS81ov/FWk0Htik3J/w
In-Reply-To: <1432226665-8994-1-git-send-email-srinivas.kandagatla-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
On 05/21/2015 09:44 AM, Srinivas Kandagatla wrote:
> diff --git a/drivers/nvmem/nvmem-mmio.c b/drivers/nvmem/nvmem-mmio.c
> new file mode 100644
> index 0000000..0d8131f
> --- /dev/null
> +++ b/drivers/nvmem/nvmem-mmio.c
> @@ -0,0 +1,69 @@
> +/*
> + * Copyright (C) 2015 Srinivas Kandagatla <srinivas.kandagatla-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 and
> + * only version 2 as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + */
> +
> +#include <linux/device.h>
> +#include <linux/module.h>
> +#include <linux/err.h>
> +#include <linux/of.h>
> +#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/nvmem_provider.h>
#include <linux/regmap.h>
> +#include "nvmem-mmio.h"
> +
> +int nvmem_mmio_remove(struct platform_device *pdev)
> +{
> + struct nvmem_device *nvmem = platform_get_drvdata(pdev);
> +
> + return nvmem_unregister(nvmem);
> +}
> +EXPORT_SYMBOL_GPL(nvmem_mmio_remove);
> +
> +int nvmem_mmio_probe(struct platform_device *pdev)
> +{
> +
[...]
> +
> + platform_set_drvdata(pdev, nvmem);
It may be better to return the nvmem device instead so that the one
drvdata member is usable by the calling driver.
> +
> + return 0;
> +}
> +EXPORT_SYMBOL_GPL(nvmem_mmio_probe);
Kernel-doc on these exported functions?
> diff --git a/drivers/nvmem/nvmem-mmio.h b/drivers/nvmem/nvmem-mmio.h
> new file mode 100644
> index 0000000..a2ad4e5
> --- /dev/null
> +++ b/drivers/nvmem/nvmem-mmio.h
> @@ -0,0 +1,41 @@
> +/*
> + * MMIO based nvmem providers.
> + *
> + * Copyright (C) 2015 Srinivas Kandagatla <srinivas.kandagatla-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
> + *
> + * This file is licensed under the terms of the GNU General Public
> + * License version 2. This program is licensed "as is" without any
> + * warranty of any kind, whether express or implied.
> + */
> +
> +#ifndef _LINUX_NVMEM_MMIO_H
> +#define _LINUX_NVMEM_MMIO_H
> +
> +#include <linux/platform_device.h>
Forward declare struct platform_device instead.
> +#include <linux/nvmem-provider.h>
Forward declare nvmem_config instead.
> +#include <linux/regmap.h>
Forward declare regmap_config instead.
> +
> +struct nvmem_mmio_data {
> + struct regmap_config *regmap_config;
> + struct nvmem_config *nvmem_config;
> +};
> +
> +#if IS_ENABLED(CONFIG_NVMEM)
> +
> +int nvmem_mmio_probe(struct platform_device *pdev);
> +int nvmem_mmio_remove(struct platform_device *pdev);
--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH v5 08/11] nvmem: qfprom: Add Qualcomm QFPROM support.
From: Stephen Boyd @ 2015-06-16 23:00 UTC (permalink / raw)
To: Srinivas Kandagatla, linux-arm-kernel
Cc: Maxime Ripard, Rob Herring, Kumar Gala, Mark Brown, s.hauer,
Greg Kroah-Hartman, linux-api, linux-kernel, devicetree,
linux-arm-msm, arnd, pantelis.antoniou, mporter
In-Reply-To: <1432226675-9039-1-git-send-email-srinivas.kandagatla@linaro.org>
On 05/21/2015 09:44 AM, Srinivas Kandagatla wrote:
> diff --git a/drivers/nvmem/Kconfig b/drivers/nvmem/Kconfig
> index f157b6d..e665e23 100644
> --- a/drivers/nvmem/Kconfig
> +++ b/drivers/nvmem/Kconfig
> @@ -8,3 +8,18 @@ menuconfig NVMEM
> from both the Linux Kernel and the userspace.
>
> If unsure, say no.
> +
> +if NVMEM
> +
> +config QCOM_QFPROM
> + tristate "QCOM QFPROM Support"
> + depends on ARCH_QCOM
|| COMPILE_TEST?
> + select REGMAP_MMIO
> + help
> + Say y here to enable QFPROM support. The QFPROM provides access
> + functions for QFPROM data to rest of the drivers via nvmem interface.
> +
> + This driver can also be built as a module. If so, the module
> + will be called nvmem-qfprom.
> +
> +endif
> diff --git a/drivers/nvmem/Makefile b/drivers/nvmem/Makefile
> index f694cfc..caea611 100644
> --- a/drivers/nvmem/Makefile
> +++ b/drivers/nvmem/Makefile
> @@ -5,3 +5,7 @@
> obj-$(CONFIG_NVMEM) += nvmem_core.o
> nvmem_core-y := core.o
> nvmem_core-y += nvmem-mmio.o
> +
> +# Devices
> +obj-$(CONFIG_QCOM_QFPROM) += nvmem_qfprom.o
> +nvmem_qfprom-y := qfprom.o
Why not just
obj-$(CONFIG_QCOM_QFPROM) += nvmem_qfprom.o
?
> diff --git a/drivers/nvmem/qfprom.c b/drivers/nvmem/qfprom.c
> new file mode 100644
> index 0000000..5ea84bb
> --- /dev/null
> +++ b/drivers/nvmem/qfprom.c
> @@ -0,0 +1,51 @@
> +/*
> + * Copyright (C) 2015 Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 and
> + * only version 2 as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + */
> +
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include "nvmem-mmio.h"
> +
> +static struct regmap_config qfprom_regmap_config = {
const?
> + .reg_bits = 32,
> + .val_bits = 8,
> + .reg_stride = 1,
> +};
> +
> +static struct nvmem_config econfig = {
const?
> + .name = "qfprom",
> + .owner = THIS_MODULE,
> +};
> +
> +static struct nvmem_mmio_data qfprom_data = {
const?
> + .nvmem_config = &econfig,
> + .regmap_config = &qfprom_regmap_config,
> +};
>
--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
^ permalink raw reply
* Re: [PATCH v5 09/11] nvmem: qfprom: Add bindings for qfprom
From: Stephen Boyd @ 2015-06-16 23:01 UTC (permalink / raw)
To: Srinivas Kandagatla,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
Cc: Maxime Ripard, Rob Herring, Kumar Gala, Mark Brown,
s.hauer-bIcnvbaLZ9MEGnE8C9+IrQ, Greg Kroah-Hartman,
linux-api-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-msm-u79uwXL29TY76Z2rM5mHXA, arnd-r2nGTMty4D4,
pantelis.antoniou-OWPKS81ov/FWk0Htik3J/w,
mporter-OWPKS81ov/FWk0Htik3J/w
In-Reply-To: <1432226685-9081-1-git-send-email-srinivas.kandagatla-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
On 05/21/2015 09:44 AM, Srinivas Kandagatla wrote:
> This patch adds bindings for qfprom found in QCOM SOCs. QFPROM driver
> is based on simple nvmem framework.
>
> Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
> ---
Reviewed-by: Stephen Boyd <sboyd-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
^ permalink raw reply
* Re: [PATCH v5 10/11] nvmem: sunxi: Move the SID driver to the nvmem framework
From: Stephen Boyd @ 2015-06-16 23:04 UTC (permalink / raw)
To: Srinivas Kandagatla,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
Cc: Maxime Ripard, Rob Herring, Kumar Gala, Mark Brown,
s.hauer-bIcnvbaLZ9MEGnE8C9+IrQ, Greg Kroah-Hartman,
linux-api-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-msm-u79uwXL29TY76Z2rM5mHXA, arnd-r2nGTMty4D4,
pantelis.antoniou-OWPKS81ov/FWk0Htik3J/w,
mporter-OWPKS81ov/FWk0Htik3J/w
In-Reply-To: <1432226733-9243-1-git-send-email-srinivas.kandagatla-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
On 05/21/2015 09:45 AM, Srinivas Kandagatla wrote:
> diff --git a/drivers/nvmem/Makefile b/drivers/nvmem/Makefile
> index caea611..cc46791 100644
> --- a/drivers/nvmem/Makefile
> +++ b/drivers/nvmem/Makefile
> @@ -9,3 +9,5 @@ nvmem_core-y += nvmem-mmio.o
> # Devices
> obj-$(CONFIG_QCOM_QFPROM) += nvmem_qfprom.o
> nvmem_qfprom-y := qfprom.o
> +obj-$(CONFIG_NVMEM_SUNXI_SID) += nvmem-sunxi-sid.o
> +nvmem-sunxi-sid-y := sunxi-sid.o
Oh I see, so the module has nvmem- in the name. Isn't there some way to
add a rule to do that for all provider drivers?
> diff --git a/drivers/nvmem/sunxi-sid.c b/drivers/nvmem/sunxi-sid.c
> new file mode 100644
> index 0000000..5bfce35
> --- /dev/null
> +++ b/drivers/nvmem/sunxi-sid.c
> @@ -0,0 +1,64 @@
> +/*
> + * Allwinner sunXi SoCs Security ID support.
> + *
> + * Copyright (c) 2013 Oliver Schinagl <oliver-dxLnbx3+1qmEVqv0pETR8A@public.gmane.org>
> + * Copyright (C) 2014 Maxime Ripard <maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + */
> +
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include "nvmem-mmio.h"
> +
> +static bool sunxi_sid_writeable_reg(struct device *dev, unsigned int reg)
> +{
> + return false;
> +}
> +
> +static struct nvmem_config econfig = {
const?
> + .name = "sunix-sid",
> + .owner = THIS_MODULE,
> +};
> +
> +static struct regmap_config sunxi_sid_regmap_config = {
const?
> + .reg_bits = 32,
> + .val_bits = 32,
> + .reg_stride = 4,
> + .writeable_reg = sunxi_sid_writeable_reg,
> +};
> +
> +static struct nvmem_mmio_data sunxi_data = {
const?
> + .nvmem_config = &econfig,
> + .regmap_config = &sunxi_sid_regmap_config,
> +};
> +
--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
^ permalink raw reply
* Re: [PATCH v4] pagemap: switch to the new format and do some cleanup
From: Konstantin Khlebnikov @ 2015-06-17 4:59 UTC (permalink / raw)
To: Andrew Morton
Cc: linux-mm-Bw31MaZKKs3YtjvyW6yDsg@public.gmane.org, Mark Williamson,
Naoya Horiguchi, Linux API, Linux Kernel Mailing List,
Kirill A. Shutemov
In-Reply-To: <20150616142935.b8f679650e35534e75806399-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b@public.gmane.org>
On Wed, Jun 17, 2015 at 12:29 AM, Andrew Morton
<akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b@public.gmane.org> wrote:
> On Mon, 15 Jun 2015 08:56:49 +0300 Konstantin Khlebnikov <koct9i-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
>
>> This patch removes page-shift bits (scheduled to remove since 3.11) and
>> completes migration to the new bit layout. Also it cleans messy macro.
>
> hm, I can't find any kernel version to which this patch comes close to
> applying.
This patchset applies to 4.1-rc8 and current mmotm without problems.
I guess you've tried pick this patch alone without previous changes.
^ permalink raw reply
* Re: [RFC v3 4/4] shmem: Add support for generic FS events
From: Leon Romanovsky @ 2015-06-17 6:08 UTC (permalink / raw)
To: Beata Michalska
Cc: linux-kernel@vger.kernel.org, Linux-FSDevel, linux-api,
Greg Kroah, jack, tytso, adilger.kernel, Hugh Dickins, lczerner,
hch, linux-ext4, Linux-MM, kyungmin.park, kmpark
In-Reply-To: <1434460173-18427-5-git-send-email-b.michalska@samsung.com>
> }
> - if (error == -ENOSPC && !once++) {
> + if (error == -ENOSPC) {
> + if (!once++) {
> info = SHMEM_I(inode);
> spin_lock(&info->lock);
> shmem_recalc_inode(inode);
> spin_unlock(&info->lock);
> goto repeat;
> + } else {
> + fs_event_notify(inode->i_sb, FS_WARN_ENOSPC);
> + }
> }
Very minor remark, please fix indentation.
^ permalink raw reply
* Re: [PATCH] selftests: add seccomp suite
From: Michael Ellerman @ 2015-06-17 6:12 UTC (permalink / raw)
To: Kees Cook
Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA, Daniel Borkmann, Shuah Khan,
Andy Lutomirski, Will Drewry, Andrew Morton, Greg KH,
Mauro Carvalho Chehab, David S. Miller, Arnd Bergmann,
Joe Perches, Jingoo Han, linux-api-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20150616175414.GA24958-0X9Bc/hWBUTk6RaD4rd5nQ@public.gmane.org>
On Tue, 2015-06-16 at 10:54 -0700, Kees Cook wrote:
> This imports the existing seccomp test suite into the kernel's selftests
> tree. It contains extensive testing of seccomp features and corner cases.
> There remain additional tests to move into the kernel tree, but they have
> not yet been ported to all the architectures seccomp supports:
> https://github.com/redpig/seccomp/tree/master/tests
> diff --git a/tools/testing/selftests/seccomp/Makefile b/tools/testing/selftests/seccomp/Makefile
> new file mode 100644
> index 000000000000..8401e87e34e1
> --- /dev/null
> +++ b/tools/testing/selftests/seccomp/Makefile
> @@ -0,0 +1,10 @@
> +TEST_PROGS := seccomp_bpf
> +CFLAGS += -Wl,-no-as-needed -Wall
> +LDFLAGS += -lpthread
Can't you do:
CFLAGS += -Wall
LDLIBS += -lpthread
?
cheers
^ permalink raw reply
* Re: [RFC v3 3/4] ext4: Add support for generic FS events
From: Leon Romanovsky @ 2015-06-17 6:15 UTC (permalink / raw)
To: Beata Michalska
Cc: linux-kernel@vger.kernel.org, Linux-FSDevel, linux-api,
Greg Kroah, jack, tytso, adilger.kernel, Hugh Dickins, lczerner,
hch, linux-ext4, Linux-MM, kyungmin.park, kmpark
In-Reply-To: <1434460173-18427-4-git-send-email-b.michalska@samsung.com>
On Tue, Jun 16, 2015 at 4:09 PM, Beata Michalska
<b.michalska@samsung.com> wrote:
> Add support for generic FS events including threshold
> notifications, ENOSPC and remount as read-only warnings,
> along with generic internal warnings/errors.
>
> Signed-off-by: Beata Michalska <b.michalska@samsung.com>
> ---
> fs/ext4/balloc.c | 10 ++++++++--
> fs/ext4/ext4.h | 1 +
> fs/ext4/inode.c | 2 +-
> fs/ext4/mballoc.c | 6 +++++-
> fs/ext4/resize.c | 1 +
> fs/ext4/super.c | 39 +++++++++++++++++++++++++++++++++++++++
> 6 files changed, 55 insertions(+), 4 deletions(-)
>
> diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c
> index e95b27a..a48450f 100644
> --- a/fs/ext4/balloc.c
> +++ b/fs/ext4/balloc.c
> @@ -569,6 +569,7 @@ int ext4_claim_free_clusters(struct ext4_sb_info *sbi,
> {
> if (ext4_has_free_clusters(sbi, nclusters, flags)) {
> percpu_counter_add(&sbi->s_dirtyclusters_counter, nclusters);
> + fs_event_alloc_space(sbi->s_sb, EXT4_C2B(sbi, nclusters));
> return 0;
> } else
> return -ENOSPC;
Do you need to add "fs_event_notify(sb, FS_WARN_ENOSPC);" here too?
> @@ -590,9 +591,10 @@ int ext4_should_retry_alloc(struct super_block *sb, int *retries)
> {
> if (!ext4_has_free_clusters(EXT4_SB(sb), 1, 0) ||
> (*retries)++ > 3 ||
> - !EXT4_SB(sb)->s_journal)
> + !EXT4_SB(sb)->s_journal) {
> + fs_event_notify(sb, FS_WARN_ENOSPC);
> return 0;
> -
> + }
> jbd_debug(1, "%s: retrying operation after ENOSPC\n", sb->s_id);
>
> return jbd2_journal_force_commit_nested(EXT4_SB(sb)->s_journal);
> @@ -637,6 +639,10 @@ ext4_fsblk_t ext4_new_meta_blocks(handle_t *handle, struct inode *inode,
> dquot_alloc_block_nofail(inode,
> EXT4_C2B(EXT4_SB(inode->i_sb), ar.len));
> }
> +
> + if (*errp == -ENOSPC)
> + fs_event_notify(inode->i_sb, FS_WARN_ENOSPC_META);
> +
> return ret;
> }
>
> diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
> index 163afe2..7d75ff9 100644
> --- a/fs/ext4/ext4.h
> +++ b/fs/ext4/ext4.h
> @@ -2542,6 +2542,7 @@ void ext4_mark_group_corrupted(struct ext4_sb_info *sbi,
> if (!EXT4_MB_GRP_BBITMAP_CORRUPT(grp))
> percpu_counter_sub(&sbi->s_freeclusters_counter, grp->bb_free);
> set_bit(EXT4_GROUP_INFO_BBITMAP_CORRUPT_BIT, &grp->bb_state);
> + fs_event_alloc_space(sbi->s_sb, EXT4_C2B(sbi, grp->bb_free));
> }
>
> /*
> diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
> index 5cb9a21..2a7af0f 100644
> --- a/fs/ext4/inode.c
> +++ b/fs/ext4/inode.c
> @@ -1238,7 +1238,7 @@ static void ext4_da_release_space(struct inode *inode, int to_free)
> percpu_counter_sub(&sbi->s_dirtyclusters_counter, to_free);
>
> spin_unlock(&EXT4_I(inode)->i_block_reservation_lock);
> -
> + fs_event_free_space(sbi->s_sb, to_free);
> dquot_release_reservation_block(inode, EXT4_C2B(sbi, to_free));
> }
>
> diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
> index 24a4b6d..c2df6f0 100644
> --- a/fs/ext4/mballoc.c
> +++ b/fs/ext4/mballoc.c
> @@ -4511,6 +4511,9 @@ out:
> kmem_cache_free(ext4_ac_cachep, ac);
> if (inquota && ar->len < inquota)
> dquot_free_block(ar->inode, EXT4_C2B(sbi, inquota - ar->len));
> + if (reserv_clstrs && ar->len < reserv_clstrs)
> + fs_event_free_space(sbi->s_sb,
> + EXT4_C2B(sbi, reserv_clstrs - ar->len));
> if (!ar->len) {
> if ((ar->flags & EXT4_MB_DELALLOC_RESERVED) == 0)
> /* release all the reserved blocks if non delalloc */
> @@ -4848,7 +4851,7 @@ do_more:
> if (!(flags & EXT4_FREE_BLOCKS_NO_QUOT_UPDATE))
> dquot_free_block(inode, EXT4_C2B(sbi, count_clusters));
> percpu_counter_add(&sbi->s_freeclusters_counter, count_clusters);
> -
> + fs_event_free_space(sb, EXT4_C2B(sbi, count_clusters));
> ext4_mb_unload_buddy(&e4b);
>
> /* We dirtied the bitmap block */
> @@ -4982,6 +4985,7 @@ int ext4_group_add_blocks(handle_t *handle, struct super_block *sb,
> ext4_unlock_group(sb, block_group);
> percpu_counter_add(&sbi->s_freeclusters_counter,
> EXT4_NUM_B2C(sbi, blocks_freed));
> + fs_event_free_space(sb, blocks_freed);
>
> if (sbi->s_log_groups_per_flex) {
> ext4_group_t flex_group = ext4_flex_group(sbi, block_group);
> diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c
> index 8a8ec62..dbf08d6 100644
> --- a/fs/ext4/resize.c
> +++ b/fs/ext4/resize.c
> @@ -1378,6 +1378,7 @@ static void ext4_update_super(struct super_block *sb,
> EXT4_NUM_B2C(sbi, free_blocks));
> percpu_counter_add(&sbi->s_freeinodes_counter,
> EXT4_INODES_PER_GROUP(sb) * flex_gd->count);
> + fs_event_free_space(sb, free_blocks - reserved_blocks);
>
> ext4_debug("free blocks count %llu",
> percpu_counter_read(&sbi->s_freeclusters_counter));
> diff --git a/fs/ext4/super.c b/fs/ext4/super.c
> index e061e66..108b667 100644
> --- a/fs/ext4/super.c
> +++ b/fs/ext4/super.c
> @@ -585,6 +585,8 @@ void __ext4_abort(struct super_block *sb, const char *function,
> if (EXT4_SB(sb)->s_journal)
> jbd2_journal_abort(EXT4_SB(sb)->s_journal, -EIO);
> save_error_info(sb, function, line);
> + fs_event_notify(sb, FS_ERR_REMOUNT_RO);
> +
> }
> if (test_opt(sb, ERRORS_PANIC))
> panic("EXT4-fs panic from previous error\n");
> @@ -1083,6 +1085,12 @@ static const struct quotactl_ops ext4_qctl_operations = {
> };
> #endif
>
> +static void ext4_trace_query(struct super_block *sb, u64 *ncount);
> +
> +static const struct fs_trace_operations ext4_trace_ops = {
> + .query = ext4_trace_query,
> +};
> +
> static const struct super_operations ext4_sops = {
> .alloc_inode = ext4_alloc_inode,
> .destroy_inode = ext4_destroy_inode,
> @@ -3398,11 +3406,20 @@ static int ext4_reserve_clusters(struct ext4_sb_info *sbi, ext4_fsblk_t count)
> {
> ext4_fsblk_t clusters = ext4_blocks_count(sbi->s_es) >>
> sbi->s_cluster_bits;
> + ext4_fsblk_t current_resv;
>
> if (count >= clusters)
> return -EINVAL;
>
> + current_resv = atomic64_read(&sbi->s_resv_clusters);
> atomic64_set(&sbi->s_resv_clusters, count);
> +
> + if (count > current_resv)
> + fs_event_alloc_space(sbi->s_sb,
> + EXT4_C2B(sbi, count - current_resv));
> + else
> + fs_event_free_space(sbi->s_sb,
> + EXT4_C2B(sbi, current_resv - count));
> return 0;
> }
>
> @@ -3966,6 +3983,9 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
> sb->s_qcop = &ext4_qctl_operations;
> sb->s_quota_types = QTYPE_MASK_USR | QTYPE_MASK_GRP;
> #endif
> + sb->s_etrace.ops = &ext4_trace_ops;
> + sb->s_etrace.events_cap_mask = FS_EVENTS_ALL;
> +
> memcpy(sb->s_uuid, es->s_uuid, sizeof(es->s_uuid));
>
> INIT_LIST_HEAD(&sbi->s_orphan); /* unlinked but open files */
> @@ -5438,6 +5458,25 @@ out:
>
> #endif
>
> +static void ext4_trace_query(struct super_block *sb, u64 *ncount)
> +{
> + struct ext4_sb_info *sbi = EXT4_SB(sb);
> + struct ext4_super_block *es = sbi->s_es;
> + ext4_fsblk_t rsv_blocks;
> + ext4_fsblk_t nblocks;
> +
> + nblocks = percpu_counter_sum_positive(&sbi->s_freeclusters_counter) -
> + percpu_counter_sum_positive(&sbi->s_dirtyclusters_counter);
> + nblocks = EXT4_C2B(sbi, nblocks);
> + rsv_blocks = ext4_r_blocks_count(es) +
> + EXT4_C2B(sbi, atomic64_read(&sbi->s_resv_clusters));
> + if (nblocks < rsv_blocks)
> + nblocks = 0;
> + else
> + nblocks -= rsv_blocks;
> + *ncount = nblocks;
> +}
> +
> static struct dentry *ext4_mount(struct file_system_type *fs_type, int flags,
> const char *dev_name, void *data)
> {
> --
> 1.7.9.5
>
> --
> To unsubscribe, send a message with 'unsubscribe linux-mm' in
> the body to majordomo@kvack.org. For more info on Linux MM,
> see: http://www.linux-mm.org/ .
> Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
--
Leon Romanovsky | Independent Linux Consultant
www.leon.nu | leon@leon.nu
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply
* Re: [PATCH v4] pagemap: switch to the new format and do some cleanup
From: Konstantin Khlebnikov @ 2015-06-17 6:40 UTC (permalink / raw)
To: Andrew Morton
Cc: linux-mm@kvack.org, Mark Williamson, Naoya Horiguchi, Linux API,
Linux Kernel Mailing List, Kirill A. Shutemov
In-Reply-To: <CALYGNiNrEPffQwhjhqB6jor5b8w6BQ=KnAa3LrxQ6QFKERH_mQ@mail.gmail.com>
On Wed, Jun 17, 2015 at 7:59 AM, Konstantin Khlebnikov <koct9i@gmail.com> wrote:
> On Wed, Jun 17, 2015 at 12:29 AM, Andrew Morton
> <akpm@linux-foundation.org> wrote:
>> On Mon, 15 Jun 2015 08:56:49 +0300 Konstantin Khlebnikov <koct9i@gmail.com> wrote:
>>
>>> This patch removes page-shift bits (scheduled to remove since 3.11) and
>>> completes migration to the new bit layout. Also it cleans messy macro.
>>
>> hm, I can't find any kernel version to which this patch comes close to
>> applying.
>
> This patchset applies to 4.1-rc8 and current mmotm without problems.
> I guess you've tried pick this patch alone without previous changes.
My bad. I've sent single v4 patch as a reply to v3 patch and forget
'4/4' in subject.
That's fourth patch in patchset.
Here is v3 patchset cover letter: https://lkml.org/lkml/2015/6/9/804
"[PATCHSET v3 0/4] pagemap: make useable for non-privilege users"
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply
* Re: [PATCH] selftests: add seccomp suite
From: Michael Ellerman @ 2015-06-17 7:31 UTC (permalink / raw)
To: Kees Cook
Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA, Daniel Borkmann, Shuah Khan,
Andy Lutomirski, Will Drewry, Andrew Morton, Greg KH,
Mauro Carvalho Chehab, David S. Miller, Arnd Bergmann,
Joe Perches, Jingoo Han, linux-api-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20150616175414.GA24958-0X9Bc/hWBUTk6RaD4rd5nQ@public.gmane.org>
On Tue, 2015-06-16 at 10:54 -0700, Kees Cook wrote:
> This imports the existing seccomp test suite into the kernel's selftests
> tree. It contains extensive testing of seccomp features and corner cases.
> There remain additional tests to move into the kernel tree, but they have
> not yet been ported to all the architectures seccomp supports:
> https://github.com/redpig/seccomp/tree/master/tests
>
> Signed-off-by: Kees Cook <keescook-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>
> ---
> MAINTAINERS | 1 +
> tools/testing/selftests/Makefile | 1 +
> tools/testing/selftests/seccomp/.gitignore | 1 +
> tools/testing/selftests/seccomp/Makefile | 10 +
> tools/testing/selftests/seccomp/seccomp_bpf.c | 2109 ++++++++++++++++++++++++
> tools/testing/selftests/seccomp/test_harness.h | 537 ++++++
Thanks very much for adding this, it would have been very helpful recently when
I was trying to get seccomp filter working on powerpc :)
I get one failure in TRACE_syscall.syscall_dropped:
seccomp_bpf.c:1394:TRACE_syscall.syscall_dropped:Expected 1 (1) == syscall(207) (18446744073709551615)
So it looks like we're returning -1 instead of 1.
That's probably a bug in our handling of the return value, or maybe an
inconsistency across the arches. I'll try and find time to dig into it.
cheers
^ permalink raw reply
* Re: [PATCH v3 1/4] pagemap: check permissions and capabilities at open time
From: Naoya Horiguchi @ 2015-06-17 7:58 UTC (permalink / raw)
To: Konstantin Khlebnikov
Cc: linux-mm@kvack.org, Andrew Morton, linux-api@vger.kernel.org,
Mark Williamson, linux-kernel@vger.kernel.org, Kirill A. Shutemov
In-Reply-To: <20150609200015.21971.25692.stgit@zurg>
On Tue, Jun 09, 2015 at 11:00:15PM +0300, Konstantin Khlebnikov wrote:
> From: Konstantin Khlebnikov <khlebnikov@yandex-team.ru>
>
> This patch moves permission checks from pagemap_read() into pagemap_open().
>
> Pointer to mm is saved in file->private_data. This reference pins only
> mm_struct itself. /proc/*/mem, maps, smaps already work in the same way.
>
> Signed-off-by: Konstantin Khlebnikov <khlebnikov@yandex-team.ru>
> Link: http://lkml.kernel.org/r/CA+55aFyKpWrt_Ajzh1rzp_GcwZ4=6Y=kOv8hBz172CFJp6L8Tg@mail.gmail.com
Reviewed-by: Naoya Horiguchi <n-horiguchi@ah.jp.nec.com>
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply
* Re: [PATCH v5 04/11] nvmem: Add a simple NVMEM framework for consumers
From: Sascha Hauer @ 2015-06-17 8:00 UTC (permalink / raw)
To: Stephen Boyd
Cc: Srinivas Kandagatla, linux-arm-kernel, devicetree, arnd,
Greg Kroah-Hartman, linux-kernel, pantelis.antoniou, Rob Herring,
Mark Brown, Kumar Gala, mporter, Maxime Ripard, linux-api,
linux-arm-msm
In-Reply-To: <5580A345.30204@codeaurora.org>
On Tue, Jun 16, 2015 at 03:29:25PM -0700, Stephen Boyd wrote:
> On 05/21/2015 09:43 AM, Srinivas Kandagatla wrote:
> > + /* if it's not end on byte boundary */
> > + if ((nbits + bit_offset) % BITS_PER_BYTE) {
> > + /* setup the last byte with msb bits from nvmem */
> > + rc = regmap_raw_read(nvmem->regmap,
> > + cell->offset + cell->bytes - 1, &v, 1);
> > + *p |= GENMASK(7, (nbits + bit_offset) % BITS_PER_BYTE) & v;
> > +
> > + }
> > +
> > + return buf;
> > +}
> > +
> > +/**
> > + * nvmem_cell_write(): Write to a given nvmem cell
>
> This isn't kernel doc notation. It should be like
>
> nvmem_cell_write - Write to a given nvmem cell
Almost. Should be:
nvmem_cell_write() - Write to a given nvmem cell
Sascha
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
^ permalink raw reply
* Re: [PATCH v3 2/4] pagemap: add mmap-exclusive bit for marking pages mapped only here
From: Naoya Horiguchi @ 2015-06-17 8:11 UTC (permalink / raw)
To: Konstantin Khlebnikov
Cc: linux-mm@kvack.org, Andrew Morton, linux-api@vger.kernel.org,
Mark Williamson, linux-kernel@vger.kernel.org, Kirill A. Shutemov
In-Reply-To: <20150609200017.21971.23391.stgit@zurg>
On Tue, Jun 09, 2015 at 11:00:17PM +0300, Konstantin Khlebnikov wrote:
> From: Konstantin Khlebnikov <khlebnikov@yandex-team.ru>
>
> This patch sets bit 56 in pagemap if this page is mapped only once.
> It allows to detect exclusively used pages without exposing PFN:
>
> present file exclusive state
> 0 0 0 non-present
> 1 1 0 file page mapped somewhere else
> 1 1 1 file page mapped only here
> 1 0 0 anon non-CoWed page (shared with parent/child)
> 1 0 1 anon CoWed page (or never forked)
>
> CoWed pages in MAP_FILE|MAP_PRIVATE areas are anon in this context.
>
> Mmap-exclusive bit doesn't reflect potential page-sharing via swapcache:
> page could be mapped once but has several swap-ptes which point to it.
> Application could detect that by swap bit in pagemap entry and touch
> that pte via /proc/pid/mem to get real information.
>
> Signed-off-by: Konstantin Khlebnikov <khlebnikov@yandex-team.ru>
> Link: http://lkml.kernel.org/r/CAEVpBa+_RyACkhODZrRvQLs80iy0sqpdrd0AaP_-tgnX3Y9yNQ@mail.gmail.com
>
> ---
>
> v2:
> * handle transparent huge pages
> * invert bit and rename shared -> exclusive (less confusing name)
> ---
...
> @@ -1119,6 +1122,13 @@ static int pagemap_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end,
> else
> pmd_flags2 = 0;
>
> + if (pmd_present(*pmd)) {
> + struct page *page = pmd_page(*pmd);
> +
> + if (page_mapcount(page) == 1)
> + pmd_flags2 |= __PM_MMAP_EXCLUSIVE;
> + }
> +
Could you do the same thing for huge_pte_to_pagemap_entry(), too?
Thanks,
Naoya Horiguchi
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply
* Re: [RFC v3 1/4] fs: Add generic file system event notifications
From: Beata Michalska @ 2015-06-17 9:22 UTC (permalink / raw)
To: Al Viro
Cc: linux-kernel, linux-fsdevel, linux-api, greg, jack, tytso,
adilger.kernel, hughd, lczerner, hch, linux-ext4, linux-mm,
kyungmin.park, kmpark
In-Reply-To: <20150616162147.GA17109@ZenIV.linux.org.uk>
Hi,
On 06/16/2015 06:21 PM, Al Viro wrote:
> On Tue, Jun 16, 2015 at 03:09:30PM +0200, Beata Michalska wrote:
>> Introduce configurable generic interface for file
>> system-wide event notifications, to provide file
>> systems with a common way of reporting any potential
>> issues as they emerge.
>>
>> The notifications are to be issued through generic
>> netlink interface by newly introduced multicast group.
>>
>> Threshold notifications have been included, allowing
>> triggering an event whenever the amount of free space drops
>> below a certain level - or levels to be more precise as two
>> of them are being supported: the lower and the upper range.
>> The notifications work both ways: once the threshold level
>> has been reached, an event shall be generated whenever
>> the number of available blocks goes up again re-activating
>> the threshold.
>>
>> The interface has been exposed through a vfs. Once mounted,
>> it serves as an entry point for the set-up where one can
>> register for particular file system events.
>
> Hmm...
>
> 1) what happens if two processes write to that file at the same time,
> trying to create an entry for the same fs? WARN_ON() and fail for one
> of them if they race?
>
There are some limits here - I admit. The entries in the config file
might be overwritten at any time - there is no support for multiple
config entries for the same mounted fs. This is mainly due to the threshold
notifications: handling potentially numerous threshold limits each time
the number of available blocks changes didn't seem like a good idea.
So this is more like a global config, resembling sysfs fs-related tune options.
> 2) what happens if fs is mounted more than once (e.g. in different
> namespaces, or bound at different mountpoints, or just plain mounted
> several times in different places) and we add an event for each?
> More specifically, what should happen when one of those gets unmounted?
>
Each write to that file is being handled within the current namespace.
Setting up an entry for a mount point from a different mnt namespace
needs switching to that ns. As for bound mounts: the entry exists
until the mount point it has been registered with is detached.
The events can only be registered for one of the mount points,
as they are tied with the super
block - so one cannot have a separate
config entry for each bound mounts.
> 3) what's the meaning of ->active? Is that "fs_drop_trace_entry() hadn't
> been called yet" flag? Unless I'm misreading it, we can very well get
> explicit removal race with umount, resulting in cleanup_mnt() returning
> from fs_event_mount_dropped() before the first process (i.e. write
> asking to remove that entry) gets around to its deactivate_super(),
> ending up with umount(2) on a filesystem that isn't mounted anywhere
> else reporting success to userland before the actual fs shutdown, which
> is not a nice thing to do...
>
The 'active' means simply that the entry for a given mounted fs
is still
valid in a way that the events are still required: the entry
in the config file
has not been removed. When the trace is
being removed
- it's 'active' filed gets invalidated to mark that the events for related
fs are no longer needed. deactivate_super() should get called only once,
dropping the
reference acquired while creating the entry (fs_new_trace_entry).
While in fs_drop_trace_entry, lock is being held (in both cases: unmount and
explicit
entry removal). The fs_drop_trace_entry will silently skip all
the clean-up if the
entry is inactive. I might be missing smth here - though.
If so,I would really appreciate some more of your comments.
> 4) test in fs_event_mount_dropped() looks very odd - by that point we
> are absolutely guaranteed to have ->mnt_ns == NULL. What's that supposed
> to do?
>
I have totally missed the fact that the mnt namespace pointer is invalidated
during unmount_tree - cannot really explain why that did happen. So thank You
for pointing that out.
This should be simply checking if it's still valid.
This verification is
needed in case the mount that is being detached is not
the one the events have
been registered with as they refer to fs not a particular
mount point. This is
the case with the mnt namespaces: let's assume one registers
for events for
particular mounted fs in an init mnt namespace, then the new mnt
namespace is
being created with shared moutn points being cloned: so the same
mount point
exists in both namespaces. Now if this mnt point gets detached:
either through
umount or during the mnt namespace being swept out - the entry
in the init mnt
namespace should remain untouched - same applies the other way round.
>
> Al, trying to figure out the lifetime rules in all of that...
>
Best Regards
Beata
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply
* Re: [RFC v3 4/4] shmem: Add support for generic FS events
From: Beata Michalska @ 2015-06-17 9:23 UTC (permalink / raw)
To: Leon Romanovsky
Cc: linux-kernel@vger.kernel.org, Linux-FSDevel, linux-api,
Greg Kroah, jack, tytso, adilger.kernel, Hugh Dickins, lczerner,
hch, linux-ext4, Linux-MM, kyungmin.park, kmpark
In-Reply-To: <CALq1K=L-DWP5avgXtc0p5=D_M8tXm+Y45DphP7G9QBYo-5sXFA@mail.gmail.com>
On 06/17/2015 08:08 AM, Leon Romanovsky wrote:
>> }
>> - if (error == -ENOSPC && !once++) {
>> + if (error == -ENOSPC) {
>> + if (!once++) {
>> info = SHMEM_I(inode);
>> spin_lock(&info->lock);
>> shmem_recalc_inode(inode);
>> spin_unlock(&info->lock);
>> goto repeat;
>> + } else {
>> + fs_event_notify(inode->i_sb, FS_WARN_ENOSPC);
>> + }
>> }
>
> Very minor remark, please fix indentation.
>
I will, thank You.
BR
Beata
^ permalink raw reply
* Re: [RFC v3 3/4] ext4: Add support for generic FS events
From: Beata Michalska @ 2015-06-17 9:25 UTC (permalink / raw)
To: Leon Romanovsky
Cc: linux-kernel@vger.kernel.org, Linux-FSDevel, linux-api,
Greg Kroah, jack, tytso, adilger.kernel, Hugh Dickins, lczerner,
hch, linux-ext4, Linux-MM, kyungmin.park, kmpark
In-Reply-To: <CALq1K=KUOmV21djY4d818744WaKSqH7Bbvwu4SHJxgWYR4nUkA@mail.gmail.com>
On 06/17/2015 08:15 AM, Leon Romanovsky wrote:
> On Tue, Jun 16, 2015 at 4:09 PM, Beata Michalska
> <b.michalska@samsung.com> wrote:
>> Add support for generic FS events including threshold
>> notifications, ENOSPC and remount as read-only warnings,
>> along with generic internal warnings/errors.
>>
>> Signed-off-by: Beata Michalska <b.michalska@samsung.com>
>> ---
>> fs/ext4/balloc.c | 10 ++++++++--
>> fs/ext4/ext4.h | 1 +
>> fs/ext4/inode.c | 2 +-
>> fs/ext4/mballoc.c | 6 +++++-
>> fs/ext4/resize.c | 1 +
>> fs/ext4/super.c | 39 +++++++++++++++++++++++++++++++++++++++
>> 6 files changed, 55 insertions(+), 4 deletions(-)
>>
>> diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c
>> index e95b27a..a48450f 100644
>> --- a/fs/ext4/balloc.c
>> +++ b/fs/ext4/balloc.c
>> @@ -569,6 +569,7 @@ int ext4_claim_free_clusters(struct ext4_sb_info *sbi,
>> {
>> if (ext4_has_free_clusters(sbi, nclusters, flags)) {
>> percpu_counter_add(&sbi->s_dirtyclusters_counter, nclusters);
>> + fs_event_alloc_space(sbi->s_sb, EXT4_C2B(sbi, nclusters));
>> return 0;
>> } else
>> return -ENOSPC;
> Do you need to add "fs_event_notify(sb, FS_WARN_ENOSPC);" here too?
Yeap, I've missed that one.
Thank You.
BR
Beata
>
>> @@ -590,9 +591,10 @@ int ext4_should_retry_alloc(struct super_block *sb, int *retries)
>> {
>> if (!ext4_has_free_clusters(EXT4_SB(sb), 1, 0) ||
>> (*retries)++ > 3 ||
>> - !EXT4_SB(sb)->s_journal)
>> + !EXT4_SB(sb)->s_journal) {
>> + fs_event_notify(sb, FS_WARN_ENOSPC);
>> return 0;
>> -
>> + }
>> jbd_debug(1, "%s: retrying operation after ENOSPC\n", sb->s_id);
>>
>> return jbd2_journal_force_commit_nested(EXT4_SB(sb)->s_journal);
>> @@ -637,6 +639,10 @@ ext4_fsblk_t ext4_new_meta_blocks(handle_t *handle, struct inode *inode,
>> dquot_alloc_block_nofail(inode,
>> EXT4_C2B(EXT4_SB(inode->i_sb), ar.len));
>> }
>> +
>> + if (*errp == -ENOSPC)
>> + fs_event_notify(inode->i_sb, FS_WARN_ENOSPC_META);
>> +
>> return ret;
>> }
>>
>> diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
>> index 163afe2..7d75ff9 100644
>> --- a/fs/ext4/ext4.h
>> +++ b/fs/ext4/ext4.h
>> @@ -2542,6 +2542,7 @@ void ext4_mark_group_corrupted(struct ext4_sb_info *sbi,
>> if (!EXT4_MB_GRP_BBITMAP_CORRUPT(grp))
>> percpu_counter_sub(&sbi->s_freeclusters_counter, grp->bb_free);
>> set_bit(EXT4_GROUP_INFO_BBITMAP_CORRUPT_BIT, &grp->bb_state);
>> + fs_event_alloc_space(sbi->s_sb, EXT4_C2B(sbi, grp->bb_free));
>> }
>>
>> /*
>> diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
>> index 5cb9a21..2a7af0f 100644
>> --- a/fs/ext4/inode.c
>> +++ b/fs/ext4/inode.c
>> @@ -1238,7 +1238,7 @@ static void ext4_da_release_space(struct inode *inode, int to_free)
>> percpu_counter_sub(&sbi->s_dirtyclusters_counter, to_free);
>>
>> spin_unlock(&EXT4_I(inode)->i_block_reservation_lock);
>> -
>> + fs_event_free_space(sbi->s_sb, to_free);
>> dquot_release_reservation_block(inode, EXT4_C2B(sbi, to_free));
>> }
>>
>> diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
>> index 24a4b6d..c2df6f0 100644
>> --- a/fs/ext4/mballoc.c
>> +++ b/fs/ext4/mballoc.c
>> @@ -4511,6 +4511,9 @@ out:
>> kmem_cache_free(ext4_ac_cachep, ac);
>> if (inquota && ar->len < inquota)
>> dquot_free_block(ar->inode, EXT4_C2B(sbi, inquota - ar->len));
>> + if (reserv_clstrs && ar->len < reserv_clstrs)
>> + fs_event_free_space(sbi->s_sb,
>> + EXT4_C2B(sbi, reserv_clstrs - ar->len));
>> if (!ar->len) {
>> if ((ar->flags & EXT4_MB_DELALLOC_RESERVED) == 0)
>> /* release all the reserved blocks if non delalloc */
>> @@ -4848,7 +4851,7 @@ do_more:
>> if (!(flags & EXT4_FREE_BLOCKS_NO_QUOT_UPDATE))
>> dquot_free_block(inode, EXT4_C2B(sbi, count_clusters));
>> percpu_counter_add(&sbi->s_freeclusters_counter, count_clusters);
>> -
>> + fs_event_free_space(sb, EXT4_C2B(sbi, count_clusters));
>> ext4_mb_unload_buddy(&e4b);
>>
>> /* We dirtied the bitmap block */
>> @@ -4982,6 +4985,7 @@ int ext4_group_add_blocks(handle_t *handle, struct super_block *sb,
>> ext4_unlock_group(sb, block_group);
>> percpu_counter_add(&sbi->s_freeclusters_counter,
>> EXT4_NUM_B2C(sbi, blocks_freed));
>> + fs_event_free_space(sb, blocks_freed);
>>
>> if (sbi->s_log_groups_per_flex) {
>> ext4_group_t flex_group = ext4_flex_group(sbi, block_group);
>> diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c
>> index 8a8ec62..dbf08d6 100644
>> --- a/fs/ext4/resize.c
>> +++ b/fs/ext4/resize.c
>> @@ -1378,6 +1378,7 @@ static void ext4_update_super(struct super_block *sb,
>> EXT4_NUM_B2C(sbi, free_blocks));
>> percpu_counter_add(&sbi->s_freeinodes_counter,
>> EXT4_INODES_PER_GROUP(sb) * flex_gd->count);
>> + fs_event_free_space(sb, free_blocks - reserved_blocks);
>>
>> ext4_debug("free blocks count %llu",
>> percpu_counter_read(&sbi->s_freeclusters_counter));
>> diff --git a/fs/ext4/super.c b/fs/ext4/super.c
>> index e061e66..108b667 100644
>> --- a/fs/ext4/super.c
>> +++ b/fs/ext4/super.c
>> @@ -585,6 +585,8 @@ void __ext4_abort(struct super_block *sb, const char *function,
>> if (EXT4_SB(sb)->s_journal)
>> jbd2_journal_abort(EXT4_SB(sb)->s_journal, -EIO);
>> save_error_info(sb, function, line);
>> + fs_event_notify(sb, FS_ERR_REMOUNT_RO);
>> +
>> }
>> if (test_opt(sb, ERRORS_PANIC))
>> panic("EXT4-fs panic from previous error\n");
>> @@ -1083,6 +1085,12 @@ static const struct quotactl_ops ext4_qctl_operations = {
>> };
>> #endif
>>
>> +static void ext4_trace_query(struct super_block *sb, u64 *ncount);
>> +
>> +static const struct fs_trace_operations ext4_trace_ops = {
>> + .query = ext4_trace_query,
>> +};
>> +
>> static const struct super_operations ext4_sops = {
>> .alloc_inode = ext4_alloc_inode,
>> .destroy_inode = ext4_destroy_inode,
>> @@ -3398,11 +3406,20 @@ static int ext4_reserve_clusters(struct ext4_sb_info *sbi, ext4_fsblk_t count)
>> {
>> ext4_fsblk_t clusters = ext4_blocks_count(sbi->s_es) >>
>> sbi->s_cluster_bits;
>> + ext4_fsblk_t current_resv;
>>
>> if (count >= clusters)
>> return -EINVAL;
>>
>> + current_resv = atomic64_read(&sbi->s_resv_clusters);
>> atomic64_set(&sbi->s_resv_clusters, count);
>> +
>> + if (count > current_resv)
>> + fs_event_alloc_space(sbi->s_sb,
>> + EXT4_C2B(sbi, count - current_resv));
>> + else
>> + fs_event_free_space(sbi->s_sb,
>> + EXT4_C2B(sbi, current_resv - count));
>> return 0;
>> }
>>
>> @@ -3966,6 +3983,9 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
>> sb->s_qcop = &ext4_qctl_operations;
>> sb->s_quota_types = QTYPE_MASK_USR | QTYPE_MASK_GRP;
>> #endif
>> + sb->s_etrace.ops = &ext4_trace_ops;
>> + sb->s_etrace.events_cap_mask = FS_EVENTS_ALL;
>> +
>> memcpy(sb->s_uuid, es->s_uuid, sizeof(es->s_uuid));
>>
>> INIT_LIST_HEAD(&sbi->s_orphan); /* unlinked but open files */
>> @@ -5438,6 +5458,25 @@ out:
>>
>> #endif
>>
>> +static void ext4_trace_query(struct super_block *sb, u64 *ncount)
>> +{
>> + struct ext4_sb_info *sbi = EXT4_SB(sb);
>> + struct ext4_super_block *es = sbi->s_es;
>> + ext4_fsblk_t rsv_blocks;
>> + ext4_fsblk_t nblocks;
>> +
>> + nblocks = percpu_counter_sum_positive(&sbi->s_freeclusters_counter) -
>> + percpu_counter_sum_positive(&sbi->s_dirtyclusters_counter);
>> + nblocks = EXT4_C2B(sbi, nblocks);
>> + rsv_blocks = ext4_r_blocks_count(es) +
>> + EXT4_C2B(sbi, atomic64_read(&sbi->s_resv_clusters));
>> + if (nblocks < rsv_blocks)
>> + nblocks = 0;
>> + else
>> + nblocks -= rsv_blocks;
>> + *ncount = nblocks;
>> +}
>> +
>> static struct dentry *ext4_mount(struct file_system_type *fs_type, int flags,
>> const char *dev_name, void *data)
>> {
>> --
>> 1.7.9.5
>>
>> --
>> To unsubscribe, send a message with 'unsubscribe linux-mm' in
>> the body to majordomo@kvack.org. For more info on Linux MM,
>> see: http://www.linux-mm.org/ .
>> Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
>
>
>
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply
* Re: [PATCH v6 17/21] libnvdimm: infrastructure for btt devices
From: Christoph Hellwig @ 2015-06-17 10:49 UTC (permalink / raw)
To: Dan Williams
Cc: linux-nvdimm-hn68Rpc1hR1g9hUCZPvPmw, axboe-tSWWG44O7X1aa/9Udqfwiw,
sfr-3FnU+UHB4dNDw9hX6IcOSA, rafael-DgEjT+Ai2ygdnm+yROfE0A,
neilb-l3A5Bk7waGM, gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, mingo-DgEjT+Ai2ygdnm+yROfE0A,
linux-acpi-u79uwXL29TY76Z2rM5mHXA, jmoyer-H+wXaHxf7aLQT0dZR+AlfA,
linux-api-u79uwXL29TY76Z2rM5mHXA,
akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b, hch-jcswGhMUV9g
In-Reply-To: <20150611201142.25175.66768.stgit-p8uTFz9XbKj2zm6wflaqv1nYeNYlB/vhral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
The block change need to be a separate patch. They should go in through
Jens tree or at least get an ACK from him.
^ permalink raw reply
* Re: [PATCH v6 00/21] libnvdimm: non-volatile memory devices
From: Christoph Hellwig @ 2015-06-17 11:26 UTC (permalink / raw)
To: Dan Williams
Cc: linux-nvdimm, Boaz Harrosh, rafael, neilb, Dave Chinner, Lv Zheng,
H. Peter Anvin, hch, sfr, Rafael J. Wysocki, Robert Moore, mingo,
linux-acpi, jmoyer, Nicholas Moulin, Matthew Wilcox, Ross Zwisler,
Vishal Verma, Jens Axboe, Borislav Petkov, Thomas Gleixner, axboe,
gregkh, linux-kernel, Andy Lutomirski, linux-api, akpm,
Linus Torvalds
In-Reply-To: <20150611183830.25175.51256.stgit@dwillia2-desk3.amr.corp.intel.com>
Still not a big fan of the spec, but I guess this is a mosly reasonable
implementation now.
So for patches 1-16:
Acked-by: Christoph Hellwig <hch@lst.de>
The btt integration still needs a proper patch split and review, and
I still detest the mess with the test moduly by heart.
^ permalink raw reply
* Re: [RFC PATCH 00/18] kthreads/signal: Safer kthread API and signal handling
From: Christoph Hellwig @ 2015-06-17 11:34 UTC (permalink / raw)
To: Petr Mladek
Cc: Andrew Morton, Oleg Nesterov, Tejun Heo, Ingo Molnar,
Peter Zijlstra, Richard Weinberger, Steven Rostedt,
David Woodhouse, linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
Trond Myklebust, Anna Schumaker, linux-nfs-u79uwXL29TY76Z2rM5mHXA,
Chris Mason, Paul E. McKenney, Thomas Gleixner, Linus Torvalds,
Jiri Kosina, Borislav Petkov, Michal Hocko,
live-patching-u79uwXL29TY76Z2rM5mHXA,
linux-api-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1433516477-5153-1-git-send-email-pmladek-AlSwsSmVLrQ@public.gmane.org>
On Fri, Jun 05, 2015 at 05:00:59PM +0200, Petr Mladek wrote:
> Kthreads are implemented as an infinite loop. They include check points
> for termination, freezer, parking, and even signal handling.
>
> We need to touch all kthreads every time we want to add or
> modify the behavior of such checkpoints. It is not easy because
> there are several hundreds of kthreads and each of them is
> implemented in a slightly different way.
>
> This anarchy brings potentially broken or non-standard behavior.
> For example, few kthreads already handle signals a strange way.
>
>
> This patchset is a _proof-of-concept_ how to improve the situation.
Maybe it might be a better idea to audit the existing callers of
signals for kthreads and first check if we can get rid of them. Then
as a second step if any are left convert them to signalfd-style
operation where signals aren't checked synchronously but as something
the threads can consume on a as needed basis.
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH 1/3 v19 for 4.2] sys_membarrier(): system-wide memory barrier (generic, x86)
From: Mathieu Desnoyers @ 2015-06-17 12:10 UTC (permalink / raw)
To: Andrew Morton
Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA, Mathieu Desnoyers,
KOSAKI Motohiro, Steven Rostedt, Nicholas Miell, Linus Torvalds,
Ingo Molnar, Alan Cox, Lai Jiangshan, Stephen Hemminger,
Thomas Gleixner, Peter Zijlstra, David Howells, Pranith Kumar,
Michael Kerrisk, linux-api-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1434543047-7015-1-git-send-email-mathieu.desnoyers-vg+e7yoeK/dWk0Htik3J/w@public.gmane.org>
Here is an implementation of a new system call, sys_membarrier(), which
executes a memory barrier on all threads running on the system. It is
implemented by calling synchronize_sched(). It can be used to distribute
the cost of user-space memory barriers asymmetrically by transforming
pairs of memory barriers into pairs consisting of sys_membarrier() and a
compiler barrier. For synchronization primitives that distinguish
between read-side and write-side (e.g. userspace RCU [1], rwlocks), the
read-side can be accelerated significantly by moving the bulk of the
memory barrier overhead to the write-side.
The existing applications of which I am aware that would be improved by this
system call are as follows:
* Through Userspace RCU library (http://urcu.so)
- DNS server (Knot DNS) https://www.knot-dns.cz/
- Network sniffer (http://netsniff-ng.org/)
- Distributed object storage (https://sheepdog.github.io/sheepdog/)
- User-space tracing (http://lttng.org)
- Network storage system (https://www.gluster.org/)
- Virtual routers (https://events.linuxfoundation.org/sites/events/files/slides/DPDK_RCU_0MQ.pdf)
- Financial software (https://lkml.org/lkml/2015/3/23/189)
Those projects use RCU in userspace to increase read-side speed and
scalability compared to locking. Especially in the case of RCU used
by libraries, sys_membarrier can speed up the read-side by moving the
bulk of the memory barrier cost to synchronize_rcu().
* Direct users of sys_membarrier
- core dotnet garbage collector (https://github.com/dotnet/coreclr/issues/198)
Microsoft core dotnet GC developers are planning to use the mprotect()
side-effect of issuing memory barriers through IPIs as a way to implement
Windows FlushProcessWriteBuffers() on Linux. They are referring to
sys_membarrier in their github thread, specifically stating that
sys_membarrier() is what they are looking for.
This implementation is based on kernel v4.1-rc8.
To explain the benefit of this scheme, let's introduce two example threads:
Thread A (non-frequent, e.g. executing liburcu synchronize_rcu())
Thread B (frequent, e.g. executing liburcu
rcu_read_lock()/rcu_read_unlock())
In a scheme where all smp_mb() in thread A are ordering memory accesses
with respect to smp_mb() present in Thread B, we can change each
smp_mb() within Thread A into calls to sys_membarrier() and each
smp_mb() within Thread B into compiler barriers "barrier()".
Before the change, we had, for each smp_mb() pairs:
Thread A Thread B
previous mem accesses previous mem accesses
smp_mb() smp_mb()
following mem accesses following mem accesses
After the change, these pairs become:
Thread A Thread B
prev mem accesses prev mem accesses
sys_membarrier() barrier()
follow mem accesses follow mem accesses
As we can see, there are two possible scenarios: either Thread B memory
accesses do not happen concurrently with Thread A accesses (1), or they
do (2).
1) Non-concurrent Thread A vs Thread B accesses:
Thread A Thread B
prev mem accesses
sys_membarrier()
follow mem accesses
prev mem accesses
barrier()
follow mem accesses
In this case, thread B accesses will be weakly ordered. This is OK,
because at that point, thread A is not particularly interested in
ordering them with respect to its own accesses.
2) Concurrent Thread A vs Thread B accesses
Thread A Thread B
prev mem accesses prev mem accesses
sys_membarrier() barrier()
follow mem accesses follow mem accesses
In this case, thread B accesses, which are ensured to be in program
order thanks to the compiler barrier, will be "upgraded" to full
smp_mb() by synchronize_sched().
* Benchmarks
On Intel Xeon E5405 (8 cores)
(one thread is calling sys_membarrier, the other 7 threads are busy
looping)
1000 non-expedited sys_membarrier calls in 33s = 33 milliseconds/call.
* User-space user of this system call: Userspace RCU library
Both the signal-based and the sys_membarrier userspace RCU schemes
permit us to remove the memory barrier from the userspace RCU
rcu_read_lock() and rcu_read_unlock() primitives, thus significantly
accelerating them. These memory barriers are replaced by compiler
barriers on the read-side, and all matching memory barriers on the
write-side are turned into an invocation of a memory barrier on all
active threads in the process. By letting the kernel perform this
synchronization rather than dumbly sending a signal to every process
threads (as we currently do), we diminish the number of unnecessary wake
ups and only issue the memory barriers on active threads. Non-running
threads do not need to execute such barrier anyway, because these are
implied by the scheduler context switches.
Results in liburcu:
Operations in 10s, 6 readers, 2 writers:
memory barriers in reader: 1701557485 reads, 2202847 writes
signal-based scheme: 9830061167 reads, 6700 writes
sys_membarrier: 9952759104 reads, 425 writes
sys_membarrier (dyn. check): 7970328887 reads, 425 writes
The dynamic sys_membarrier availability check adds some overhead to
the read-side compared to the signal-based scheme, but besides that,
sys_membarrier slightly outperforms the signal-based scheme. However,
this non-expedited sys_membarrier implementation has a much slower grace
period than signal and memory barrier schemes.
Besides diminishing the number of wake-ups, one major advantage of the
membarrier system call over the signal-based scheme is that it does not
need to reserve a signal. This plays much more nicely with libraries,
and with processes injected into for tracing purposes, for which we
cannot expect that signals will be unused by the application.
An expedited version of this system call can be added later on to speed
up the grace period. Its implementation will likely depend on reading
the cpu_curr()->mm without holding each CPU's rq lock.
This patch adds the system call to x86 and to asm-generic.
[1] http://urcu.so
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers-vg+e7yoeK/dWk0Htik3J/w@public.gmane.org>
Reviewed-by: Paul E. McKenney <paulmck-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
Reviewed-by: Josh Triplett <josh-iaAMLnmF4UmaiuxdJuQwMA@public.gmane.org>
CC: KOSAKI Motohiro <kosaki.motohiro-+CUm20s59erQFUHtdCDX3A@public.gmane.org>
CC: Steven Rostedt <rostedt-nx8X9YLhiw1AfugRpC6u6w@public.gmane.org>
CC: Nicholas Miell <nmiell-Wuw85uim5zDR7s880joybQ@public.gmane.org>
CC: Linus Torvalds <torvalds-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b@public.gmane.org>
CC: Ingo Molnar <mingo-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
CC: Alan Cox <gnomes-qBU/x9rampVanCEyBjwyrvXRex20P6io@public.gmane.org>
CC: Lai Jiangshan <laijs-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
CC: Stephen Hemminger <stephen-OTpzqLSitTUnbdJkjeBofR2eb7JE58TQ@public.gmane.org>
CC: Andrew Morton <akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b@public.gmane.org>
CC: Thomas Gleixner <tglx-hfZtesqFncYOwBW4kG4KsQ@public.gmane.org>
CC: Peter Zijlstra <peterz-wEGCiKHe2LqWVfeAwA7xHQ@public.gmane.org>
CC: David Howells <dhowells-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
CC: Pranith Kumar <bobby.prani-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
CC: Michael Kerrisk <mtk.manpages-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
CC: linux-api-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
---
membarrier(2) man page:
--------------- snip -------------------
MEMBARRIER(2) Linux Programmer's Manual MEMBARRIER(2)
NAME
membarrier - issue memory barriers on a set of threads
SYNOPSIS
#include <linux/membarrier.h>
int membarrier(int cmd, int flags);
DESCRIPTION
The cmd argument is one of the following:
MEMBARRIER_CMD_QUERY
Query the set of supported commands. It returns a bitmask of
supported commands.
MEMBARRIER_CMD_SHARED
Execute a memory barrier on all threads running on the system.
Upon return from system call, the caller thread is ensured that
all running threads have passed through a state where all memory
accesses to user-space addresses match program order between
entry to and return from the system call (non-running threads
are de facto in such a state). This covers threads from all pro‐
cesses running on the system. This command returns 0.
The flags argument needs to be 0. For future extensions.
All memory accesses performed in program order from each targeted
thread is guaranteed to be ordered with respect to sys_membarrier(). If
we use the semantic "barrier()" to represent a compiler barrier forcing
memory accesses to be performed in program order across the barrier,
and smp_mb() to represent explicit memory barriers forcing full memory
ordering across the barrier, we have the following ordering table for
each pair of barrier(), sys_membarrier() and smp_mb():
The pair ordering is detailed as (O: ordered, X: not ordered):
barrier() smp_mb() sys_membarrier()
barrier() X X O
smp_mb() X O O
sys_membarrier() O O O
RETURN VALUE
On success, these system calls return zero. On error, -1 is returned,
and errno is set appropriately. For a given command, with flags
argument set to 0, this system call is guaranteed to always return the
same value until reboot.
ERRORS
ENOSYS System call is not implemented.
EINVAL Invalid arguments.
Linux 2015-04-15 MEMBARRIER(2)
--------------- snip -------------------
Changes since v18:
- Add unlikely() check to flags,
- Describe current users in changelog.
Changes since v17:
- Update commit message.
Changes since v16:
- Update documentation.
- Add man page to changelog.
- Build sys_membarrier on !CONFIG_SMP. It allows userspace applications
to not care about the number of processors on the system. Based on
recommendations from Stephen Hemminger and Steven Rostedt.
- Check that flags argument is 0, update documentation to require it.
Changes since v15:
- Add flags argument in addition to cmd.
- Update documentation.
Changes since v14:
- Take care of Thomas Gleixner's comments.
Changes since v13:
- Move to kernel/membarrier.c.
- Remove MEMBARRIER_PRIVATE flag.
- Add MAINTAINERS file entry.
Changes since v12:
- Remove _FLAG suffix from uapi flags.
- Add Expert menuconfig option CONFIG_MEMBARRIER (default=y).
- Remove EXPEDITED mode. Only implement non-expedited for now, until
reading the cpu_curr()->mm can be done without holding the CPU's rq
lock.
Changes since v11:
- 5 years have passed.
- Rebase on v3.19 kernel.
- Add futex-alike PRIVATE vs SHARED semantic: private for per-process
barriers, non-private for memory mappings shared between processes.
- Simplify user API.
- Code refactoring.
Changes since v10:
- Apply Randy's comments.
- Rebase on 2.6.34-rc4 -tip.
Changes since v9:
- Clean up #ifdef CONFIG_SMP.
Changes since v8:
- Go back to rq spin locks taken by sys_membarrier() rather than adding
memory barriers to the scheduler. It implies a potential RoS
(reduction of service) if sys_membarrier() is executed in a busy-loop
by a user, but nothing more than what is already possible with other
existing system calls, but saves memory barriers in the scheduler fast
path.
- re-add the memory barrier comments to x86 switch_mm() as an example to
other architectures.
- Update documentation of the memory barriers in sys_membarrier and
switch_mm().
- Append execution scenarios to the changelog showing the purpose of
each memory barrier.
Changes since v7:
- Move spinlock-mb and scheduler related changes to separate patches.
- Add support for sys_membarrier on x86_32.
- Only x86 32/64 system calls are reserved in this patch. It is planned
to incrementally reserve syscall IDs on other architectures as these
are tested.
Changes since v6:
- Remove some unlikely() not so unlikely.
- Add the proper scheduler memory barriers needed to only use the RCU
read lock in sys_membarrier rather than take each runqueue spinlock:
- Move memory barriers from per-architecture switch_mm() to schedule()
and finish_lock_switch(), where they clearly document that all data
protected by the rq lock is guaranteed to have memory barriers issued
between the scheduler update and the task execution. Replacing the
spin lock acquire/release barriers with these memory barriers imply
either no overhead (x86 spinlock atomic instruction already implies a
full mb) or some hopefully small overhead caused by the upgrade of the
spinlock acquire/release barriers to more heavyweight smp_mb().
- The "generic" version of spinlock-mb.h declares both a mapping to
standard spinlocks and full memory barriers. Each architecture can
specialize this header following their own need and declare
CONFIG_HAVE_SPINLOCK_MB to use their own spinlock-mb.h.
- Note: benchmarks of scheduler overhead with specialized spinlock-mb.h
implementations on a wide range of architecture would be welcome.
Changes since v5:
- Plan ahead for extensibility by introducing mandatory/optional masks
to the "flags" system call parameter. Past experience with accept4(),
signalfd4(), eventfd2(), epoll_create1(), dup3(), pipe2(), and
inotify_init1() indicates that this is the kind of thing we want to
plan for. Return -EINVAL if the mandatory flags received are unknown.
- Create include/linux/membarrier.h to define these flags.
- Add MEMBARRIER_QUERY optional flag.
Changes since v4:
- Add "int expedited" parameter, use synchronize_sched() in the
non-expedited case. Thanks to Lai Jiangshan for making us consider
seriously using synchronize_sched() to provide the low-overhead
membarrier scheme.
- Check num_online_cpus() == 1, quickly return without doing nothing.
Changes since v3a:
- Confirm that each CPU indeed runs the current task's ->mm before
sending an IPI. Ensures that we do not disturb RT tasks in the
presence of lazy TLB shootdown.
- Document memory barriers needed in switch_mm().
- Surround helper functions with #ifdef CONFIG_SMP.
Changes since v2:
- simply send-to-many to the mm_cpumask. It contains the list of
processors we have to IPI to (which use the mm), and this mask is
updated atomically.
Changes since v1:
- Only perform the IPI in CONFIG_SMP.
- Only perform the IPI if the process has more than one thread.
- Only send IPIs to CPUs involved with threads belonging to our process.
- Adaptative IPI scheme (single vs many IPI with threshold).
- Issue smp_mb() at the beginning and end of the system call.
---
MAINTAINERS | 8 +++++
arch/x86/syscalls/syscall_32.tbl | 1 +
arch/x86/syscalls/syscall_64.tbl | 1 +
include/linux/syscalls.h | 2 ++
include/uapi/asm-generic/unistd.h | 4 ++-
include/uapi/linux/Kbuild | 1 +
include/uapi/linux/membarrier.h | 53 +++++++++++++++++++++++++++++++
init/Kconfig | 12 +++++++
kernel/Makefile | 1 +
kernel/membarrier.c | 66 +++++++++++++++++++++++++++++++++++++++
kernel/sys_ni.c | 3 ++
11 files changed, 151 insertions(+), 1 deletion(-)
create mode 100644 include/uapi/linux/membarrier.h
create mode 100644 kernel/membarrier.c
diff --git a/MAINTAINERS b/MAINTAINERS
index d8afd29..750a53d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -6387,6 +6387,14 @@ W: http://www.mellanox.com
Q: http://patchwork.ozlabs.org/project/netdev/list/
F: drivers/net/ethernet/mellanox/mlx4/en_*
+MEMBARRIER SUPPORT
+M: Mathieu Desnoyers <mathieu.desnoyers-vg+e7yoeK/dWk0Htik3J/w@public.gmane.org>
+M: "Paul E. McKenney" <paulmck-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
+L: linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
+S: Supported
+F: kernel/membarrier.c
+F: include/uapi/linux/membarrier.h
+
MEMORY MANAGEMENT
L: linux-mm-Bw31MaZKKs3YtjvyW6yDsg@public.gmane.org
W: http://www.linux-mm.org
diff --git a/arch/x86/syscalls/syscall_32.tbl b/arch/x86/syscalls/syscall_32.tbl
index ef8187f..e63ad61 100644
--- a/arch/x86/syscalls/syscall_32.tbl
+++ b/arch/x86/syscalls/syscall_32.tbl
@@ -365,3 +365,4 @@
356 i386 memfd_create sys_memfd_create
357 i386 bpf sys_bpf
358 i386 execveat sys_execveat stub32_execveat
+359 i386 membarrier sys_membarrier
diff --git a/arch/x86/syscalls/syscall_64.tbl b/arch/x86/syscalls/syscall_64.tbl
index 9ef32d5..87f3cd6 100644
--- a/arch/x86/syscalls/syscall_64.tbl
+++ b/arch/x86/syscalls/syscall_64.tbl
@@ -329,6 +329,7 @@
320 common kexec_file_load sys_kexec_file_load
321 common bpf sys_bpf
322 64 execveat stub_execveat
+323 common membarrier sys_membarrier
#
# x32-specific system call numbers start at 512 to avoid cache impact
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index 76d1e38..51a9054 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -884,4 +884,6 @@ asmlinkage long sys_execveat(int dfd, const char __user *filename,
const char __user *const __user *argv,
const char __user *const __user *envp, int flags);
+asmlinkage long sys_membarrier(int cmd, int flags);
+
#endif
diff --git a/include/uapi/asm-generic/unistd.h b/include/uapi/asm-generic/unistd.h
index e016bd9..8da542a 100644
--- a/include/uapi/asm-generic/unistd.h
+++ b/include/uapi/asm-generic/unistd.h
@@ -709,9 +709,11 @@ __SYSCALL(__NR_memfd_create, sys_memfd_create)
__SYSCALL(__NR_bpf, sys_bpf)
#define __NR_execveat 281
__SC_COMP(__NR_execveat, sys_execveat, compat_sys_execveat)
+#define __NR_membarrier 282
+__SYSCALL(__NR_membarrier, sys_membarrier)
#undef __NR_syscalls
-#define __NR_syscalls 282
+#define __NR_syscalls 283
/*
* All syscalls below here should go away really,
diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild
index 1a0006a..7bcc827 100644
--- a/include/uapi/linux/Kbuild
+++ b/include/uapi/linux/Kbuild
@@ -250,6 +250,7 @@ header-y += mdio.h
header-y += media.h
header-y += media-bus-format.h
header-y += mei.h
+header-y += membarrier.h
header-y += memfd.h
header-y += mempolicy.h
header-y += meye.h
diff --git a/include/uapi/linux/membarrier.h b/include/uapi/linux/membarrier.h
new file mode 100644
index 0000000..e0b108b
--- /dev/null
+++ b/include/uapi/linux/membarrier.h
@@ -0,0 +1,53 @@
+#ifndef _UAPI_LINUX_MEMBARRIER_H
+#define _UAPI_LINUX_MEMBARRIER_H
+
+/*
+ * linux/membarrier.h
+ *
+ * membarrier system call API
+ *
+ * Copyright (c) 2010, 2015 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/**
+ * enum membarrier_cmd - membarrier system call command
+ * @MEMBARRIER_CMD_QUERY: Query the set of supported commands. It returns
+ * a bitmask of valid commands.
+ * @MEMBARRIER_CMD_SHARED: Execute a memory barrier on all running threads.
+ * Upon return from system call, the caller thread
+ * is ensured that all running threads have passed
+ * through a state where all memory accesses to
+ * user-space addresses match program order between
+ * entry to and return from the system call
+ * (non-running threads are de facto in such a
+ * state). This covers threads from all processes
+ * running on the system. This command returns 0.
+ *
+ * Command to be passed to the membarrier system call. The commands need to
+ * be a single bit each, except for MEMBARRIER_CMD_QUERY which is assigned to
+ * the value 0.
+ */
+enum membarrier_cmd {
+ MEMBARRIER_CMD_QUERY = 0,
+ MEMBARRIER_CMD_SHARED = (1 << 0),
+};
+
+#endif /* _UAPI_LINUX_MEMBARRIER_H */
diff --git a/init/Kconfig b/init/Kconfig
index dc24dec..307e406 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -1583,6 +1583,18 @@ config PCI_QUIRKS
bugs/quirks. Disable this only if your target machine is
unaffected by PCI quirks.
+config MEMBARRIER
+ bool "Enable membarrier() system call" if EXPERT
+ default y
+ help
+ Enable the membarrier() system call that allows issuing memory
+ barriers across all running threads, which can be used to distribute
+ the cost of user-space memory barriers asymmetrically by transforming
+ pairs of memory barriers into pairs consisting of membarrier() and a
+ compiler barrier.
+
+ If unsure, say Y.
+
config EMBEDDED
bool "Embedded system"
option allnoconfig_y
diff --git a/kernel/Makefile b/kernel/Makefile
index 60c302c..05191fd 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -98,6 +98,7 @@ obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
obj-$(CONFIG_JUMP_LABEL) += jump_label.o
obj-$(CONFIG_CONTEXT_TRACKING) += context_tracking.o
obj-$(CONFIG_TORTURE_TEST) += torture.o
+obj-$(CONFIG_MEMBARRIER) += membarrier.o
$(obj)/configs.o: $(obj)/config_data.h
diff --git a/kernel/membarrier.c b/kernel/membarrier.c
new file mode 100644
index 0000000..536c727
--- /dev/null
+++ b/kernel/membarrier.c
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2010, 2015 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ *
+ * membarrier system call
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/syscalls.h>
+#include <linux/membarrier.h>
+
+/*
+ * Bitmask made from a "or" of all commands within enum membarrier_cmd,
+ * except MEMBARRIER_CMD_QUERY.
+ */
+#define MEMBARRIER_CMD_BITMASK (MEMBARRIER_CMD_SHARED)
+
+/**
+ * sys_membarrier - issue memory barriers on a set of threads
+ * @cmd: Takes command values defined in enum membarrier_cmd.
+ * @flags: Currently needs to be 0. For future extensions.
+ *
+ * If this system call is not implemented, -ENOSYS is returned. If the
+ * command specified does not exist, or if the command argument is invalid,
+ * this system call returns -EINVAL. For a given command, with flags argument
+ * set to 0, this system call is guaranteed to always return the same value
+ * until reboot.
+ *
+ * All memory accesses performed in program order from each targeted thread
+ * is guaranteed to be ordered with respect to sys_membarrier(). If we use
+ * the semantic "barrier()" to represent a compiler barrier forcing memory
+ * accesses to be performed in program order across the barrier, and
+ * smp_mb() to represent explicit memory barriers forcing full memory
+ * ordering across the barrier, we have the following ordering table for
+ * each pair of barrier(), sys_membarrier() and smp_mb():
+ *
+ * The pair ordering is detailed as (O: ordered, X: not ordered):
+ *
+ * barrier() smp_mb() sys_membarrier()
+ * barrier() X X O
+ * smp_mb() X O O
+ * sys_membarrier() O O O
+ */
+SYSCALL_DEFINE2(membarrier, int, cmd, int, flags)
+{
+ if (unlikely(flags))
+ return -EINVAL;
+ switch (cmd) {
+ case MEMBARRIER_CMD_QUERY:
+ return MEMBARRIER_CMD_BITMASK;
+ case MEMBARRIER_CMD_SHARED:
+ if (num_online_cpus() > 1)
+ synchronize_sched();
+ return 0;
+ default:
+ return -EINVAL;
+ }
+}
diff --git a/kernel/sys_ni.c b/kernel/sys_ni.c
index 7995ef5..eb4fde0 100644
--- a/kernel/sys_ni.c
+++ b/kernel/sys_ni.c
@@ -243,3 +243,6 @@ cond_syscall(sys_bpf);
/* execveat */
cond_syscall(sys_execveat);
+
+/* membarrier */
+cond_syscall(sys_membarrier);
--
2.1.4
^ permalink raw reply related
* [PATCH] selftests/kdbus: handle cap_get_proc() error properly
From: Sergei Zviagintsev @ 2015-06-17 14:18 UTC (permalink / raw)
To: Greg Kroah-Hartman, Daniel Mack, David Herrmann, Djalal Harouni
Cc: Shuah Khan, linux-kernel, linux-api, Sergei Zviagintsev
Fix typo in checking error value of cap_get_proc(): cap -> caps
Signed-off-by: Sergei Zviagintsev <sergei@s15v.net>
---
tools/testing/selftests/kdbus/kdbus-util.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/testing/selftests/kdbus/kdbus-util.c b/tools/testing/selftests/kdbus/kdbus-util.c
index 1e267d585a14..a3e49b04f3a7 100644
--- a/tools/testing/selftests/kdbus/kdbus-util.c
+++ b/tools/testing/selftests/kdbus/kdbus-util.c
@@ -1547,7 +1547,7 @@ int test_is_capable(int cap, ...)
cap_t caps;
caps = cap_get_proc();
- if (!cap) {
+ if (!caps) {
ret = -errno;
kdbus_printf("error cap_get_proc(): %d (%m)\n", ret);
return ret;
--
1.8.3.1
^ permalink raw reply related
* [PATCH] selftests/kdbus: drop useless assignment
From: Sergei Zviagintsev @ 2015-06-17 14:18 UTC (permalink / raw)
To: Greg Kroah-Hartman, Daniel Mack, David Herrmann, Djalal Harouni
Cc: Shuah Khan, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-api-u79uwXL29TY76Z2rM5mHXA, Sergei Zviagintsev
Assign returned file descriptor directly to `fd', without intermediate
`ret' variable.
Signed-off-by: Sergei Zviagintsev <sergei-E844GTqJAzo@public.gmane.org>
---
tools/testing/selftests/kdbus/kdbus-util.c | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/tools/testing/selftests/kdbus/kdbus-util.c b/tools/testing/selftests/kdbus/kdbus-util.c
index a3e49b04f3a7..f9102264cfb9 100644
--- a/tools/testing/selftests/kdbus/kdbus-util.c
+++ b/tools/testing/selftests/kdbus/kdbus-util.c
@@ -408,11 +408,9 @@ int sys_memfd_create(const char *name, __u64 size)
{
int ret, fd;
- ret = syscall(__NR_memfd_create, name, MFD_ALLOW_SEALING);
- if (ret < 0)
- return ret;
-
- fd = ret;
+ fd = syscall(__NR_memfd_create, name, MFD_ALLOW_SEALING);
+ if (fd < 0)
+ return fd;
ret = ftruncate(fd, size);
if (ret < 0) {
--
1.8.3.1
^ permalink raw reply related
* [PATCH] selftests/kdbus: remove useless initializations from kdbus_clone_userns_test()
From: Sergei Zviagintsev @ 2015-06-17 14:18 UTC (permalink / raw)
To: Greg Kroah-Hartman, Daniel Mack, David Herrmann, Djalal Harouni
Cc: Shuah Khan, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-api-u79uwXL29TY76Z2rM5mHXA, Sergei Zviagintsev
Do not initialize efd, unpriv_conn_id, userns_conn_id and monitor. These
vars are assigned to values later in code while initial values are never
used.
Signed-off-by: Sergei Zviagintsev <sergei-E844GTqJAzo@public.gmane.org>
---
tools/testing/selftests/kdbus/test-metadata-ns.c | 9 +++------
1 file changed, 3 insertions(+), 6 deletions(-)
diff --git a/tools/testing/selftests/kdbus/test-metadata-ns.c b/tools/testing/selftests/kdbus/test-metadata-ns.c
index 2cb1d4d2a5be..ccdfae06922b 100644
--- a/tools/testing/selftests/kdbus/test-metadata-ns.c
+++ b/tools/testing/selftests/kdbus/test-metadata-ns.c
@@ -281,16 +281,13 @@ out:
static int kdbus_clone_userns_test(const char *bus,
struct kdbus_conn *conn)
{
- int ret;
- int status;
- int efd = -1;
+ int ret, status, efd;
pid_t pid, ppid;
- uint64_t unpriv_conn_id = 0;
- uint64_t userns_conn_id = 0;
+ uint64_t unpriv_conn_id, userns_conn_id;
struct kdbus_msg *msg;
const struct kdbus_item *item;
struct kdbus_pids expected_pids;
- struct kdbus_conn *monitor = NULL;
+ struct kdbus_conn *monitor;
kdbus_printf("STARTING TEST 'metadata-ns'.\n");
--
1.8.3.1
^ permalink raw reply related
* [PATCH] selftests/kdbus: drop duplicated code from __kdbus_msg_send()
From: Sergei Zviagintsev @ 2015-06-17 14:18 UTC (permalink / raw)
To: Greg Kroah-Hartman, Daniel Mack, David Herrmann, Djalal Harouni
Cc: Shuah Khan, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-api-u79uwXL29TY76Z2rM5mHXA, Sergei Zviagintsev
Set value of `size' in one step instead of four.
Signed-off-by: Sergei Zviagintsev <sergei-E844GTqJAzo@public.gmane.org>
---
tools/testing/selftests/kdbus/kdbus-util.c | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/tools/testing/selftests/kdbus/kdbus-util.c b/tools/testing/selftests/kdbus/kdbus-util.c
index f9102264cfb9..ae81da63d810 100644
--- a/tools/testing/selftests/kdbus/kdbus-util.c
+++ b/tools/testing/selftests/kdbus/kdbus-util.c
@@ -462,10 +462,7 @@ static int __kdbus_msg_send(const struct kdbus_conn *conn,
int memfd = -1;
int ret;
- size = sizeof(*msg);
- size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_vec));
- size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_vec));
- size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_vec));
+ size = sizeof(*msg) + 3 * KDBUS_ITEM_SIZE(sizeof(struct kdbus_vec));
if (dst_id == KDBUS_DST_ID_BROADCAST)
size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_bloom_filter)) + 64;
--
1.8.3.1
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox