* Re: [RFC v2 1/4] fs: Add generic file system event notifications
From: Beata Michalska @ 2015-04-28 14:46 UTC (permalink / raw)
To: Greg KH
Cc: Jan Kara, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
linux-api-u79uwXL29TY76Z2rM5mHXA, tytso-3s7WtUTddSA,
adilger.kernel-m1MBpc4rdrD3fQ9qLvQP4Q,
hughd-hpIqsD4AKlfQT0dZR+AlfA, lczerner-H+wXaHxf7aLQT0dZR+AlfA,
hch-wEGCiKHe2LqWVfeAwA7xHQ, linux-ext4-u79uwXL29TY76Z2rM5mHXA,
linux-mm-Bw31MaZKKs3YtjvyW6yDsg,
kyungmin.park-Sze3O3UU22JBDgjK7y7TUQ,
kmpark-wEGCiKHe2LqWVfeAwA7xHQ
In-Reply-To: <20150428140936.GA13406-U8xfFu+wG4EAvxtiuMwx3w@public.gmane.org>
On 04/28/2015 04:09 PM, Greg KH wrote:
> On Tue, Apr 28, 2015 at 03:56:53PM +0200, Jan Kara wrote:
>> On Mon 27-04-15 17:37:11, Greg KH wrote:
>>> On Mon, Apr 27, 2015 at 05:08:27PM +0200, Beata Michalska wrote:
>>>> On 04/27/2015 04:24 PM, Greg KH wrote:
>>>>> On Mon, Apr 27, 2015 at 01:51:41PM +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.
>>>>>>
>>>>>> Signed-off-by: Beata Michalska <b.michalska-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
>>>>>> ---
>>>>>> Documentation/filesystems/events.txt | 231 ++++++++++
>>>>>> fs/Makefile | 1 +
>>>>>> fs/events/Makefile | 6 +
>>>>>> fs/events/fs_event.c | 770 ++++++++++++++++++++++++++++++++++
>>>>>> fs/events/fs_event.h | 25 ++
>>>>>> fs/events/fs_event_netlink.c | 99 +++++
>>>>>> fs/namespace.c | 1 +
>>>>>> include/linux/fs.h | 6 +-
>>>>>> include/linux/fs_event.h | 58 +++
>>>>>> include/uapi/linux/fs_event.h | 54 +++
>>>>>> include/uapi/linux/genetlink.h | 1 +
>>>>>> net/netlink/genetlink.c | 7 +-
>>>>>> 12 files changed, 1257 insertions(+), 2 deletions(-)
>>>>>> create mode 100644 Documentation/filesystems/events.txt
>>>>>> create mode 100644 fs/events/Makefile
>>>>>> create mode 100644 fs/events/fs_event.c
>>>>>> create mode 100644 fs/events/fs_event.h
>>>>>> create mode 100644 fs/events/fs_event_netlink.c
>>>>>> create mode 100644 include/linux/fs_event.h
>>>>>> create mode 100644 include/uapi/linux/fs_event.h
>>>>>
>>>>> Any reason why you just don't do uevents for the block devices today,
>>>>> and not create a new type of netlink message and userspace tool required
>>>>> to read these?
>>>>
>>>> The idea here is to have support for filesystems with no backing device as well.
>>>> Parsing the message with libnl is really simple and requires few lines of code
>>>> (sample application has been presented in the initial version of this RFC)
>>>
>>> I'm not saying it's not "simple" to parse, just that now you are doing
>>> something that requires a different tool. If you have a block device,
>>> you should be able to emit uevents for it, you don't need a backing
>>> device, we handle virtual filesystems in /sys/block/ just fine :)
>>>
>>> People already have tools that listen to libudev for system monitoring
>>> and management, why require them to hook up to yet-another-library? And
>>> what is going to provide the ability for multiple userspace tools to
>>> listen to these netlink messages in case you have more than one program
>>> that wants to watch for these things (i.e. multiple desktop filesystem
>>> monitoring tools, system-health checkers, etc.)?
>> As much as I understand your concerns I'm not convinced uevent interface
>> is a good fit. There are filesystems that don't have underlying block
>> device - think of e.g. tmpfs or filesystems working directly on top of
>> flash devices. These still want to send notification to userspace (one of
>> primary motivation for this interfaces was so that tmpfs can notify about
>> something). And creating some fake nodes in /sys/block for tmpfs and
>> similar filesystems seems like doing more harm than good to me...
>
> If these are "fake" block devices, what's going to be present in the
> block major/minor fields of the netlink message? For some reason I
> thought it was a required field, and because of that, I thought we had a
> "real" filesystem somewhere to refer to, otherwise how would userspace
> know what filesystem was creating these events?
>
> What am I missing here?
>
> confused,
>
> greg k-h
>
For those 'fake' block devs, upon mount, get_anon_bdev will assign
the major:minor numbers. Userspace might get those through stat.
BR
Beata
^ permalink raw reply
* Re: [RFC v2 1/4] fs: Add generic file system event notifications
From: Greg KH @ 2015-04-28 14:09 UTC (permalink / raw)
To: Jan Kara
Cc: Beata Michalska, linux-kernel, linux-fsdevel, linux-api, tytso,
adilger.kernel, hughd, lczerner, hch, linux-ext4, linux-mm,
kyungmin.park, kmpark
In-Reply-To: <20150428135653.GD9955@quack.suse.cz>
On Tue, Apr 28, 2015 at 03:56:53PM +0200, Jan Kara wrote:
> On Mon 27-04-15 17:37:11, Greg KH wrote:
> > On Mon, Apr 27, 2015 at 05:08:27PM +0200, Beata Michalska wrote:
> > > On 04/27/2015 04:24 PM, Greg KH wrote:
> > > > On Mon, Apr 27, 2015 at 01:51:41PM +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.
> > > >>
> > > >> Signed-off-by: Beata Michalska <b.michalska@samsung.com>
> > > >> ---
> > > >> Documentation/filesystems/events.txt | 231 ++++++++++
> > > >> fs/Makefile | 1 +
> > > >> fs/events/Makefile | 6 +
> > > >> fs/events/fs_event.c | 770 ++++++++++++++++++++++++++++++++++
> > > >> fs/events/fs_event.h | 25 ++
> > > >> fs/events/fs_event_netlink.c | 99 +++++
> > > >> fs/namespace.c | 1 +
> > > >> include/linux/fs.h | 6 +-
> > > >> include/linux/fs_event.h | 58 +++
> > > >> include/uapi/linux/fs_event.h | 54 +++
> > > >> include/uapi/linux/genetlink.h | 1 +
> > > >> net/netlink/genetlink.c | 7 +-
> > > >> 12 files changed, 1257 insertions(+), 2 deletions(-)
> > > >> create mode 100644 Documentation/filesystems/events.txt
> > > >> create mode 100644 fs/events/Makefile
> > > >> create mode 100644 fs/events/fs_event.c
> > > >> create mode 100644 fs/events/fs_event.h
> > > >> create mode 100644 fs/events/fs_event_netlink.c
> > > >> create mode 100644 include/linux/fs_event.h
> > > >> create mode 100644 include/uapi/linux/fs_event.h
> > > >
> > > > Any reason why you just don't do uevents for the block devices today,
> > > > and not create a new type of netlink message and userspace tool required
> > > > to read these?
> > >
> > > The idea here is to have support for filesystems with no backing device as well.
> > > Parsing the message with libnl is really simple and requires few lines of code
> > > (sample application has been presented in the initial version of this RFC)
> >
> > I'm not saying it's not "simple" to parse, just that now you are doing
> > something that requires a different tool. If you have a block device,
> > you should be able to emit uevents for it, you don't need a backing
> > device, we handle virtual filesystems in /sys/block/ just fine :)
> >
> > People already have tools that listen to libudev for system monitoring
> > and management, why require them to hook up to yet-another-library? And
> > what is going to provide the ability for multiple userspace tools to
> > listen to these netlink messages in case you have more than one program
> > that wants to watch for these things (i.e. multiple desktop filesystem
> > monitoring tools, system-health checkers, etc.)?
> As much as I understand your concerns I'm not convinced uevent interface
> is a good fit. There are filesystems that don't have underlying block
> device - think of e.g. tmpfs or filesystems working directly on top of
> flash devices. These still want to send notification to userspace (one of
> primary motivation for this interfaces was so that tmpfs can notify about
> something). And creating some fake nodes in /sys/block for tmpfs and
> similar filesystems seems like doing more harm than good to me...
If these are "fake" block devices, what's going to be present in the
block major/minor fields of the netlink message? For some reason I
thought it was a required field, and because of that, I thought we had a
"real" filesystem somewhere to refer to, otherwise how would userspace
know what filesystem was creating these events?
What am I missing here?
confused,
greg k-h
--
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 v8 1/3] scsi: ufs: add ioctl interface for query request
From: Dov Levenglick @ 2015-04-28 14:09 UTC (permalink / raw)
Cc: james.bottomley-JuX6DAaQMKPCXq6kfMZ53/egYHeGw8Jk,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-scsi-u79uwXL29TY76Z2rM5mHXA,
linux-arm-msm-u79uwXL29TY76Z2rM5mHXA,
santoshsy-Re5JQEeQqe8AvxtiuMwx3w,
linux-scsi-owner-u79uwXL29TY76Z2rM5mHXA,
subhashj-sgV2jX0FEOL9JmXXK+q4OQ, ygardi-sgV2jX0FEOL9JmXXK+q4OQ,
draviv-sgV2jX0FEOL9JmXXK+q4OQ, Noa Rubens, Raviv Shvili,
Gilad Broner, Vinayak Holikatti, James E.J. Bottomley,
open list:ABI/API
In-Reply-To: <1429012281-24068-2-git-send-email-gbroner-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
Reviewed-by: Dov Levenglick <dovl-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
> From: Dolev Raviv <draviv-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
>
> This patch exposes the ioctl interface for UFS driver via SCSI device
> ioctl interface. As of now UFS driver would provide the ioctl for query
> interface to connected UFS device.
>
> Signed-off-by: Dolev Raviv <draviv-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
> Signed-off-by: Noa Rubens <noag-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
> Signed-off-by: Raviv Shvili <rshvili-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
> Signed-off-by: Yaniv Gardi <ygardi-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
> Signed-off-by: Gilad Broner <gbroner-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
> ---
> drivers/scsi/ufs/ufs.h | 53 +++-------
> drivers/scsi/ufs/ufshcd.c | 219
> +++++++++++++++++++++++++++++++++++++++++-
> include/scsi/scsi.h | 1 +
> include/uapi/scsi/Kbuild | 1 +
> include/uapi/scsi/ufs/Kbuild | 3 +
> include/uapi/scsi/ufs/ioctl.h | 57 +++++++++++
> include/uapi/scsi/ufs/ufs.h | 66 +++++++++++++
> 7 files changed, 356 insertions(+), 44 deletions(-)
> create mode 100644 include/uapi/scsi/ufs/Kbuild
> create mode 100644 include/uapi/scsi/ufs/ioctl.h
> create mode 100644 include/uapi/scsi/ufs/ufs.h
>
<snip many lines of code>
> + UPIU_QUERY_OPCODE_CLEAR_FLAG = 0x7,
> + UPIU_QUERY_OPCODE_TOGGLE_FLAG = 0x8,
> +};
> +#endif /* UAPI_UFS_H_ */
> --
> Qualcomm Israel, on behalf of Qualcomm Innovation Center, Inc.
> The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
> a Linux Foundation Collaborative Project
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
> the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
QUALCOMM ISRAEL, on behalf of Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
^ permalink raw reply
* Re: [RFC v2 1/4] fs: Add generic file system event notifications
From: Jan Kara @ 2015-04-28 13:56 UTC (permalink / raw)
To: Greg KH
Cc: Beata Michalska, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
linux-api-u79uwXL29TY76Z2rM5mHXA, jack-AlSwsSmVLrQ,
tytso-3s7WtUTddSA, adilger.kernel-m1MBpc4rdrD3fQ9qLvQP4Q,
hughd-hpIqsD4AKlfQT0dZR+AlfA, lczerner-H+wXaHxf7aLQT0dZR+AlfA,
hch-wEGCiKHe2LqWVfeAwA7xHQ, linux-ext4-u79uwXL29TY76Z2rM5mHXA,
linux-mm-Bw31MaZKKs3YtjvyW6yDsg,
kyungmin.park-Sze3O3UU22JBDgjK7y7TUQ,
kmpark-wEGCiKHe2LqWVfeAwA7xHQ
In-Reply-To: <20150427153711.GA23428-U8xfFu+wG4EAvxtiuMwx3w@public.gmane.org>
On Mon 27-04-15 17:37:11, Greg KH wrote:
> On Mon, Apr 27, 2015 at 05:08:27PM +0200, Beata Michalska wrote:
> > On 04/27/2015 04:24 PM, Greg KH wrote:
> > > On Mon, Apr 27, 2015 at 01:51:41PM +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.
> > >>
> > >> Signed-off-by: Beata Michalska <b.michalska-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
> > >> ---
> > >> Documentation/filesystems/events.txt | 231 ++++++++++
> > >> fs/Makefile | 1 +
> > >> fs/events/Makefile | 6 +
> > >> fs/events/fs_event.c | 770 ++++++++++++++++++++++++++++++++++
> > >> fs/events/fs_event.h | 25 ++
> > >> fs/events/fs_event_netlink.c | 99 +++++
> > >> fs/namespace.c | 1 +
> > >> include/linux/fs.h | 6 +-
> > >> include/linux/fs_event.h | 58 +++
> > >> include/uapi/linux/fs_event.h | 54 +++
> > >> include/uapi/linux/genetlink.h | 1 +
> > >> net/netlink/genetlink.c | 7 +-
> > >> 12 files changed, 1257 insertions(+), 2 deletions(-)
> > >> create mode 100644 Documentation/filesystems/events.txt
> > >> create mode 100644 fs/events/Makefile
> > >> create mode 100644 fs/events/fs_event.c
> > >> create mode 100644 fs/events/fs_event.h
> > >> create mode 100644 fs/events/fs_event_netlink.c
> > >> create mode 100644 include/linux/fs_event.h
> > >> create mode 100644 include/uapi/linux/fs_event.h
> > >
> > > Any reason why you just don't do uevents for the block devices today,
> > > and not create a new type of netlink message and userspace tool required
> > > to read these?
> >
> > The idea here is to have support for filesystems with no backing device as well.
> > Parsing the message with libnl is really simple and requires few lines of code
> > (sample application has been presented in the initial version of this RFC)
>
> I'm not saying it's not "simple" to parse, just that now you are doing
> something that requires a different tool. If you have a block device,
> you should be able to emit uevents for it, you don't need a backing
> device, we handle virtual filesystems in /sys/block/ just fine :)
>
> People already have tools that listen to libudev for system monitoring
> and management, why require them to hook up to yet-another-library? And
> what is going to provide the ability for multiple userspace tools to
> listen to these netlink messages in case you have more than one program
> that wants to watch for these things (i.e. multiple desktop filesystem
> monitoring tools, system-health checkers, etc.)?
As much as I understand your concerns I'm not convinced uevent interface
is a good fit. There are filesystems that don't have underlying block
device - think of e.g. tmpfs or filesystems working directly on top of
flash devices. These still want to send notification to userspace (one of
primary motivation for this interfaces was so that tmpfs can notify about
something). And creating some fake nodes in /sys/block for tmpfs and
similar filesystems seems like doing more harm than good to me...
Honza
> > Most of the code operates on sb only if it
> > was explicitly asked to, through call from filesystem. There is also
> > a callback notifying of mount being dropped (which proceeds the call to
> > kill_super) that invalidates the object that depends on it.
> > Still, it should be explicitly stated that the sb is being used through
> > bidding up the s_count counter, though that would require taking the
> > sb_lock. AFAIK, one can get the reference to super block but for a particular
> > device. Maybe it would be worth having it more generic (?).
>
> Why not just grab a reference to the sb when you save the pointer, and
> release it when you are done with it? That should handle the lifecycle
> properly. It's always a very bad idea to have a pointer to a reference
> counted object without actually grabbing the reference, as you have no
> idea what is happening with it behind your back.
>
> thanks,
>
> greg k-h
--
Jan Kara <jack-AlSwsSmVLrQ@public.gmane.org>
SUSE Labs, CR
^ permalink raw reply
* Re: [PATCH 01/11] coresight-etm4x: Adding CoreSight ETM4x driver
From: Linus Walleij @ 2015-04-28 12:28 UTC (permalink / raw)
To: Mathieu Poirier
Cc: Greg KH, linux-arm-kernel@lists.infradead.org,
linux-api@vger.kernel.org, linux-kernel@vger.kernel.org,
Kaixu Xia, Chunyan Zhang
In-Reply-To: <1429742451-11465-2-git-send-email-mathieu.poirier@linaro.org>
On Thu, Apr 23, 2015 at 12:40 AM, Mathieu Poirier
<mathieu.poirier@linaro.org> wrote:
> From: Pratik Patel <pratikp@codeaurora.org>
>
> This driver manages the CoreSight ETMv4 (Embedded Trace Macrocell) IP block
> to support HW assisted tracing on ARMv7 and ARMv8 architectures.
>
> Signed-off-by: Pratik Patel <pratikp@codeaurora.org>
> Signed-off-by: Kaixu Xia <xiakaixu@huawei.com>
> Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
(...)
> +/* The number of ETMv4 currently registered */
> +static int etm4_count;
> +static struct etmv4_drvdata *etmdrvdata[NR_CPUS];
Don't you need a mutex or something around etm4_count so
as to protect it? You could also make it an atomic.
Also why is it a signed int ... unsigned int?
I know, lame comments, the runtime PM stuff looks perfect now,
someone had a refcount comment but it's doing the right thing.
Yours,
Linus Walleij
^ permalink raw reply
* [PATCH v3 3/3] proc: add kpageidle file
From: Vladimir Davydov @ 2015-04-28 12:24 UTC (permalink / raw)
To: Andrew Morton
Cc: Minchan Kim, Johannes Weiner, Michal Hocko, Greg Thelen,
Michel Lespinasse, David Rientjes, Pavel Emelyanov,
Cyrill Gorcunov, Jonathan Corbet, linux-api, linux-doc, linux-mm,
cgroups, linux-kernel
In-Reply-To: <cover.1430217477.git.vdavydov@parallels.com>
Knowing the portion of memory that is not used by a certain application
or memory cgroup (idle memory) can be useful for partitioning the system
efficiently, e.g. by setting memory cgroup limits appropriately.
Currently, the only means to estimate the amount of idle memory provided
by the kernel is /proc/PID/{clear_refs,smaps}: the user can clear the
access bit for all pages mapped to a particular process by writing 1 to
clear_refs, wait for some time, and then count smaps:Referenced.
However, this method has two serious shortcomings:
- it does not count unmapped file pages
- it affects the reclaimer logic
To overcome these drawbacks, this patch introduces two new page flags,
Idle and Young, and a new proc file, /proc/kpageidle. A page's Idle flag
can only be set from userspace by writing 1 to /proc/kpageidle at the
offset corresponding to the page, and it is cleared whenever the page is
accessed either through page tables (it is cleared in page_referenced()
in this case) or using the read(2) system call (mark_page_accessed()).
Thus by setting the Idle flag for pages of a particular workload, which
can be found e.g. by reading /proc/PID/pagemap, waiting for some time to
let the workload access its working set, and then reading the kpageidle
file, one can estimate the amount of pages that are not used by the
workload.
The Young page flag is used to avoid interference with the memory
reclaimer. A page's Young flag is set whenever the Access bit of a page
table entry pointing to the page is cleared by writing to kpageidle. If
page_referenced() is called on a Young page, it will add 1 to its return
value, therefore concealing the fact that the Access bit was cleared.
Note, since there is no room for extra page flags on 32 bit, this
feature uses extended page flags when compiled on 32 bit.
Signed-off-by: Vladimir Davydov <vdavydov@parallels.com>
---
Documentation/vm/pagemap.txt | 10 ++-
fs/proc/page.c | 154 ++++++++++++++++++++++++++++++++++++++++++
fs/proc/task_mmu.c | 4 +-
include/linux/mm.h | 88 ++++++++++++++++++++++++
include/linux/page-flags.h | 9 +++
include/linux/page_ext.h | 4 ++
mm/Kconfig | 12 ++++
mm/debug.c | 4 ++
mm/page_ext.c | 3 +
mm/rmap.c | 7 ++
mm/swap.c | 2 +
11 files changed, 295 insertions(+), 2 deletions(-)
diff --git a/Documentation/vm/pagemap.txt b/Documentation/vm/pagemap.txt
index a9b7afc8fbc6..ac6fd32a9296 100644
--- a/Documentation/vm/pagemap.txt
+++ b/Documentation/vm/pagemap.txt
@@ -5,7 +5,7 @@ pagemap is a new (as of 2.6.25) set of interfaces in the kernel that allow
userspace programs to examine the page tables and related information by
reading files in /proc.
-There are four components to pagemap:
+There are five components to pagemap:
* /proc/pid/pagemap. This file lets a userspace process find out which
physical frame each virtual page is mapped to. It contains one 64-bit
@@ -69,6 +69,14 @@ There are four components to pagemap:
memory cgroup each page is charged to, indexed by PFN. Only available when
CONFIG_MEMCG is set.
+ * /proc/kpageidle. For each page this file contains a 64-bit number, which
+ equals 1 if the page is idle or 0 otherwise, indexed by PFN. A page is
+ considered idle if it has not been accessed since it was marked idle. To
+ mark a page idle one should write 1 to this file at the offset corresponding
+ to the page. Only user memory pages can be marked idle, for other page types
+ input is silently ignored. Writing to this file beyond max PFN results in
+ the ENXIO error. Only available when CONFIG_IDLE_PAGE_TRACKING is set.
+
Short descriptions to the page flags:
0. LOCKED
diff --git a/fs/proc/page.c b/fs/proc/page.c
index 70d23245dd43..cfc55ba7fee6 100644
--- a/fs/proc/page.c
+++ b/fs/proc/page.c
@@ -275,6 +275,156 @@ static const struct file_operations proc_kpagecgroup_operations = {
};
#endif /* CONFIG_MEMCG */
+#ifdef CONFIG_IDLE_PAGE_TRACKING
+static struct page *kpageidle_get_page(unsigned long pfn)
+{
+ struct page *page;
+
+ if (!pfn_valid(pfn))
+ return NULL;
+ page = pfn_to_page(pfn);
+ /*
+ * We are only interested in user memory pages, i.e. pages that are
+ * allocated and on an LRU list.
+ */
+ if (!page || page_count(page) == 0 || !PageLRU(page))
+ return NULL;
+ if (!get_page_unless_zero(page))
+ return NULL;
+ if (unlikely(!PageLRU(page))) {
+ put_page(page);
+ return NULL;
+ }
+ return page;
+}
+
+static void kpageidle_clear_refs(struct page *page)
+{
+ unsigned long dummy;
+
+ if (page_referenced(page, 0, NULL, &dummy))
+ /*
+ * This page was referenced. To avoid interference with the
+ * reclaimer, mark it young so that the next call will also
+ * return > 0 (see page_referenced_one)
+ */
+ set_page_young(page);
+}
+
+static ssize_t kpageidle_read(struct file *file, char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ u64 __user *out = (u64 __user *)buf;
+ struct page *page;
+ unsigned long src = *ppos;
+ unsigned long pfn;
+ ssize_t ret = 0;
+ u64 val;
+
+ pfn = src / KPMSIZE;
+ count = min_t(unsigned long, count, (max_pfn * KPMSIZE) - src);
+ if (src & KPMMASK || count & KPMMASK)
+ return -EINVAL;
+
+ while (count > 0) {
+ val = 0;
+ page = kpageidle_get_page(pfn);
+ if (page) {
+ if (page_is_idle(page)) {
+ /*
+ * The page might have been referenced via a
+ * pte, in which case it is not idle. Clear
+ * refs and recheck.
+ */
+ kpageidle_clear_refs(page);
+ if (page_is_idle(page))
+ val = 1;
+ }
+ put_page(page);
+ }
+
+ if (put_user(val, out)) {
+ ret = -EFAULT;
+ break;
+ }
+
+ pfn++;
+ out++;
+ count -= KPMSIZE;
+ }
+
+ *ppos += (char __user *)out - buf;
+ if (!ret)
+ ret = (char __user *)out - buf;
+ return ret;
+}
+
+static ssize_t kpageidle_write(struct file *file, const char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ const u64 __user *in = (u64 __user *)buf;
+ struct page *page;
+ unsigned long src = *ppos;
+ unsigned long pfn;
+ ssize_t ret = 0;
+ u64 val;
+
+ pfn = src / KPMSIZE;
+ if (src & KPMMASK || count & KPMMASK)
+ return -EINVAL;
+
+ while (count > 0) {
+ if (pfn >= max_pfn) {
+ if ((char __user *)in == buf)
+ ret = -ENXIO;
+ break;
+ }
+
+ if (get_user(val, in)) {
+ ret = -EFAULT;
+ break;
+ }
+
+ if (val == 1) {
+ page = kpageidle_get_page(pfn);
+ if (page) {
+ kpageidle_clear_refs(page);
+ set_page_idle(page);
+ put_page(page);
+ }
+ } else if (val) {
+ ret = -EINVAL;
+ break;
+ }
+
+ pfn++;
+ in++;
+ count -= KPMSIZE;
+ }
+
+ *ppos += (char __user *)in - buf;
+ if (!ret)
+ ret = (char __user *)in - buf;
+ return ret;
+}
+
+static const struct file_operations proc_kpageidle_operations = {
+ .llseek = mem_lseek,
+ .read = kpageidle_read,
+ .write = kpageidle_write,
+};
+
+#ifndef CONFIG_64BIT
+static bool need_page_idle(void)
+{
+ return true;
+}
+struct page_ext_operations page_idle_ops = {
+ .need = need_page_idle,
+};
+#endif
+#endif /* CONFIG_IDLE_PAGE_TRACKING */
+
static int __init proc_page_init(void)
{
proc_create("kpagecount", S_IRUSR, NULL, &proc_kpagecount_operations);
@@ -282,6 +432,10 @@ static int __init proc_page_init(void)
#ifdef CONFIG_MEMCG
proc_create("kpagecgroup", S_IRUSR, NULL, &proc_kpagecgroup_operations);
#endif
+#ifdef CONFIG_IDLE_PAGE_TRACKING
+ proc_create("kpageidle", S_IRUSR | S_IWUSR, NULL,
+ &proc_kpageidle_operations);
+#endif
return 0;
}
fs_initcall(proc_page_init);
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
index 6dee68d013ff..ab04846f7dd5 100644
--- a/fs/proc/task_mmu.c
+++ b/fs/proc/task_mmu.c
@@ -458,7 +458,7 @@ static void smaps_account(struct mem_size_stats *mss, struct page *page,
mss->resident += size;
/* Accumulate the size in pages that have been accessed. */
- if (young || PageReferenced(page))
+ if (young || page_is_young(page) || PageReferenced(page))
mss->referenced += size;
mapcount = page_mapcount(page);
if (mapcount >= 2) {
@@ -808,6 +808,7 @@ static int clear_refs_pte_range(pmd_t *pmd, unsigned long addr,
/* Clear accessed and referenced bits. */
pmdp_test_and_clear_young(vma, addr, pmd);
+ clear_page_young(page);
ClearPageReferenced(page);
out:
spin_unlock(ptl);
@@ -835,6 +836,7 @@ out:
/* Clear accessed and referenced bits. */
ptep_test_and_clear_young(vma, addr, pte);
+ clear_page_young(page);
ClearPageReferenced(page);
}
pte_unmap_unlock(pte - 1, ptl);
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 0755b9fd03a7..794d29aa2317 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -2200,5 +2200,93 @@ void __init setup_nr_node_ids(void);
static inline void setup_nr_node_ids(void) {}
#endif
+#ifdef CONFIG_IDLE_PAGE_TRACKING
+#ifdef CONFIG_64BIT
+static inline bool page_is_young(struct page *page)
+{
+ return PageYoung(page);
+}
+
+static inline void set_page_young(struct page *page)
+{
+ SetPageYoung(page);
+}
+
+static inline void clear_page_young(struct page *page)
+{
+ ClearPageYoung(page);
+}
+
+static inline bool page_is_idle(struct page *page)
+{
+ return PageIdle(page);
+}
+
+static inline void set_page_idle(struct page *page)
+{
+ SetPageIdle(page);
+}
+
+static inline void clear_page_idle(struct page *page)
+{
+ ClearPageIdle(page);
+}
+#else /* !CONFIG_64BIT */
+/*
+ * If there is not enough space to store Idle and Young bits in page flags, use
+ * page ext flags instead.
+ */
+extern struct page_ext_operations page_idle_ops;
+
+static inline bool page_is_young(struct page *page)
+{
+ return test_bit(PAGE_EXT_YOUNG, &lookup_page_ext(page)->flags);
+}
+
+static inline void set_page_young(struct page *page)
+{
+ set_bit(PAGE_EXT_YOUNG, &lookup_page_ext(page)->flags);
+}
+
+static inline void clear_page_young(struct page *page)
+{
+ clear_bit(PAGE_EXT_YOUNG, &lookup_page_ext(page)->flags);
+}
+
+static inline bool page_is_idle(struct page *page)
+{
+ return test_bit(PAGE_EXT_IDLE, &lookup_page_ext(page)->flags);
+}
+
+static inline void set_page_idle(struct page *page)
+{
+ set_bit(PAGE_EXT_IDLE, &lookup_page_ext(page)->flags);
+}
+
+static inline void clear_page_idle(struct page *page)
+{
+ clear_bit(PAGE_EXT_IDLE, &lookup_page_ext(page)->flags);
+}
+#endif /* CONFIG_64BIT */
+#else /* !CONFIG_IDLE_PAGE_TRACKING */
+static inline bool page_is_young(struct page *page)
+{
+ return false;
+}
+
+static inline void clear_page_young(struct page *page)
+{
+}
+
+static inline bool page_is_idle(struct page *page)
+{
+ return false;
+}
+
+static inline void clear_page_idle(struct page *page)
+{
+}
+#endif /* CONFIG_IDLE_PAGE_TRACKING */
+
#endif /* __KERNEL__ */
#endif /* _LINUX_MM_H */
diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h
index f34e040b34e9..5e7c4f50a644 100644
--- a/include/linux/page-flags.h
+++ b/include/linux/page-flags.h
@@ -109,6 +109,10 @@ enum pageflags {
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
PG_compound_lock,
#endif
+#if defined(CONFIG_IDLE_PAGE_TRACKING) && defined(CONFIG_64BIT)
+ PG_young,
+ PG_idle,
+#endif
__NR_PAGEFLAGS,
/* Filesystems */
@@ -289,6 +293,11 @@ PAGEFLAG_FALSE(HWPoison)
#define __PG_HWPOISON 0
#endif
+#if defined(CONFIG_IDLE_PAGE_TRACKING) && defined(CONFIG_64BIT)
+PAGEFLAG(Young, young)
+PAGEFLAG(Idle, idle)
+#endif
+
/*
* On an anonymous page mapped into a user virtual memory area,
* page->mapping points to its anon_vma, not to a struct address_space;
diff --git a/include/linux/page_ext.h b/include/linux/page_ext.h
index c42981cd99aa..17f118a82854 100644
--- a/include/linux/page_ext.h
+++ b/include/linux/page_ext.h
@@ -26,6 +26,10 @@ enum page_ext_flags {
PAGE_EXT_DEBUG_POISON, /* Page is poisoned */
PAGE_EXT_DEBUG_GUARD,
PAGE_EXT_OWNER,
+#if defined(CONFIG_IDLE_PAGE_TRACKING) && !defined(CONFIG_64BIT)
+ PAGE_EXT_YOUNG,
+ PAGE_EXT_IDLE,
+#endif
};
/*
diff --git a/mm/Kconfig b/mm/Kconfig
index 390214da4546..3600eace4774 100644
--- a/mm/Kconfig
+++ b/mm/Kconfig
@@ -635,3 +635,15 @@ config MAX_STACK_SIZE_MB
changed to a smaller value in which case that is used.
A sane initial value is 80 MB.
+
+config IDLE_PAGE_TRACKING
+ bool "Enable idle page tracking"
+ select PROC_PAGE_MONITOR
+ select PAGE_EXTENSION if !64BIT
+ help
+ This feature allows to estimate the amount of user pages that have
+ not been touched during a given period of time. This information can
+ be useful to tune memory cgroup limits and/or for job placement
+ within a compute cluster.
+
+ See Documentation/vm/pagemap.txt for more details.
diff --git a/mm/debug.c b/mm/debug.c
index 3eb3ac2fcee7..bb66f9ccec03 100644
--- a/mm/debug.c
+++ b/mm/debug.c
@@ -48,6 +48,10 @@ static const struct trace_print_flags pageflag_names[] = {
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
{1UL << PG_compound_lock, "compound_lock" },
#endif
+#if defined(CONFIG_IDLE_PAGE_TRACKING) && defined(CONFIG_64BIT)
+ {1UL << PG_young, "young" },
+ {1UL << PG_idle, "idle" },
+#endif
};
static void dump_flags(unsigned long flags,
diff --git a/mm/page_ext.c b/mm/page_ext.c
index d86fd2f5353f..e4b3af054bf2 100644
--- a/mm/page_ext.c
+++ b/mm/page_ext.c
@@ -59,6 +59,9 @@ static struct page_ext_operations *page_ext_ops[] = {
#ifdef CONFIG_PAGE_OWNER
&page_owner_ops,
#endif
+#if defined(CONFIG_IDLE_PAGE_TRACKING) && !defined(CONFIG_64BIT)
+ &page_idle_ops,
+#endif
};
static unsigned long total_usage;
diff --git a/mm/rmap.c b/mm/rmap.c
index 24dd3f9fee27..12e73b758d9e 100644
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -784,6 +784,13 @@ static int page_referenced_one(struct page *page, struct vm_area_struct *vma,
if (referenced) {
pra->referenced++;
pra->vm_flags |= vma->vm_flags;
+ if (page_is_idle(page))
+ clear_page_idle(page);
+ }
+
+ if (page_is_young(page)) {
+ clear_page_young(page);
+ pra->referenced++;
}
pra->mapcount--;
diff --git a/mm/swap.c b/mm/swap.c
index a7251a8ed532..6bf6f293a9ea 100644
--- a/mm/swap.c
+++ b/mm/swap.c
@@ -623,6 +623,8 @@ void mark_page_accessed(struct page *page)
} else if (!PageReferenced(page)) {
SetPageReferenced(page);
}
+ if (page_is_idle(page))
+ clear_page_idle(page);
}
EXPORT_SYMBOL(mark_page_accessed);
--
1.7.10.4
--
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 related
* [PATCH v3 2/3] proc: add kpagecgroup file
From: Vladimir Davydov @ 2015-04-28 12:24 UTC (permalink / raw)
To: Andrew Morton
Cc: Minchan Kim, Johannes Weiner, Michal Hocko, Greg Thelen,
Michel Lespinasse, David Rientjes, Pavel Emelyanov,
Cyrill Gorcunov, Jonathan Corbet, linux-api, linux-doc, linux-mm,
cgroups, linux-kernel
In-Reply-To: <cover.1430217477.git.vdavydov@parallels.com>
/proc/kpagecgroup contains a 64-bit inode number of the memory cgroup
each page is charged to, indexed by PFN. Having this information is
useful for estimating a cgroup working set size.
The file is present if CONFIG_PROC_PAGE_MONITOR && CONFIG_MEMCG.
Signed-off-by: Vladimir Davydov <vdavydov@parallels.com>
---
Documentation/vm/pagemap.txt | 6 ++++-
fs/proc/Kconfig | 5 ++--
fs/proc/page.c | 53 ++++++++++++++++++++++++++++++++++++++++++
3 files changed, 61 insertions(+), 3 deletions(-)
diff --git a/Documentation/vm/pagemap.txt b/Documentation/vm/pagemap.txt
index 6bfbc172cdb9..a9b7afc8fbc6 100644
--- a/Documentation/vm/pagemap.txt
+++ b/Documentation/vm/pagemap.txt
@@ -5,7 +5,7 @@ pagemap is a new (as of 2.6.25) set of interfaces in the kernel that allow
userspace programs to examine the page tables and related information by
reading files in /proc.
-There are three components to pagemap:
+There are four components to pagemap:
* /proc/pid/pagemap. This file lets a userspace process find out which
physical frame each virtual page is mapped to. It contains one 64-bit
@@ -65,6 +65,10 @@ There are three components to pagemap:
23. BALLOON
24. ZERO_PAGE
+ * /proc/kpagecgroup. This file contains a 64-bit inode number of the
+ memory cgroup each page is charged to, indexed by PFN. Only available when
+ CONFIG_MEMCG is set.
+
Short descriptions to the page flags:
0. LOCKED
diff --git a/fs/proc/Kconfig b/fs/proc/Kconfig
index 2183fcf41d59..5021a2935bb9 100644
--- a/fs/proc/Kconfig
+++ b/fs/proc/Kconfig
@@ -69,5 +69,6 @@ config PROC_PAGE_MONITOR
help
Various /proc files exist to monitor process memory utilization:
/proc/pid/smaps, /proc/pid/clear_refs, /proc/pid/pagemap,
- /proc/kpagecount, and /proc/kpageflags. Disabling these
- interfaces will reduce the size of the kernel by approximately 4kb.
+ /proc/kpagecount, /proc/kpageflags, and /proc/kpagecgroup.
+ Disabling these interfaces will reduce the size of the kernel
+ by approximately 4kb.
diff --git a/fs/proc/page.c b/fs/proc/page.c
index 7eee2d8b97d9..70d23245dd43 100644
--- a/fs/proc/page.c
+++ b/fs/proc/page.c
@@ -9,6 +9,7 @@
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/hugetlb.h>
+#include <linux/memcontrol.h>
#include <linux/kernel-page-flags.h>
#include <asm/uaccess.h>
#include "internal.h"
@@ -225,10 +226,62 @@ static const struct file_operations proc_kpageflags_operations = {
.read = kpageflags_read,
};
+#ifdef CONFIG_MEMCG
+static ssize_t kpagecgroup_read(struct file *file, char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ u64 __user *out = (u64 __user *)buf;
+ struct page *ppage;
+ unsigned long src = *ppos;
+ unsigned long pfn;
+ ssize_t ret = 0;
+ u64 ino;
+
+ pfn = src / KPMSIZE;
+ count = min_t(unsigned long, count, (max_pfn * KPMSIZE) - src);
+ if (src & KPMMASK || count & KPMMASK)
+ return -EINVAL;
+
+ while (count > 0) {
+ if (pfn_valid(pfn))
+ ppage = pfn_to_page(pfn);
+ else
+ ppage = NULL;
+
+ if (ppage)
+ ino = page_cgroup_ino(ppage);
+ else
+ ino = 0;
+
+ if (put_user(ino, out)) {
+ ret = -EFAULT;
+ break;
+ }
+
+ pfn++;
+ out++;
+ count -= KPMSIZE;
+ }
+
+ *ppos += (char __user *)out - buf;
+ if (!ret)
+ ret = (char __user *)out - buf;
+ return ret;
+}
+
+static const struct file_operations proc_kpagecgroup_operations = {
+ .llseek = mem_lseek,
+ .read = kpagecgroup_read,
+};
+#endif /* CONFIG_MEMCG */
+
static int __init proc_page_init(void)
{
proc_create("kpagecount", S_IRUSR, NULL, &proc_kpagecount_operations);
proc_create("kpageflags", S_IRUSR, NULL, &proc_kpageflags_operations);
+#ifdef CONFIG_MEMCG
+ proc_create("kpagecgroup", S_IRUSR, NULL, &proc_kpagecgroup_operations);
+#endif
return 0;
}
fs_initcall(proc_page_init);
--
1.7.10.4
^ permalink raw reply related
* [PATCH v3 1/3] memcg: add page_cgroup_ino helper
From: Vladimir Davydov @ 2015-04-28 12:24 UTC (permalink / raw)
To: Andrew Morton
Cc: Minchan Kim, Johannes Weiner, Michal Hocko, Greg Thelen,
Michel Lespinasse, David Rientjes, Pavel Emelyanov,
Cyrill Gorcunov, Jonathan Corbet, linux-api, linux-doc, linux-mm,
cgroups, linux-kernel
In-Reply-To: <cover.1430217477.git.vdavydov@parallels.com>
Hwpoison allows to filter pages by memory cgroup ino. To ahieve that, it
calls try_get_mem_cgroup_from_page(), then mem_cgroup_css(), and finally
cgroup_ino() on the cgroup returned. This looks bulky. Since in the next
patch I need to get the ino of the memory cgroup a page is charged to
too, in this patch I introduce the page_cgroup_ino() helper.
Note that page_cgroup_ino() only considers those pages that are charged
to mem_cgroup->memory (i.e. page->mem_cgroup != NULL), and for others it
returns 0, while try_get_mem_cgroup_page(), used by hwpoison before, may
extract the cgroup from a swapcache readahead page too. Ignoring
swapcache readahead pages allows to call page_cgroup_ino() on unlocked
pages, which is nice. Hwpoison users will hardly see any difference.
Another difference between try_get_mem_cgroup_page() and
page_cgroup_ino() is that the latter works on pages charged to offline
memory cgroups, returning the inode number of the closest online
ancestor in this case, while the former does not, which is crucial for
the next patch.
Since try_get_mem_cgroup_page() is not used by anyone else, this patch
removes this function. Also, it makes hwpoison memcg filter depend on
CONFIG_MEMCG instead of CONFIG_MEMCG_SWAP (I've no idea why it was made
dependant on CONFIG_MEMCG_SWAP initially).
Signed-off-by: Vladimir Davydov <vdavydov@parallels.com>
---
include/linux/memcontrol.h | 8 ++---
mm/hwpoison-inject.c | 5 +--
mm/memcontrol.c | 73 ++++++++++++++++++++++----------------------
mm/memory-failure.c | 16 ++--------
4 files changed, 42 insertions(+), 60 deletions(-)
diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h
index 72dff5fb0d0c..9262a8407af7 100644
--- a/include/linux/memcontrol.h
+++ b/include/linux/memcontrol.h
@@ -91,7 +91,6 @@ bool mem_cgroup_is_descendant(struct mem_cgroup *memcg,
struct mem_cgroup *root);
bool task_in_mem_cgroup(struct task_struct *task, struct mem_cgroup *memcg);
-extern struct mem_cgroup *try_get_mem_cgroup_from_page(struct page *page);
extern struct mem_cgroup *mem_cgroup_from_task(struct task_struct *p);
extern struct mem_cgroup *parent_mem_cgroup(struct mem_cgroup *memcg);
@@ -192,6 +191,8 @@ static inline void mem_cgroup_count_vm_event(struct mm_struct *mm,
void mem_cgroup_split_huge_fixup(struct page *head);
#endif
+unsigned long page_cgroup_ino(struct page *page);
+
#else /* CONFIG_MEMCG */
struct mem_cgroup;
@@ -252,11 +253,6 @@ static inline struct lruvec *mem_cgroup_page_lruvec(struct page *page,
return &zone->lruvec;
}
-static inline struct mem_cgroup *try_get_mem_cgroup_from_page(struct page *page)
-{
- return NULL;
-}
-
static inline bool mm_match_cgroup(struct mm_struct *mm,
struct mem_cgroup *memcg)
{
diff --git a/mm/hwpoison-inject.c b/mm/hwpoison-inject.c
index 329caf56df22..df63c3133d70 100644
--- a/mm/hwpoison-inject.c
+++ b/mm/hwpoison-inject.c
@@ -45,12 +45,9 @@ static int hwpoison_inject(void *data, u64 val)
/*
* do a racy check with elevated page count, to make sure PG_hwpoison
* will only be set for the targeted owner (or on a free page).
- * We temporarily take page lock for try_get_mem_cgroup_from_page().
* memory_failure() will redo the check reliably inside page lock.
*/
- lock_page(hpage);
err = hwpoison_filter(hpage);
- unlock_page(hpage);
if (err)
return 0;
@@ -123,7 +120,7 @@ static int pfn_inject_init(void)
if (!dentry)
goto fail;
-#ifdef CONFIG_MEMCG_SWAP
+#ifdef CONFIG_MEMCG
dentry = debugfs_create_u64("corrupt-filter-memcg", 0600,
hwpoison_dir, &hwpoison_filter_memcg);
if (!dentry)
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 14c2f2017e37..87c7f852d45b 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -2349,40 +2349,6 @@ static void cancel_charge(struct mem_cgroup *memcg, unsigned int nr_pages)
css_put_many(&memcg->css, nr_pages);
}
-/*
- * try_get_mem_cgroup_from_page - look up page's memcg association
- * @page: the page
- *
- * Look up, get a css reference, and return the memcg that owns @page.
- *
- * The page must be locked to prevent racing with swap-in and page
- * cache charges. If coming from an unlocked page table, the caller
- * must ensure the page is on the LRU or this can race with charging.
- */
-struct mem_cgroup *try_get_mem_cgroup_from_page(struct page *page)
-{
- struct mem_cgroup *memcg;
- unsigned short id;
- swp_entry_t ent;
-
- VM_BUG_ON_PAGE(!PageLocked(page), page);
-
- memcg = page->mem_cgroup;
- if (memcg) {
- if (!css_tryget_online(&memcg->css))
- memcg = NULL;
- } else if (PageSwapCache(page)) {
- ent.val = page_private(page);
- id = lookup_swap_cgroup_id(ent);
- rcu_read_lock();
- memcg = mem_cgroup_from_id(id);
- if (memcg && !css_tryget_online(&memcg->css))
- memcg = NULL;
- rcu_read_unlock();
- }
- return memcg;
-}
-
static void lock_page_lru(struct page *page, int *isolated)
{
struct zone *zone = page_zone(page);
@@ -2774,6 +2740,31 @@ void mem_cgroup_split_huge_fixup(struct page *head)
}
#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
+/**
+ * page_cgroup_ino - return inode number of page's memcg
+ * @page: the page
+ *
+ * Look up the closest online ancestor of the memory cgroup @page is charged to
+ * and return its inode number. It is safe to call this function without taking
+ * a reference to the page.
+ */
+unsigned long page_cgroup_ino(struct page *page)
+{
+ struct mem_cgroup *memcg;
+ unsigned long ino = 0;
+
+ rcu_read_lock();
+ memcg = READ_ONCE(page->mem_cgroup);
+ while (memcg && !css_tryget_online(&memcg->css))
+ memcg = parent_mem_cgroup(memcg);
+ rcu_read_unlock();
+ if (memcg) {
+ ino = cgroup_ino(memcg->css.cgroup);
+ css_put(&memcg->css);
+ }
+ return ino;
+}
+
#ifdef CONFIG_MEMCG_SWAP
static void mem_cgroup_swap_statistics(struct mem_cgroup *memcg,
bool charge)
@@ -5482,8 +5473,18 @@ int mem_cgroup_try_charge(struct page *page, struct mm_struct *mm,
VM_BUG_ON_PAGE(!PageTransHuge(page), page);
}
- if (do_swap_account && PageSwapCache(page))
- memcg = try_get_mem_cgroup_from_page(page);
+ if (do_swap_account && PageSwapCache(page)) {
+ swp_entry_t ent = { .val = page_private(page), };
+ unsigned short id = lookup_swap_cgroup_id(ent);
+
+ VM_BUG_ON_PAGE(!PageLocked(page), page);
+
+ rcu_read_lock();
+ memcg = mem_cgroup_from_id(id);
+ if (memcg && !css_tryget_online(&memcg->css))
+ memcg = NULL;
+ rcu_read_unlock();
+ }
if (!memcg)
memcg = get_mem_cgroup_from_mm(mm);
diff --git a/mm/memory-failure.c b/mm/memory-failure.c
index d9359b770cd9..64cd565fd4f8 100644
--- a/mm/memory-failure.c
+++ b/mm/memory-failure.c
@@ -128,27 +128,15 @@ static int hwpoison_filter_flags(struct page *p)
* can only guarantee that the page either belongs to the memcg tasks, or is
* a freed page.
*/
-#ifdef CONFIG_MEMCG_SWAP
+#ifdef CONFIG_MEMCG
u64 hwpoison_filter_memcg;
EXPORT_SYMBOL_GPL(hwpoison_filter_memcg);
static int hwpoison_filter_task(struct page *p)
{
- struct mem_cgroup *mem;
- struct cgroup_subsys_state *css;
- unsigned long ino;
-
if (!hwpoison_filter_memcg)
return 0;
- mem = try_get_mem_cgroup_from_page(p);
- if (!mem)
- return -EINVAL;
-
- css = mem_cgroup_css(mem);
- ino = cgroup_ino(css->cgroup);
- css_put(css);
-
- if (ino != hwpoison_filter_memcg)
+ if (page_cgroup_ino(p) != hwpoison_filter_memcg)
return -EINVAL;
return 0;
--
1.7.10.4
--
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 related
* [PATCH v3 0/3] idle memory tracking
From: Vladimir Davydov @ 2015-04-28 12:24 UTC (permalink / raw)
To: Andrew Morton
Cc: Minchan Kim, Johannes Weiner, Michal Hocko, Greg Thelen,
Michel Lespinasse, David Rientjes, Pavel Emelyanov,
Cyrill Gorcunov, Jonathan Corbet, linux-api, linux-doc, linux-mm,
cgroups, linux-kernel
Hi,
This patch set introduces a new user API for tracking user memory pages
that have not been used for a given period of time. The purpose of this
is to provide the userspace with the means of tracking a workload's
working set, i.e. the set of pages that are actively used by the
workload. Knowing the working set size can be useful for partitioning
the system more efficiently, e.g. by tuning memory cgroup limits
appropriately, or for job placement within a compute cluster.
---- USE CASES ----
The unified cgroup hierarchy has memory.low and memory.high knobs, which
are defined as the low and high boundaries for the workload working set
size. However, the working set size of a workload may be unknown or
change in time. With this patch set, one can periodically estimate the
amount of memory unused by each cgroup and tune their memory.low and
memory.high parameters accordingly, therefore optimizing the overall
memory utilization.
Another use case is balancing workloads within a compute cluster.
Knowing how much memory is not really used by a workload unit may help
take a more optimal decision when considering migrating the unit to
another node within the cluster.
---- USER API ----
The user API consists of two new proc files:
* /proc/kpageidle. For each page this file contains a 64-bit number, which
equals 1 if the page is idle or 0 otherwise, indexed by PFN. A page is
considered idle if it has not been accessed since it was marked idle. To
mark a page idle one should write 1 to this file at the offset corresponding
to the page. Only user memory pages can be marked idle, for other page types
input is silently ignored. Writing to this file beyond max PFN results in
the ENXIO error. Only available when CONFIG_IDLE_PAGE_TRACKING is set.
This file can be used to estimate the amount of pages that are not
used by a particular workload as follows:
1. mark all pages of interest idle by writing 1 at the corresponding
offsets to /proc/kpageidle
2. wait until the workload accesses its working set
3. read /proc/kpageidle and count the amount of idle pages
* /proc/kpagecgroup. This file contains a 64-bit inode number of the
memory cgroup each page is charged to, indexed by PFN. Only available when
CONFIG_MEMCG is set.
This file can be used to find all pages (including unmapped file
pages) accounted to a particular cgroup. Using /proc/kpageidle, one
can then estimate the cgroup working set size.
For an example of using these files for estimating the amount of unused
memory pages per each memory cgroup, please see the script attached
below.
---- REASONING ----
The reason to introduce the new user API instead of using
/proc/PID/{clear_refs,smaps} is that the latter has two serious
drawbacks:
- it does not count unmapped file pages
- it affects the reclaimer logic
The new API attempts to overcome them both. For more details on how it
is achieved, please see the comment to patch 3.
---- CHANGE LOG ----
Changes in v3:
- Enable CONFIG_IDLE_PAGE_TRACKING for 32 bit. Since this feature
requires two extra page flags and there is no space for them on 32
bit, page ext is used (thanks to Minchan Kim).
- Minor code cleanups and comments improved.
- Rebase on top of 4.1-rc1.
Changes in v2:
- The main difference from v1 is the API change. In v1 the user can
only set the idle flag for all pages at once, and for clearing the
Idle flag on pages accessed via page tables /proc/PID/clear_refs
should be used.
The main drawback of the v1 approach, as noted by Minchan, is that on
big machines setting the idle flag for each pages can result in CPU
bursts, which would be especially frustrating if the user only wanted
to estimate the amount of idle pages for a particular process or VMA.
With the new API a more fine-grained approach is possible: one can
read a process's /proc/PID/pagemap and set/check the Idle flag only
for those pages of the process's address space he or she is
interested in.
Another good point about the v2 API is that it is possible to limit
/proc/kpage* scanning rate when the user wants to estimate the total
number of idle pages, which is unachievable with the v1 approach.
- Make /proc/kpagecgroup return the ino of the closest online ancestor
in case the cgroup a page is charged to is offline.
- Fix /proc/PID/clear_refs not clearing Young page flag.
- Rebase on top of v4.0-rc6-mmotm-2015-04-01-14-54
v2: https://lkml.org/lkml/2015/4/7/260
v1: https://lkml.org/lkml/2015/3/18/794
---- PATCH SET STRUCTURE ----
The patch set is organized as follows:
- patch 1 adds page_cgroup_ino() helper for the sake of
/proc/kpagecgroup
- patch 2 adds /proc/kpagecgroup, which reports cgroup ino each page is
charged to
- patch 3 implements the idle page tracking feature, including the
userspace API, /proc/kpageidle
---- SIMILAR WORKS ----
Originally, the patch for tracking idle memory was proposed back in 2011
by Michel Lespinasse (see http://lwn.net/Articles/459269/). The main
difference between Michel's patch and this one is that Michel
implemented a kernel space daemon for estimating idle memory size per
cgroup while this patch only provides the userspace with the minimal API
for doing the job, leaving the rest up to the userspace. However, they
both share the same idea of Idle/Young page flags to avoid affecting the
reclaimer logic.
---- SCRIPT FOR COUNTING IDLE PAGES PER CGROUP ----
#! /usr/bin/python
#
CGROUP_MOUNT = "/sys/fs/cgroup/memory"
import os
import stat
import errno
import struct
def set_idle():
pgidle = open("/proc/kpageidle", "wb")
while True:
try:
pgidle.write(struct.pack("Q", 1))
except IOError as e:
if e.errno == errno.ENXIO: break
raise
pgidle.close()
def count_idle():
pgflags = open("/proc/kpageflags", "rb")
pgcgroup = open("/proc/kpagecgroup", "rb")
pgidle = open("/proc/kpageidle", "rb")
nidle = {}
while True:
s = pgflags.read(8)
if len(s) != 8: break;
flags = struct.unpack('Q', s)[0]
cgino = struct.unpack('Q', pgcgroup.read(8))[0]
idle = struct.unpack('Q', pgidle.read(8))[0]
if not idle: continue
if (flags >> 18) & 1: continue # unevictable?
npages = 512 if (flags >> 22) & 1 else 1 # huge?
nidle[cgino] = nidle.get(cgino, 0) + npages
pgflags.close()
pgcgroup.close()
pgidle.close()
return nidle
print "Setting the idle flag for each page..."
set_idle()
raw_input("Wait until the workload accesses its working set, then press Enter")
print "Counting idle pages..."
nidle = count_idle()
for dir, subdirs, files in os.walk(CGROUP_MOUNT):
ino = os.stat(dir)[stat.ST_INO]
print dir + ": " + str(nidle.get(ino, 0))
---- END SCRIPT ----
Comments are more than welcome.
Thanks,
Vladimir Davydov (3):
memcg: add page_cgroup_ino helper
proc: add kpagecgroup file
proc: add kpageidle file
Documentation/vm/pagemap.txt | 14 ++-
fs/proc/Kconfig | 5 +-
fs/proc/page.c | 207 ++++++++++++++++++++++++++++++++++++++++++
fs/proc/task_mmu.c | 4 +-
include/linux/memcontrol.h | 8 +-
include/linux/mm.h | 88 ++++++++++++++++++
include/linux/page-flags.h | 9 ++
include/linux/page_ext.h | 4 +
mm/Kconfig | 12 +++
mm/debug.c | 4 +
mm/hwpoison-inject.c | 5 +-
mm/memcontrol.c | 73 +++++++--------
mm/memory-failure.c | 16 +---
mm/page_ext.c | 3 +
mm/rmap.c | 7 ++
mm/swap.c | 2 +
16 files changed, 397 insertions(+), 64 deletions(-)
--
1.7.10.4
--
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 01/11] coresight-etm4x: Adding CoreSight ETM4x driver
From: Linus Walleij @ 2015-04-28 12:23 UTC (permalink / raw)
To: Ivan T. Ivanov
Cc: Mathieu Poirier, Greg KH, linux-arm-kernel@lists.infradead.org,
linux-api@vger.kernel.org, linux-kernel@vger.kernel.org,
Kaixu Xia, Chunyan Zhang
In-Reply-To: <1429890108.5211.8.camel@mm-sol.com>
On Fri, Apr 24, 2015 at 5:41 PM, Ivan T. Ivanov <iivanov@mm-sol.com> wrote:
> On Wed, 2015-04-22 at 16:40 -0600, Mathieu Poirier wrote:
>>
>
>> +static struct amba_id etm4_ids[] = {
>> + { /* ETM 4.0 - Hi6220 board */
>> + .id = 0x0003b95d,
>> + .mask = 0x0003ffff,
>> + .data = "ETM 4.0",
>> + },
>> + { /* ETM 4.0 - Juno board */
>> + .id = 0x000bb95e,
>> + .mask = 0x000bffff,
>
> Mask looks suspicious.
I'm thinking that maybe we should have some masks predefined in
<linux/amba/bus.h> for bits in this field so we get it right.
Yours,
Linus Walleij
^ permalink raw reply
* Re: [PATCH v6 10/15] serial: stm32-usart: Add STM32 USART Driver
From: Maxime Coquelin @ 2015-04-28 12:13 UTC (permalink / raw)
To: Vladimir Zapolskiy
Cc: Uwe Kleine-König, Andreas Färber, Geert Uytterhoeven,
Rob Herring, Philipp Zabel, Linus Walleij, Arnd Bergmann,
Stefan Agner, Peter Meerwald, Paul Bolle, Peter Hurley,
Andy Shevchenko, Chanwoo Choi, Russell King, Daniel Lezcano,
Joe Perches, Jonathan Corbet, Pawel Moll, Mark Rutland,
Ian Campbell, Kumar Gala, Thomas Gleixner
In-Reply-To: <552678E7.4040107-nmGgyN9QBj3QT0dZR+AlfA@public.gmane.org>
Hi Vladimir,
Thanks for the review, and sorry for the late reply.
2015-04-09 15:04 GMT+02:00 Vladimir Zapolskiy <vladimir_zapolskiy-nmGgyN9QBj3QT0dZR+AlfA@public.gmane.org>:
> Hi Maxime,
>
> On 07.04.2015 19:30, Maxime Coquelin wrote:
>> This drivers adds support to the STM32 USART controller, which is a
>> standard serial driver.
>>
>> Tested-by: Chanwoo Choi <cw00.choi-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
>> Reviewed-by: Peter Hurley <peter-WaGBZJeGNqdsbIuE7sb01tBPR1lH4CV8@public.gmane.org>
>> Signed-off-by: Maxime Coquelin <mcoquelin.stm32-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
>> ---
>> drivers/tty/serial/Kconfig | 17 +
>> drivers/tty/serial/Makefile | 1 +
>> drivers/tty/serial/stm32-usart.c | 735 +++++++++++++++++++++++++++++++++++++++
>> include/uapi/linux/serial_core.h | 3 +
>> 4 files changed, 756 insertions(+)
>> create mode 100644 drivers/tty/serial/stm32-usart.c
>
> [snip]
>
>> +static void stm32_console_write(struct console *co, const char *s, unsigned cnt)
>> +{
>> + struct uart_port *port = &stm32_ports[co->index].port;
>> + unsigned long flags;
>> + u32 old_cr1, new_cr1;
>> + int locked = 1;
>> +
>> + if (oops_in_progress) {
>> + locked = spin_trylock_irqsave(&port->lock, flags);
>> + } else {
>> + locked = 1; ID
>
> locked = 1 is done from the declaration.
Right, I will fix this in next version
>
> Also do you want to add "if (port->sysrq) locked = 0;" check?
Yes, that makes sense. It will be also in v7.
>
>> + spin_lock_irqsave(&port->lock, flags);
>> + }
>> +
>
> [snip]
>
> Everything else is fine from point of view.
>
> Reviewed-by: Vladimir Zapolskiy <vladimir_zapolskiy-nmGgyN9QBj3QT0dZR+AlfA@public.gmane.org>
Regards,
Maxime
>
> --
> With best wishes,
> Vladimir
^ permalink raw reply
* [RFC 3/3] mm: introduce do_munmap_nofail
From: Michal Hocko @ 2015-04-28 12:11 UTC (permalink / raw)
To: linux-mm-Bw31MaZKKs3YtjvyW6yDsg
Cc: Cyril Hrubis, Andrew Morton, Hugh Dickins, Michel Lespinasse,
Linus Torvalds, Rik van Riel, Michael Kerrisk, LKML, Linux API
In-Reply-To: <1430223111-14817-1-git-send-email-mhocko-AlSwsSmVLrQ@public.gmane.org>
vm_mmap_pgoff with MAP_LOCKED need to call do_munmap in case the
population of the area fails. The operation cannot fail for obvious
reasons. The current code simply retries in the loop which is not
very nice.
This patch introduces do_munmap_nofail() which uses __GFP_NOFAIL
for allocations required down the unmap path. It is always better
to loop inside the allocator rather than outside if there is no
sensible way handle the allocation failure.
Allocator can perform additional steps to help the allocation to
succeed (e.g. can get access to memory reserves).
The caller of the function has to make sure that the mapping is
initialized properly - namely [start, len] correspond to an existing VMA
and that the split doesn't exceed sysctl_max_map_count. This is true for
vm_mmap_pgoff so it is safe to be used in this path. The function is for
internal use only so it is not exported to the rest of the kernel.
While we are at it, let's make nommu shrink_vma return void because it
doesn't have any failing path.
Signed-off-by: Michal Hocko <mhocko-AlSwsSmVLrQ@public.gmane.org>
---
mm/internal.h | 4 ++++
mm/mmap.c | 6 ++++++
mm/nommu.c | 11 ++++++++---
mm/util.c | 15 ++-------------
4 files changed, 20 insertions(+), 16 deletions(-)
diff --git a/mm/internal.h b/mm/internal.h
index a25e359a4039..7f9d1f112d3b 100644
--- a/mm/internal.h
+++ b/mm/internal.h
@@ -415,6 +415,10 @@ extern unsigned long vm_mmap_pgoff(struct file *, unsigned long,
unsigned long, unsigned long,
unsigned long, unsigned long);
+/* Caller has to make sure the [addr, len] corresponds to a valid VMA */
+extern void do_munmap_nofail(struct mm_struct * mm,
+ unsigned long addr, size_t len);
+
extern void set_pageblock_order(void);
unsigned long reclaim_clean_pages_from_list(struct zone *zone,
struct list_head *page_list);
diff --git a/mm/mmap.c b/mm/mmap.c
index 4882008dac83..d54544c7b2ba 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -2612,6 +2612,12 @@ int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
return __do_munmap_gfp(mm, start, len, GFP_KERNEL);
}
+void do_munmap_nofail(struct mm_struct *mm, unsigned long start, size_t len)
+{
+ BUG_ON(__do_munmap_gfp(mm, start, len, GFP_KERNEL|__GFP_NOFAIL));
+}
+
+
int vm_munmap(unsigned long start, size_t len)
{
int ret;
diff --git a/mm/nommu.c b/mm/nommu.c
index f1e7b41a2031..9bdd1dedb4cd 100644
--- a/mm/nommu.c
+++ b/mm/nommu.c
@@ -1628,7 +1628,7 @@ int split_vma(struct mm_struct *mm, struct vm_area_struct *vma,
* shrink a VMA by removing the specified chunk from either the beginning or
* the end
*/
-static int shrink_vma(struct mm_struct *mm,
+static void shrink_vma(struct mm_struct *mm,
struct vm_area_struct *vma,
unsigned long from, unsigned long to)
{
@@ -1661,7 +1661,6 @@ static int shrink_vma(struct mm_struct *mm,
up_write(&nommu_region_sem);
free_page_series(from, to);
- return 0;
}
/*
@@ -1735,7 +1734,8 @@ static int __do_munmap_gfp(struct mm_struct *mm, unsigned long start, size_t len
return ret;
}
}
- return shrink_vma(mm, vma, start, end);
+ shrink_vma(mm, vma, start, end);
+ return;
}
erase_whole_vma:
@@ -1751,6 +1751,11 @@ int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
}
EXPORT_SYMBOL(do_munmap);
+static void do_munmap_nofail(struct mm_struct *mm, unsigned long start, size_t len)
+{
+ BUG_ON(do_munmap(mm, start, len, GFP_KERNEL|__GFP_NOFAIL));
+}
+
int vm_munmap(unsigned long addr, size_t len)
{
struct mm_struct *mm = current->mm;
diff --git a/mm/util.c b/mm/util.c
index fbffefa3b812..ddac3ea918c2 100644
--- a/mm/util.c
+++ b/mm/util.c
@@ -324,21 +324,10 @@ unsigned long vm_mmap_pgoff(struct file *file, unsigned long addr,
*/
if (flag & MAP_LOCKED) {
down_write(&mm->mmap_sem);
- while (!fatal_signal_pending(current)) {
+ if (!fatal_signal_pending(current)) {
mm->map_count--;
need_map_count_fix = false;
- if (!do_munmap(mm, ret, populate))
- break;
-
- /*
- * Do not block other threads to make a progress
- * e.g. madvise
- */
- mm->map_count++;
- need_map_count_fix = true;
- up_write(&mm->mmap_sem);
- cond_resched();
- down_write(&mm->mmap_sem);
+ do_munmap_nofail(mm, ret, populate);
}
up_write(&mm->mmap_sem);
--
2.1.4
^ permalink raw reply related
* [RFC 2/3] mm: allow munmap related functions to understand gfp_mask
From: Michal Hocko @ 2015-04-28 12:11 UTC (permalink / raw)
To: linux-mm
Cc: Cyril Hrubis, Andrew Morton, Hugh Dickins, Michel Lespinasse,
Linus Torvalds, Rik van Riel, Michael Kerrisk, LKML, Linux API
In-Reply-To: <1430223111-14817-1-git-send-email-mhocko@suse.cz>
__split_vma path requires to allocate a memory. Later patch in the
series will require to change standard GFP_KERNEL allocation to use
__GFP_NOFAIL. In order to do that all the allocation paths down this
path should understand gfp requirements of the caller.
This involves vma_dup_policy and vma_adjust which have _gfp variant now
and anon_vma_clone got just a new parameter because it doesn't have
many callers.
The patch doesn't have any runtime effects but it makes the code
slightly larger:
text data bss dec hex filename
511480 74147 44440 630067 99d33 mm/built-in.o.before
511560 74147 44440 630147 99d83 mm/built-in.o.after
Signed-off-by: Michal Hocko <mhocko@suse.cz>
---
include/linux/mempolicy.h | 17 ++++++++++++++---
include/linux/mm.h | 10 ++++++++--
include/linux/rmap.h | 2 +-
mm/mempolicy.c | 9 +++++----
mm/mmap.c | 43 +++++++++++++++++++++++++------------------
mm/nommu.c | 24 ++++++++++++++++++------
mm/rmap.c | 7 ++++---
7 files changed, 75 insertions(+), 37 deletions(-)
diff --git a/include/linux/mempolicy.h b/include/linux/mempolicy.h
index 3d385c81c153..a42585c09d4e 100644
--- a/include/linux/mempolicy.h
+++ b/include/linux/mempolicy.h
@@ -82,11 +82,12 @@ static inline void mpol_cond_put(struct mempolicy *pol)
__mpol_put(pol);
}
-extern struct mempolicy *__mpol_dup(struct mempolicy *pol);
+extern struct mempolicy *mpol_dup_gfp(struct mempolicy *pol,
+ gfp_t gfp_mask);
static inline struct mempolicy *mpol_dup(struct mempolicy *pol)
{
if (pol)
- pol = __mpol_dup(pol);
+ pol = mpol_dup_gfp(pol, GFP_KERNEL);
return pol;
}
@@ -125,7 +126,12 @@ struct shared_policy {
spinlock_t lock;
};
-int vma_dup_policy(struct vm_area_struct *src, struct vm_area_struct *dst);
+int vma_dup_policy_gfp(struct vm_area_struct *src,
+ struct vm_area_struct *dst, gfp_t gfp_mask);
+static inline int
+vma_dup_policy(struct vm_area_struct *src, struct vm_area_struct *dst) {
+ return vma_dup_policy_gfp(src, dst, GFP_KERNEL);
+}
void mpol_shared_policy_init(struct shared_policy *sp, struct mempolicy *mpol);
int mpol_set_shared_policy(struct shared_policy *info,
struct vm_area_struct *vma,
@@ -235,6 +241,11 @@ vma_dup_policy(struct vm_area_struct *src, struct vm_area_struct *dst)
{
return 0;
}
+static inline int
+vma_dup_policy_gfp(struct vm_area_struct *src,
+ struct vm_area_struct *dst, gfp_t gfp_mask) {
+ return 0;
+}
static inline void numa_policy_init(void)
{
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 5d20fba62081..723032a2273f 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -1752,8 +1752,14 @@ void anon_vma_interval_tree_verify(struct anon_vma_chain *node);
/* mmap.c */
extern int __vm_enough_memory(struct mm_struct *mm, long pages, int cap_sys_admin);
-extern int vma_adjust(struct vm_area_struct *vma, unsigned long start,
- unsigned long end, pgoff_t pgoff, struct vm_area_struct *insert);
+extern int vma_adjust_gfp(struct vm_area_struct *vma, unsigned long start,
+ unsigned long end, pgoff_t pgoff, struct vm_area_struct *insert,
+ gfp_t gfp_mask);
+static inline int
+vma_adjust(struct vm_area_struct *vma, unsigned long start,
+ unsigned long end, pgoff_t pgoff, struct vm_area_struct *insert) {
+ return vma_adjust_gfp(vma, start, end, pgoff, insert, GFP_KERNEL);
+}
extern struct vm_area_struct *vma_merge(struct mm_struct *,
struct vm_area_struct *prev, unsigned long addr, unsigned long end,
unsigned long vm_flags, struct anon_vma *, struct file *, pgoff_t,
diff --git a/include/linux/rmap.h b/include/linux/rmap.h
index bf36b6e644c4..23d210b84431 100644
--- a/include/linux/rmap.h
+++ b/include/linux/rmap.h
@@ -147,7 +147,7 @@ static inline void anon_vma_unlock_read(struct anon_vma *anon_vma)
void anon_vma_init(void); /* create anon_vma_cachep */
int anon_vma_prepare(struct vm_area_struct *);
void unlink_anon_vmas(struct vm_area_struct *);
-int anon_vma_clone(struct vm_area_struct *, struct vm_area_struct *);
+int anon_vma_clone(struct vm_area_struct *, struct vm_area_struct *, gfp_t);
int anon_vma_fork(struct vm_area_struct *, struct vm_area_struct *);
static inline void anon_vma_merge(struct vm_area_struct *vma,
diff --git a/mm/mempolicy.c b/mm/mempolicy.c
index ede26291d4aa..9002d0a15d74 100644
--- a/mm/mempolicy.c
+++ b/mm/mempolicy.c
@@ -2060,9 +2060,10 @@ retry_cpuset:
}
EXPORT_SYMBOL(alloc_pages_current);
-int vma_dup_policy(struct vm_area_struct *src, struct vm_area_struct *dst)
+int vma_dup_policy_gfp(struct vm_area_struct *src, struct vm_area_struct *dst,
+ gfp_t gfp_mask)
{
- struct mempolicy *pol = mpol_dup(vma_policy(src));
+ struct mempolicy *pol = mpol_dup_gfp(vma_policy(src), gfp_mask);
if (IS_ERR(pol))
return PTR_ERR(pol);
@@ -2082,9 +2083,9 @@ int vma_dup_policy(struct vm_area_struct *src, struct vm_area_struct *dst)
*/
/* Slow path of a mempolicy duplicate */
-struct mempolicy *__mpol_dup(struct mempolicy *old)
+struct mempolicy *mpol_dup_gfp(struct mempolicy *old, gfp_t gfp_mask)
{
- struct mempolicy *new = kmem_cache_alloc(policy_cache, GFP_KERNEL);
+ struct mempolicy *new = kmem_cache_alloc(policy_cache, gfp_mask);
if (!new)
return ERR_PTR(-ENOMEM);
diff --git a/mm/mmap.c b/mm/mmap.c
index bb50cacc3ea5..4882008dac83 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -719,8 +719,9 @@ __vma_unlink(struct mm_struct *mm, struct vm_area_struct *vma,
* are necessary. The "insert" vma (if any) is to be inserted
* before we drop the necessary locks.
*/
-int vma_adjust(struct vm_area_struct *vma, unsigned long start,
- unsigned long end, pgoff_t pgoff, struct vm_area_struct *insert)
+int vma_adjust_gfp(struct vm_area_struct *vma, unsigned long start,
+ unsigned long end, pgoff_t pgoff, struct vm_area_struct *insert,
+ gfp_t gfp_mask)
{
struct mm_struct *mm = vma->vm_mm;
struct vm_area_struct *next = vma->vm_next;
@@ -773,7 +774,7 @@ again: remove_next = 1 + (end > next->vm_end);
int error;
importer->anon_vma = exporter->anon_vma;
- error = anon_vma_clone(importer, exporter);
+ error = anon_vma_clone(importer, exporter, gfp_mask);
if (error)
return error;
}
@@ -2435,11 +2436,11 @@ detach_vmas_to_be_unmapped(struct mm_struct *mm, struct vm_area_struct *vma,
}
/*
- * __split_vma() bypasses sysctl_max_map_count checking. We use this on the
+ * __split_vma_gfp() bypasses sysctl_max_map_count checking. We use this on the
* munmap path where it doesn't make sense to fail.
*/
-static int __split_vma(struct mm_struct *mm, struct vm_area_struct *vma,
- unsigned long addr, int new_below)
+static int __split_vma_gfp(struct mm_struct *mm, struct vm_area_struct *vma,
+ unsigned long addr, int new_below, gfp_t gfp_mask)
{
struct vm_area_struct *new;
int err = -ENOMEM;
@@ -2448,7 +2449,7 @@ static int __split_vma(struct mm_struct *mm, struct vm_area_struct *vma,
~(huge_page_mask(hstate_vma(vma)))))
return -EINVAL;
- new = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
+ new = kmem_cache_alloc(vm_area_cachep, gfp_mask);
if (!new)
goto out_err;
@@ -2464,11 +2465,11 @@ static int __split_vma(struct mm_struct *mm, struct vm_area_struct *vma,
new->vm_pgoff += ((addr - vma->vm_start) >> PAGE_SHIFT);
}
- err = vma_dup_policy(vma, new);
+ err = vma_dup_policy_gfp(vma, new, gfp_mask);
if (err)
goto out_free_vma;
- err = anon_vma_clone(new, vma);
+ err = anon_vma_clone(new, vma, gfp_mask);
if (err)
goto out_free_mpol;
@@ -2479,10 +2480,10 @@ static int __split_vma(struct mm_struct *mm, struct vm_area_struct *vma,
new->vm_ops->open(new);
if (new_below)
- err = vma_adjust(vma, addr, vma->vm_end, vma->vm_pgoff +
- ((addr - new->vm_start) >> PAGE_SHIFT), new);
+ err = vma_adjust_gfp(vma, addr, vma->vm_end, vma->vm_pgoff +
+ ((addr - new->vm_start) >> PAGE_SHIFT), new, gfp_mask);
else
- err = vma_adjust(vma, vma->vm_start, addr, vma->vm_pgoff, new);
+ err = vma_adjust_gfp(vma, vma->vm_start, addr, vma->vm_pgoff, new, gfp_mask);
/* Success. */
if (!err)
@@ -2512,7 +2513,7 @@ int split_vma(struct mm_struct *mm, struct vm_area_struct *vma,
if (mm->map_count >= sysctl_max_map_count)
return -ENOMEM;
- return __split_vma(mm, vma, addr, new_below);
+ return __split_vma_gfp(mm, vma, addr, new_below, GFP_KERNEL);
}
/* Munmap is split into 2 main parts -- this part which finds
@@ -2520,7 +2521,8 @@ int split_vma(struct mm_struct *mm, struct vm_area_struct *vma,
* work. This now handles partial unmappings.
* Jeremy Fitzhardinge <jeremy@goop.org>
*/
-int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
+static int __do_munmap_gfp(struct mm_struct *mm, unsigned long start, size_t len,
+ gfp_t gfp_mask)
{
unsigned long end;
struct vm_area_struct *vma, *prev, *last;
@@ -2562,7 +2564,7 @@ int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
if (end < vma->vm_end && mm->map_count >= sysctl_max_map_count)
return -ENOMEM;
- error = __split_vma(mm, vma, start, 0);
+ error = __split_vma_gfp(mm, vma, start, 0, gfp_mask);
if (error)
return error;
prev = vma;
@@ -2571,7 +2573,7 @@ int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
/* Does it split the last one? */
last = find_vma(mm, end);
if (last && end > last->vm_start) {
- int error = __split_vma(mm, last, end, 1);
+ int error = __split_vma_gfp(mm, last, end, 1, gfp_mask);
if (error)
return error;
}
@@ -2605,6 +2607,11 @@ int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
return 0;
}
+int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
+{
+ return __do_munmap_gfp(mm, start, len, GFP_KERNEL);
+}
+
int vm_munmap(unsigned long start, size_t len)
{
int ret;
@@ -2943,10 +2950,10 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap,
new_vma->vm_start = addr;
new_vma->vm_end = addr + len;
new_vma->vm_pgoff = pgoff;
- if (vma_dup_policy(vma, new_vma))
+ if (vma_dup_policy_gfp(vma, new_vma, GFP_KERNEL))
goto out_free_vma;
INIT_LIST_HEAD(&new_vma->anon_vma_chain);
- if (anon_vma_clone(new_vma, vma))
+ if (anon_vma_clone(new_vma, vma, GFP_KERNEL))
goto out_free_mempol;
if (new_vma->vm_file)
get_file(new_vma->vm_file);
diff --git a/mm/nommu.c b/mm/nommu.c
index 3fba2dc97c44..f1e7b41a2031 100644
--- a/mm/nommu.c
+++ b/mm/nommu.c
@@ -1556,8 +1556,8 @@ SYSCALL_DEFINE1(old_mmap, struct mmap_arg_struct __user *, arg)
* split a vma into two pieces at address 'addr', a new vma is allocated either
* for the first part or the tail.
*/
-int split_vma(struct mm_struct *mm, struct vm_area_struct *vma,
- unsigned long addr, int new_below)
+static int __split_vma_gfp(struct mm_struct *mm, struct vm_area_struct *vma,
+ unsigned long addr, int new_below, gfp_t gfp_mask)
{
struct vm_area_struct *new;
struct vm_region *region;
@@ -1573,11 +1573,11 @@ int split_vma(struct mm_struct *mm, struct vm_area_struct *vma,
if (mm->map_count >= sysctl_max_map_count)
return -ENOMEM;
- region = kmem_cache_alloc(vm_region_jar, GFP_KERNEL);
+ region = kmem_cache_alloc(vm_region_jar, gfp_mask);
if (!region)
return -ENOMEM;
- new = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
+ new = kmem_cache_alloc(vm_area_cachep, gfp_mask);
if (!new) {
kmem_cache_free(vm_region_jar, region);
return -ENOMEM;
@@ -1618,6 +1618,12 @@ int split_vma(struct mm_struct *mm, struct vm_area_struct *vma,
return 0;
}
+int split_vma(struct mm_struct *mm, struct vm_area_struct *vma,
+ unsigned long addr, int new_below)
+{
+ return __split_vma_gfp(mm, vma, addr, new_below, GFP_KERNEL);
+}
+
/*
* shrink a VMA by removing the specified chunk from either the beginning or
* the end
@@ -1663,7 +1669,8 @@ static int shrink_vma(struct mm_struct *mm,
* - under NOMMU conditions the chunk to be unmapped must be backed by a single
* VMA, though it need not cover the whole VMA
*/
-int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
+static int __do_munmap_gfp(struct mm_struct *mm, unsigned long start, size_t len
+ gfp_t gfp_mask)
{
struct vm_area_struct *vma;
unsigned long end;
@@ -1722,7 +1729,7 @@ int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
return -EINVAL;
}
if (start != vma->vm_start && end != vma->vm_end) {
- ret = split_vma(mm, vma, start, 1);
+ ret = __split_vma_gfp(mm, vma, start, 1, gfp_mask);
if (ret < 0) {
kleave(" = %d [split]", ret);
return ret;
@@ -1737,6 +1744,11 @@ erase_whole_vma:
kleave(" = 0");
return 0;
}
+
+int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
+{
+ return __do_munmap_gfp(mm, start, len, GFP_KERNEL);
+}
EXPORT_SYMBOL(do_munmap);
int vm_munmap(unsigned long addr, size_t len)
diff --git a/mm/rmap.c b/mm/rmap.c
index dad23a43e42c..e10101940031 100644
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -249,7 +249,8 @@ static inline void unlock_anon_vma_root(struct anon_vma *root)
* good chance of avoiding scanning the whole hierarchy when it searches where
* page is mapped.
*/
-int anon_vma_clone(struct vm_area_struct *dst, struct vm_area_struct *src)
+int anon_vma_clone(struct vm_area_struct *dst, struct vm_area_struct *src,
+ gfp_t gfp_mask)
{
struct anon_vma_chain *avc, *pavc;
struct anon_vma *root = NULL;
@@ -261,7 +262,7 @@ int anon_vma_clone(struct vm_area_struct *dst, struct vm_area_struct *src)
if (unlikely(!avc)) {
unlock_anon_vma_root(root);
root = NULL;
- avc = anon_vma_chain_alloc(GFP_KERNEL);
+ avc = anon_vma_chain_alloc(gfp_mask);
if (!avc)
goto enomem_failure;
}
@@ -320,7 +321,7 @@ int anon_vma_fork(struct vm_area_struct *vma, struct vm_area_struct *pvma)
* First, attach the new VMA to the parent VMA's anon_vmas,
* so rmap can find non-COWed pages in child processes.
*/
- error = anon_vma_clone(vma, pvma);
+ error = anon_vma_clone(vma, pvma, GFP_KERNEL);
if (error)
return error;
--
2.1.4
--
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 related
* [RFC 1/3] mm: mmap make MAP_LOCKED really mlock semantic
From: Michal Hocko @ 2015-04-28 12:11 UTC (permalink / raw)
To: linux-mm
Cc: Cyril Hrubis, Andrew Morton, Hugh Dickins, Michel Lespinasse,
Linus Torvalds, Rik van Riel, Michael Kerrisk, LKML, Linux API
In-Reply-To: <1430223111-14817-1-git-send-email-mhocko@suse.cz>
Cyril has encountered one of the LTP tests failing after 3.12 kernel.
To quote him:
"
What the test does is to set memory limit inside of memcg to PAGESIZE by
writing to memory.limit_in_bytes, then runs a subprocess that uses
mmap() with MAP_LOCKED which allocates 2 * PAGESIZE and expects that
it's killed by OOM. This does not happen and the call to mmap() returns
a correct pointer to a memory region, that when accessed finally causes
the OOM.
"
The difference came from the memcg OOM killer rework because OOM killer
is triggered only from the page fault path since 519e52473ebe (mm:
memcg: enable memcg OOM killer only for user faults). The rationale is
described in 3812c8c8f395 (mm: memcg: do not trap chargers with full
callstack on OOM).
This is _not_ the primary _issue_, though. It has just made a long
standing issue visible. The same is possible even without memcg but it
is much less likely (it might get more visible once we start failing
GFP_KERNEL small allocations). The primary issue is that mmap doesn't
report a failure if MAP_LOCKED fails to populate the area.
The man page however says
"
MAP_LOCKED (since Linux 2.5.37)
Lock the pages of the mapped region into memory in the manner of
mlock(2). This flag is ignored in older kernels.
"
and mlock is required to fail if the population fails.
"
mlock() locks pages in the address range starting at addr and
continuing for len bytes. All pages that contain a part of the
specified address range are guaranteed to be resident in RAM when
the call returns successfully; the pages are guaranteed to stay
in RAM until later unlocked.
"
According to the git history this has alaways been the case so it
doesn't look like anything new. Most applications probably even do not
care because they do not explicitly require the population at the mmap
call time. If the application cannot tolerate later pagefault this would
be an unexpected and potentially silent failure though.
This patch fixes the behavior to really mimic mlock so mmap fails
if the population is not successful. The only issue here is that
we cannot leave the already created VMA behind and so it has to be
unmapped which as an operation which might fail.
There are basically two potential reasons for a failure. Either the
map count limit could have been reached after we have dropped mmap_sem
for write when doing do_mmap_pgoff or any of the allocations during vma
splitting fails.
The first one is easy to solve because we can elevate map_count while we
are still holding mmap_sem before calling do_mmap_pgoff when MAP_LOCKED
is specified. In the worst case do_munmap would need to split VMA in the
middle and we would simply consume a cached map_count.
The allocation failure down the do_munmap path is the tricky one, albeit
only theoretical one right now because small allocations do not fail yet
(this sounds like something that might change in the future though). There
are more allocations places (e.g. in __split_vma) and those are allowed to fail.
Let's keep retrying do_munmap, drop the semaphore each round to allow other
threads to make a progress (e.g. madvise to free some memory) and hope we will
be able to do it sooner or later.
An alternative would be making all of do_munmap allocations non failing
by using __GFP_NOFAIL or killing the task but that sounds too harsh.
Reported-by: Cyril Hrubis <chrubis@suse.cz>
Signed-off-by: Michal Hocko <mhocko@suse.cz>
---
mm/util.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
1 file changed, 59 insertions(+), 7 deletions(-)
diff --git a/mm/util.c b/mm/util.c
index 0c7f65e7ef5e..fbffefa3b812 100644
--- a/mm/util.c
+++ b/mm/util.c
@@ -290,16 +290,68 @@ unsigned long vm_mmap_pgoff(struct file *file, unsigned long addr,
unsigned long ret;
struct mm_struct *mm = current->mm;
unsigned long populate;
+ bool need_map_count_fix = false;
ret = security_mmap_file(file, prot, flag);
- if (!ret) {
- down_write(&mm->mmap_sem);
- ret = do_mmap_pgoff(file, addr, len, prot, flag, pgoff,
- &populate);
- up_write(&mm->mmap_sem);
- if (populate)
- mm_populate(ret, populate);
+ if (ret)
+ return ret;
+
+ down_write(&mm->mmap_sem);
+ /*
+ * Reserve one slot for a cleanup should __mm_populate fail
+ * and we would need to split VMA in the middle.
+ */
+ if (flag & MAP_LOCKED) {
+ mm->map_count++;
+ need_map_count_fix = true;
+ }
+ ret = do_mmap_pgoff(file, addr, len, prot, flag, pgoff,
+ &populate);
+ up_write(&mm->mmap_sem);
+
+ if (populate) {
+ int error;
+
+ error = __mm_populate(ret, populate, 0);
+ if (!error)
+ return ret;
+
+ /*
+ * MAP_LOCKED has a mlock semantic so we have to
+ * fail mmap call if the population fails.
+ * Regular MAP_POPULATE can tolerate the failure
+ * though.
+ */
+ if (flag & MAP_LOCKED) {
+ down_write(&mm->mmap_sem);
+ while (!fatal_signal_pending(current)) {
+ mm->map_count--;
+ need_map_count_fix = false;
+ if (!do_munmap(mm, ret, populate))
+ break;
+
+ /*
+ * Do not block other threads to make a progress
+ * e.g. madvise
+ */
+ mm->map_count++;
+ need_map_count_fix = true;
+ up_write(&mm->mmap_sem);
+ cond_resched();
+ down_write(&mm->mmap_sem);
+ }
+ up_write(&mm->mmap_sem);
+
+ ret = -ENOMEM;
+ }
+ }
+
+ if (need_map_count_fix) {
+ down_read(&mm->mmap_sem);
+ mm->map_count--;
+ up_read(&mm->mmap_sem);
}
+
return ret;
}
--
2.1.4
--
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 related
* Re: Should mmap MAP_LOCKED fail if mm_poppulate fails?
From: Michal Hocko @ 2015-04-28 12:11 UTC (permalink / raw)
To: linux-mm-Bw31MaZKKs3YtjvyW6yDsg
Cc: Cyril Hrubis, Andrew Morton, Hugh Dickins, Michel Lespinasse,
Linus Torvalds, Rik van Riel, Michael Kerrisk, LKML, Linux API
In-Reply-To: <20150114095019.GC4706-2MMpYkNvuYDjFM9bn6wA6Q@public.gmane.org>
Hi,
it seems that the initial email got lost (or ignored). I would like to
revive it again. I've cooked up a potential fix to this issue which will
follow as a reply to this email.
The first patch is dumb and straightforward. It should be safe as is and
also good without the follow up 2 patches which try to handle potential
allocation failures in the do_munmap path more gracefully. As we still
do not fail small allocations even the first patch could be simplified
a bit and the retry loop replaced by a BUG_ON right away. But I felt this
would better be done robust.
An obvious alternative would be patching the man pages to mention the
subtle difference between mlock and MAP_LOCKED semantic. I have checked
debian code search and it shown some applications relying on MAP_LOCKED
but I have no idea whether they really require the mlock all-or-nothing
fault in semantic.
Any thoughts, ideas?
^ permalink raw reply
* Re: [PATCH] usb: core: add usb3 lpm sysfs
From: Greg KH @ 2015-04-28 10:42 UTC (permalink / raw)
To: Zhuang Jin Can
Cc: rafael.j.wysocki-ral2JQCrhuEAvxtiuMwx3w,
stern-nwvwT67g6+6dFdvTe/nMLpVzexx5G7lz,
dan.j.williams-ral2JQCrhuEAvxtiuMwx3w, pmladek-AlSwsSmVLrQ,
peter.chen-KZfg59tc24xl57MIdRCFDg, jwerner-F7+t8E8rja9g9hUCZPvPmw,
linux-api-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-usb-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20150419034612.GA31576-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
On Sun, Apr 19, 2015 at 11:46:12AM +0800, Zhuang Jin Can wrote:
> Some usb3 devices may not support usb3 lpm well.
> The patch adds a sysfs to enable/disable u1 or u2 of the port.The
> settings apply to both before and after device enumeration.
> Supported values are "0" - u1 and u2 are disabled, "u1" - only u1 is
> enabled, "u2" - only u2 is enabled, "u1_u2" - u1 and u2 are enabled.
>
> The interface is useful for testing some USB3 devices during
> development, and provides a way to disable usb3 lpm if the issues can
> not be fixed in final products.
How is a user supposed to "know" to make this setting for a device? Why
can't the kernel automatically set this value properly? Why does it
need to be a kernel issue at all?
And when you are doing development of broken devices, the kernel doesn't
have to support you, you can run with debugging patches of your own
until you fix your firmware :)
thanks,
greg k-h
^ permalink raw reply
* Re: [RFC v2 1/4] fs: Add generic file system event notifications
From: Beata Michalska @ 2015-04-28 9:05 UTC (permalink / raw)
To: Greg KH
Cc: linux-kernel, linux-fsdevel, linux-api, jack, tytso,
adilger.kernel, hughd, lczerner, hch, linux-ext4, linux-mm,
kyungmin.park, kmpark
In-Reply-To: <20150427153711.GA23428@kroah.com>
Hi,
On 04/27/2015 05:37 PM, Greg KH wrote:
> On Mon, Apr 27, 2015 at 05:08:27PM +0200, Beata Michalska wrote:
>> On 04/27/2015 04:24 PM, Greg KH wrote:
>>> On Mon, Apr 27, 2015 at 01:51:41PM +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.
>>>>
>>>> Signed-off-by: Beata Michalska <b.michalska@samsung.com> ---
>>>> Documentation/filesystems/events.txt | 231 ++++++++++
>>>> fs/Makefile | 1 +
>>>> fs/events/Makefile | 6 +
>>>> fs/events/fs_event.c | 770
>>>> ++++++++++++++++++++++++++++++++++ fs/events/fs_event.h | 25
>>>> ++ fs/events/fs_event_netlink.c | 99 +++++
>>>> fs/namespace.c | 1 +
>>>> include/linux/fs.h | 6 +-
>>>> include/linux/fs_event.h | 58 +++
>>>> include/uapi/linux/fs_event.h | 54 +++
>>>> include/uapi/linux/genetlink.h | 1 +
>>>> net/netlink/genetlink.c | 7 +- 12 files
>>>> changed, 1257 insertions(+), 2 deletions(-) create mode 100644
>>>> Documentation/filesystems/events.txt create mode 100644
>>>> fs/events/Makefile create mode 100644 fs/events/fs_event.c
>>>> create mode 100644 fs/events/fs_event.h create mode 100644
>>>> fs/events/fs_event_netlink.c create mode 100644
>>>> include/linux/fs_event.h create mode 100644
>>>> include/uapi/linux/fs_event.h
>>>
>>> Any reason why you just don't do uevents for the block devices
>>> today, and not create a new type of netlink message and userspace
>>> tool required to read these?
>>
>> The idea here is to have support for filesystems with no backing
>> device as well. Parsing the message with libnl is really simple and
>> requires few lines of code (sample application has been presented
>> in the initial version of this RFC)
>
> I'm not saying it's not "simple" to parse, just that now you are
> doing something that requires a different tool. If you have a block
> device, you should be able to emit uevents for it, you don't need a
> backing device, we handle virtual filesystems in /sys/block/ just
> fine :)
>
The generic netlink interface is already being used by quota. As this is to
support file system events, including the threshold notifications, it just
seemed like a nice extension. I'm not really convinced that the concept here
goes well with the uevents and it's current usage. On the other hand, GFS2
already benefits form it. Still the generic netlink seems somehow ... lighter.
Anyway I'm open to any suggestions :)
> People already have tools that listen to libudev for system
> monitoring and management, why require them to hook up to
> yet-another-library? And what is going to provide the ability for
> multiple userspace tools to listen to these netlink messages in case
> you have more than one program that wants to watch for these things
> (i.e. multiple desktop filesystem monitoring tools, system-health
> checkers, etc.)?
>
I might be missing smth here, but any application might subscribe to
the multicast group so I'm not sure I understand your concerns here (?)
>>>> --- a/fs/Makefile +++ b/fs/Makefile @@ -126,3 +126,4 @@ obj-y
>>>> += exofs/ # Multiple modules obj-$(CONFIG_CEPH_FS) += ceph/
>>>> obj-$(CONFIG_PSTORE) += pstore/ obj-$(CONFIG_EFIVAR_FS) +=
>>>> efivarfs/ +obj-y += events/
>>>
>>> Always?
>>>
>>>> diff --git a/fs/events/Makefile b/fs/events/Makefile new file
>>>> mode 100644 index 0000000..58d1454 --- /dev/null +++
>>>> b/fs/events/Makefile @@ -0,0 +1,6 @@ +# +# Makefile for the
>>>> Linux Generic File System Event Interface +# + +obj-y :=
>>>> fs_event.o
>>>
>>> Always? Even if the option is not selected? Why is everyone
>>> forced to always use this code? Can't you disable it for the
>>> "tiny" systems that don't need it?
>>>
>>
>> I was considering making it optional and I guess it's worth getting
>> back to this idea.
>
> The "linux-tiny" people will appreciate that :)
>
Consider it done for the next round.
>>>> +struct fs_trace_entry { + atomic_t count;
>>>
>>> Why not just use a 'struct kref' for your count, which will save
>>> a bunch of open-coding of reference counting, and forcing us to
>>> audit your code to verify you got all the corner cases correct?
>>> :)
>>>
>>>> + atomic_t active; + struct super_block *sb;
>>
>> Not sure if using kref would change much here as the kref would not
>> really make it easier to verify those corner cases, unfortunately.
>
> Why not, that's the goal of a kref. Yes, you already did the hard
> work, but now you require everyone else to also do the hard work of
> trying to audit your code. That's why we have common functions/data
> structures in the kernel, to make long-term maintenance easier.
>
> Please switch to make it so that we "know" you are doing this
> correctly.
>
Alright, if this is to make the review any easier I'll do that.
Still it's gonna be replacing fs_trace_entry_get/put with kref
and I doubt it will help verifying if the references are being
acquired / released properly.
>>> Are you properly reference counting this pointer? I didn't see
>>> where that was happening, so I must have missed it.
>>>
>>> thanks,
>>>
>>
>> You haven't. And if I haven't missed anything, the sb is being used
>> only as long as the super is alive.
>
> How do you know that? :)
>
>> Most of the code operates on sb only if it was explicitly asked to,
>> through call from filesystem. There is also a callback notifying of
>> mount being dropped (which proceeds the call to kill_super) that
>> invalidates the object that depends on it. Still, it should be
>> explicitly stated that the sb is being used through bidding up the
>> s_count counter, though that would require taking the sb_lock.
>> AFAIK, one can get the reference to super block but for a
>> particular device. Maybe it would be worth having it more generic
>> (?).
>
> Why not just grab a reference to the sb when you save the pointer,
> and release it when you are done with it? That should handle the
> lifecycle properly. It's always a very bad idea to have a pointer to
> a reference counted object without actually grabbing the reference,
> as you have no idea what is happening with it behind your back.
>
Ok, will do.
> thanks,
>
> greg k-h
>
Thanks for your comments so far. Much appreciated.
BR
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: [PATCH 01/11] coresight-etm4x: Adding CoreSight ETM4x driver
From: Ivan T. Ivanov @ 2015-04-28 8:30 UTC (permalink / raw)
To: Mathieu Poirier
Cc: Greg KH,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org,
linux-api-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Kaixu Xia,
Chunyan Zhang
In-Reply-To: <CANLsYky6TZhZ=JZuoBxU4dNRWVPYGUj6joMfi+dD9zjaokRE0A-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
On Mon, 2015-04-27 at 09:48 -0600, Mathieu Poirier wrote:
> On 24 April 2015 at 09:41, Ivan T. Ivanov <iivanov-NEYub+7Iv8PQT0dZR+AlfA@public.gmane.org> wrote:
> > On Wed, 2015-04-22 at 16:40 -0600, Mathieu Poirier wrote:
> >
> > > +static struct amba_id etm4_ids[] = {
> > > + { /* ETM 4.0 - Hi6220 board */
> > > + .id = 0x0003b95d,
> > > + .mask = 0x0003ffff,
> > > + .data = "ETM 4.0",
> > > + },
> > > + { /* ETM 4.0 - Juno board */
> > > + .id = 0x000bb95e,
> > > + .mask = 0x000bffff,
> >
> > Mask looks suspicious.
>
> Can you please expand the "suspicious" part ?
Well, 'b' part of the mask. I have to admit that
I don't know how this is mapped on this platform.
Regards,
Ivan
^ permalink raw reply
* Re: [v14 3/4] ext4: adds FS_IOC_FSSETXATTR/FS_IOC_FSGETXATTR interface support
From: Dave Chinner @ 2015-04-28 4:43 UTC (permalink / raw)
To: Li Xi
Cc: linux-fsdevel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Ext4 Developers List,
linux-api-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Theodore Ts'o, Andreas Dilger, Jan Kara,
viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn@public.gmane.org,
hch-wEGCiKHe2LqWVfeAwA7xHQ@public.gmane.org, Dmitry Monakhov
In-Reply-To: <CAPTn0cAHOHP060cW8k0-HnyfKdVaUwAVOyLZU43AXtECK6_EaA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
On Tue, Apr 28, 2015 at 10:01:07AM +0800, Li Xi wrote:
> Hi Dave,
>
> I ran xfstests on the kernel with this series of patches.
> Unfortunately, 5 test suits failed. But I don't think they are caused
> by this patch. Following is the result. Please let me know if there is
> any problem about it.
>
> Output of xfstests:
>
> FSTYP -- xfs (non-debug)
> PLATFORM -- Linux/x86_64 vm15 4.0.0+
> MKFS_OPTIONS -- -f -bsize=4096 /dev/sdb2
> MOUNT_OPTIONS -- /dev/sdb2 /mnt/scratch
>
> generic/001 3s ... 2s
> generic/002 0s ... 0s
> generic/003 10s ... 10s
> generic/004 [not run] xfs_io flink support is missing
> generic/005 0s ... 0s
> generic/006 1s ... 0s
> generic/007 0s ... 0s
> generic/008 [not run] xfs_io fzero support is missing
> generic/009 [not run] xfs_io fzero support is missing
> generic/010 1s ... 0s
> generic/011 1s ... 0s
> generic/012 [not run] xfs_io fpunch support is missing
> generic/013 92s ... 90s
> generic/014 3s ... 3s
> generic/015 1s ... 1s
> generic/016 [not run] xfs_io fpunch support is missing
> generic/017 [not run] xfs_io fiemap support is missing
> generic/018 [not run] xfs_io fiemap support is missing
You really need to update your xfsprogs install. You aren't testing
half of what you need to be testing if you are missing basic
functionality like fiemap support (which has been in xfs_io since
2011).
> generic/020 38s ... 31s
> generic/021 [not run] xfs_io fpunch support is missing
> generic/022 [not run] xfs_io fpunch support is missing
> generic/023 1s ... 0s
> generic/024 1s ... 0s
> generic/025 0s ... 0s
> generic/026 0s ... 0s
> generic/027 57s ... 57s
> generic/028 5s ... 5s
> generic/053 1s ... 2s
> generic/062 1s ... 2s
> generic/068 60s ... 61s
> generic/069 4s ... 3s
> generic/070 13s ... 14s
> generic/074 164s ... 162s
> generic/075 87s ... 86s
> generic/076 1s ... 1s
> generic/077 [not run] fsgqa user not defined.
ANd if you don't have this user defined, then several quota tests
don't get run.
> generic/079 1s ... 1s
> generic/083 36s ... 39s
> generic/088 1s ... 0s
> generic/089 4s ... 4s
> generic/091 62s ... 62s
> generic/093 [not run] not suitable for this OS: Linux
> generic/097 [not run] not suitable for this OS: Linux
> generic/099 [not run] not suitable for this OS: Linux
> generic/100 12s ... 12s
> generic/105 0s ... 0s
> generic/112 [not run] fsx not built with AIO for this platform
> generic/113 [not run] aio-stress not built for this platform
Ouch. There's another whole class of functionality you aren't
testing.
> generic/299 [not run] utility required, skipped this test
> generic/300 [not run] xfs_io fpunch support is missing
> generic/306 - output mismatch (see
> /root/work/quota/ext4_inode_field/xfstests.git/results//generic/306.out.bad)
> --- tests/generic/306.out 2014-07-16 10:19:26.196995657 +0800
> +++ /root/work/quota/ext4_inode_field/xfstests.git/results//generic/306.out.bad
> 2015-04-27 22:40:13.365445316 +0800
> @@ -2,11 +2,9 @@
> == try to create new file
> touch: cannot touch 'SCRATCH_MNT/this_should_fail': Read-only file system
> == pwrite to null device
> -wrote 512/512 bytes at offset 0
> -XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
> +xfs_io: specified file ["/mnt/scratch/devnull"] is not on an XFS filesystem
> == pread from zero device
> ...
> (Run 'diff -u tests/generic/306.out
> /root/work/quota/ext4_inode_field/xfstests.git/results//generic/306.out.bad'
> to see the entire diff)
That's caused by having a very old xfs_io.
> xfs/229 134s ... [failed, exit status 23] - output mismatch (see
> /root/work/quota/ext4_inode_field/xfstests.git/results//xfs/229.out.bad)
> --- tests/xfs/229.out 2014-07-16 10:19:26.215995657 +0800
> +++ /root/work/quota/ext4_inode_field/xfstests.git/results//xfs/229.out.bad
> 2015-04-27 23:25:48.709093428 +0800
> @@ -1,4 +1,31 @@
> QA output created by 229
> generating 10 files
> +Write did not return correct amount
> +Write did not return correct amount
> +Write did not return correct amount
> +Write did not return correct amount
> comparing files
Can't say that I've seen that one fail for a long time. I can't say
anything useful about it, however, given how old your xfsprogs
installation is.
> ...
> (Run 'diff -u tests/xfs/229.out
> /root/work/quota/ext4_inode_field/xfstests.git/results//xfs/229.out.bad'
> to see the entire diff)
> xfs/238 1s ... 1s
> xfs/242 [not run] zero command not supported
> xfs/244 2s ... 2s
> xfs/250 [failed, exit status 1] - output mismatch (see
> /root/work/quota/ext4_inode_field/xfstests.git/results//xfs/250.out.bad)
> --- tests/xfs/250.out 2014-07-16 10:19:26.215995657 +0800
> +++ /root/work/quota/ext4_inode_field/xfstests.git/results//xfs/250.out.bad
> 2015-04-27 23:26:15.137452337 +0800
> @@ -11,4 +11,4 @@
> *** preallocate large file
> *** unmount loop filesystem
> *** check loop filesystem
> -*** done
> +_check_xfs_filesystem: filesystem on /mnt/test/250.fs is
> inconsistent (r) (see
> /root/work/quota/ext4_inode_field/xfstests.git/results//xfs/250.full)
> ...
> (Run 'diff -u tests/xfs/250.out
> /root/work/quota/ext4_inode_field/xfstests.git/results//xfs/250.out.bad'
> to see the entire diff)
Your xfstests is not up to date. This is fixed by commit ee6ad7f
("xfs/049: umount -d fails when kernel wins teardown race").
> xfs/301 - output mismatch (see
> /root/work/quota/ext4_inode_field/xfstests.git/results//xfs/301.out.bad)
> --- tests/xfs/301.out 2014-07-16 10:19:26.217995657 +0800
> +++ /root/work/quota/ext4_inode_field/xfstests.git/results//xfs/301.out.bad
> 2015-04-27 23:33:33.629182381 +0800
> @@ -29,18 +29,21 @@
> Attribute "attr4" had a 10 byte value for DUMP_DIR/sub/biggg:
> some_text4
> EAs on restore
> +getfattr: /mnt/scratch/restoredir/dumpdir: No such file or directory
> +getfattr: /mnt/scratch/restoredir/dumpdir: No such file or directory
> User names
> -Attribute "attr5" had a 8 byte value for DUMP_DIR/dir:
> ...
> (Run 'diff -u tests/xfs/301.out
$ ./lsqa.pl tests/xfs/301
FS QA Test No. 301
Verify multi-stream xfsdump/restore preserves extended attributes
$
Your xfsdump package is out of date and needs upgrading.
> /root/work/quota/ext4_inode_field/xfstests.git/results//xfs/301.out.bad'
> to see the entire diff)
> xfs/302 [failed, exit status 1] - output mismatch (see
> /root/work/quota/ext4_inode_field/xfstests.git/results//xfs/302.out.bad)
> --- tests/xfs/302.out 2014-07-16 10:19:26.217995657 +0800
> +++ /root/work/quota/ext4_inode_field/xfstests.git/results//xfs/302.out.bad
> 2015-04-27 23:33:46.102767709 +0800
> @@ -1,2 +1,4 @@
> QA output created by 302
> Silence is golden.
> +dump failed
> +(see /root/work/quota/ext4_inode_field/xfstests.git/results//xfs/302.full
> for details)
> ...
> (Run 'diff -u tests/xfs/302.out
> /root/work/quota/ext4_inode_field/xfstests.git/results//xfs/302.out.bad'
> to see the entire diff)
Same again.
You need to upgrade everything to current xfstests/xfsprogs/xfsdump
and retest *everything*. That means rerunning all your ext4 testing,
too, because you're not exercising all the cases where the
interesting accounting bugs lie (i.e. in fallocate operations).
I'd also suggest that you run the tests using MOUNT_OPTIONS="-o
pquota" after setting up default configurations for TEST_MNT and
SCRATCH_MNT so that you actually give the project quota code a
significant amount of work to do, and do the same for ext4,
otherwise you're not really testing it at all when you run xfstests
on ext4....
Cheers,
Dave.
--
Dave Chinner
david-FqsqvQoI3Ljby3iVrkZq2A@public.gmane.org
^ permalink raw reply
* Re: [RFC PATCH 3/3] iio: derive the mounting matrix from ACPI _PLD objects
From: Octavian Purdila @ 2015-04-28 2:23 UTC (permalink / raw)
To: sathyanarayanan.kuppuswamy
Cc: Jonathan Cameron, Lars-Peter Clausen, Peter Meerwald,
Robert Moore, Rafael J Wysocki, lenb, linux-api, lkml,
linux-iio@vger.kernel.org, linux-acpi@vger.kernel.org,
Srinivas Pandruvada
In-Reply-To: <553EB0B3.5000707@linux.intel.com>
On Tue, Apr 28, 2015 at 12:57 AM, sathyanarayanan kuppuswamy
<sathyanarayanan.kuppuswamy@linux.intel.com> wrote:
> Hi
>
> On 04/27/2015 08:54 AM, Octavian Purdila wrote:
>>
>> On Mon, Apr 27, 2015 at 6:42 PM, Kuppuswamy Sathyanarayanan
>> <sathyanarayanan.kuppuswamy@linux.intel.com> wrote:
>>>
>>> Since Acpi framework already exports this info to user space, Why not do
>>> this derivation in user space code ? Why do we need new ABI, if the same
>>> can be derived from existing one.
>>>
>> The ABI was added in the previous patch so that we can present the
>> sensor orientation information to userspace even in the case of device
>> tree.
>
> If the main reason for implementing a new ABI is to support DT platforms,
> Why not implement a version of _PLD for device tree ? Don't you think it
> would be much better than adding a new ABI to export redundant information ?
>
IMO the mounting matrix is more consistent with the IIO ABIs. Although
I have no issue with repicating _PLD for device tree if people agree
that it is better.
> Also the location information of the device is not just specific to iio
> drivers. You should consider that we would have similar requirements for
> devices implemented as input or platform drivers.
The upstream standard for those sensors where the orientation matters
(accelerometer, gyro, compass) is IIO.
Granted, there are other device types for which the orientation
information may be useful (e.g. camera). However the actual
interpretation and action to be taken is different for each subsystem
(e.g. in the camera case do the correction via V4L2_CID_HFLIP /
V4L2_CID_VFLIP) so I think it is better to expose it at the subsystem
level in a way consistent with the subsystem's ABIs.
^ permalink raw reply
* Re: [v14 3/4] ext4: adds FS_IOC_FSSETXATTR/FS_IOC_FSGETXATTR interface support
From: Li Xi @ 2015-04-28 2:01 UTC (permalink / raw)
To: Dave Chinner
Cc: linux-fsdevel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Ext4 Developers List,
linux-api-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Theodore Ts'o, Andreas Dilger, Jan Kara,
viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn@public.gmane.org,
hch-wEGCiKHe2LqWVfeAwA7xHQ@public.gmane.org, Dmitry Monakhov
In-Reply-To: <20150426232033.GQ15810@dastard>
Hi Dave,
I ran xfstests on the kernel with this series of patches.
Unfortunately, 5 test suits failed. But I don't think they are caused
by this patch. Following is the result. Please let me know if there is
any problem about it.
Output of xfstests:
FSTYP -- xfs (non-debug)
PLATFORM -- Linux/x86_64 vm15 4.0.0+
MKFS_OPTIONS -- -f -bsize=4096 /dev/sdb2
MOUNT_OPTIONS -- /dev/sdb2 /mnt/scratch
generic/001 3s ... 2s
generic/002 0s ... 0s
generic/003 10s ... 10s
generic/004 [not run] xfs_io flink support is missing
generic/005 0s ... 0s
generic/006 1s ... 0s
generic/007 0s ... 0s
generic/008 [not run] xfs_io fzero support is missing
generic/009 [not run] xfs_io fzero support is missing
generic/010 1s ... 0s
generic/011 1s ... 0s
generic/012 [not run] xfs_io fpunch support is missing
generic/013 92s ... 90s
generic/014 3s ... 3s
generic/015 1s ... 1s
generic/016 [not run] xfs_io fpunch support is missing
generic/017 [not run] xfs_io fiemap support is missing
generic/018 [not run] xfs_io fiemap support is missing
generic/020 38s ... 31s
generic/021 [not run] xfs_io fpunch support is missing
generic/022 [not run] xfs_io fpunch support is missing
generic/023 1s ... 0s
generic/024 1s ... 0s
generic/025 0s ... 0s
generic/026 0s ... 0s
generic/027 57s ... 57s
generic/028 5s ... 5s
generic/053 1s ... 2s
generic/062 1s ... 2s
generic/068 60s ... 61s
generic/069 4s ... 3s
generic/070 13s ... 14s
generic/074 164s ... 162s
generic/075 87s ... 86s
generic/076 1s ... 1s
generic/077 [not run] fsgqa user not defined.
generic/079 1s ... 1s
generic/083 36s ... 39s
generic/088 1s ... 0s
generic/089 4s ... 4s
generic/091 62s ... 62s
generic/093 [not run] not suitable for this OS: Linux
generic/097 [not run] not suitable for this OS: Linux
generic/099 [not run] not suitable for this OS: Linux
generic/100 12s ... 12s
generic/105 0s ... 0s
generic/112 [not run] fsx not built with AIO for this platform
generic/113 [not run] aio-stress not built for this platform
generic/117 15s ... 15s
generic/120 16s ... 16s
generic/123 [not run] fsgqa user not defined.
generic/124 4s ... 3s
generic/125 [not run] fsgqa user not defined.
generic/126 1s ... 0s
generic/127 1745s ... 1793s
generic/128 [not run] fsgqa user not defined.
generic/129 4s ... 4s
generic/130 13s ... 13s
generic/131 1s ... 1s
generic/132 40s ... 40s
generic/133 92s ... 94s
generic/135 1s ... 1s
generic/141 0s ... 1s
generic/169 1s ... 1s
generic/184 1s ... 0s
generic/192 40s ... 40s
generic/193 [not run] fsgqa user not defined.
generic/198 [not run] src/aio-dio-regress/aiodio_sparse2 not built
generic/204 6s ... 7s
generic/207 [not run] src/aio-dio-regress/aio-dio-extend-stat not built
generic/208 [not run]
src/aio-dio-regress/aio-dio-invalidate-failure not built
generic/209 [not run]
src/aio-dio-regress/aio-dio-invalidate-readahead not built
generic/210 [not run]
src/aio-dio-regress/aio-dio-subblock-eof-read not built
generic/211 [not run]
src/aio-dio-regress/aio-free-ring-with-bogus-nr-pages not built
generic/212 [not run]
src/aio-dio-regress/aio-io-setup-with-nonwritable-context-pointer not
built
generic/213 0s ... 0s
generic/214 0s ... 0s
generic/215 2s ... 3s
generic/219 [not run] fsgqa user not defined.
generic/221 1s ... 1s
generic/223 14s ... 14s
generic/224 59s ... 61s
generic/225 18s ... 17s
generic/226 18s ... 19s
generic/228 1s ... 0s
generic/230 [not run] fsgqa user not defined.
generic/231 [not run] fsgqa user not defined.
generic/232 55s ... 52s
generic/233 [not run] fsgqa user not defined.
generic/234 9s ... 9s
generic/235 [not run] fsgqa user not defined.
generic/236 2s ... 1s
generic/237 1s ... 0s
generic/239 [not run]
src/aio-dio-regress/aio-dio-hole-filling-race not built
generic/240 [not run] src/aio-dio-regress/aiodio_sparse2 not built
generic/241 [not run] dbench not found
generic/245 0s ... 0s
generic/246 0s ... 0s
generic/247 24s ... 24s
generic/248 0s ... 0s
generic/249 2s ... 1s
generic/255 [not run] xfs_io fpunch support is missing
generic/256 [not run] xfs_io fpunch support is missing
generic/257 0s ... 0s
generic/258 1s ... 0s
generic/260 [not run] FITRIM not supported on /dev/sdb2
generic/263 93s ... 96s
generic/269 113s ... 112s
generic/270 [not run] fsgqa user not defined.
generic/273 44s ... 40s
generic/274 72s ... 70s
generic/275 32s ... 33s
generic/277 2s ... 1s
generic/280 2s ... 2s
generic/285 0s ... 0s
generic/286 6s ... 5s
generic/288 [not run] FITRIM not supported on /dev/sdb2
generic/294 1s ... 0s
generic/299 [not run] utility required, skipped this test
generic/300 [not run] xfs_io fpunch support is missing
generic/306 - output mismatch (see
/root/work/quota/ext4_inode_field/xfstests.git/results//generic/306.out.bad)
--- tests/generic/306.out 2014-07-16 10:19:26.196995657 +0800
+++ /root/work/quota/ext4_inode_field/xfstests.git/results//generic/306.out.bad
2015-04-27 22:40:13.365445316 +0800
@@ -2,11 +2,9 @@
== try to create new file
touch: cannot touch 'SCRATCH_MNT/this_should_fail': Read-only file system
== pwrite to null device
-wrote 512/512 bytes at offset 0
-XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+xfs_io: specified file ["/mnt/scratch/devnull"] is not on an XFS filesystem
== pread from zero device
...
(Run 'diff -u tests/generic/306.out
/root/work/quota/ext4_inode_field/xfstests.git/results//generic/306.out.bad'
to see the entire diff)
generic/307 1s ... 2s
generic/308 0s ... 0s
generic/309 1s ... 1s
generic/310 62s ... 63s
generic/311 124s ... 129s
generic/312 [not run] this test requires $SCRATCH_DEV has 5368709120B space
generic/313 2s ... 2s
generic/314 [not run] fsgqa user not defined.
generic/315 0s ... 0s
generic/316 [not run] xfs_io fpunch support is missing
generic/317 [not run] fsgqa user not defined.
generic/318 1s ... 1s
generic/319 0s ... 1s
generic/320 65s ... 81s
generic/321 2s ... 2s
generic/322 1s ... 2s
shared/006 381s ... 386s
shared/032 8s ... 8s
shared/051 0s ... 1s
shared/272 [not run] not suitable for this filesystem type: xfs
shared/289 [not run] not suitable for this filesystem type: xfs
shared/298 [not run] xfs_io fiemap support is missing
xfs/001 [not run] mkfs.xfs doesn't have crc feature
xfs/002 [not run] mkfs.xfs doesn't have crc feature
xfs/003 0s ... 0s
xfs/004 1s ... 1s
xfs/005 [not run] mkfs.xfs doesn't have crc feature
xfs/006 3s ... 4s
xfs/007 1s ... 0s
xfs/008 0s ... 1s
xfs/009 0s ... 1s
xfs/010 [not run] mkfs.xfs doesn't have finobt feature
xfs/011 17s ... 17s
xfs/012 1s ... 1s
xfs/013 [not run] mkfs.xfs doesn't have finobt feature
xfs/014 [not run] fsgqa user not defined.
xfs/016 35s ... 37s
xfs/017 18s ... 18s
xfs/019 1s ... 1s
xfs/021 0s ... 1s
xfs/026 12s
xfs/027 12s
xfs/028 24s
xfs/029 0s ... 1s
xfs/030 9s ... 9s
xfs/031 7s ... 7s
xfs/033 6s ... 5s
xfs/034 1s ... 1s
xfs/035 [not run] No dump tape specified
xfs/040 [not run] Can't run srcdiff without KWORKAREA set
xfs/041 15s ... 17s
xfs/042 120s ... 123s
xfs/044 [not run] This test requires a valid $SCRATCH_LOGDEV
xfs/045 1s ... 1s
xfs/046 12s
xfs/047 23s
xfs/048 0s ... 0s
xfs/049 8s ... 8s
xfs/050 15s ... 15s
xfs/052 1s ... 2s
xfs/054 2s ... 3s
xfs/056 17s
xfs/057 [not run] Place holder for IRIX test 057
xfs/058 [not run] Place holder for IRIX test 058
xfs/059 [not run] xfsdump multi-stream support required
xfs/060 [not run] xfsdump multi-stream support required
xfs/061 12s
xfs/063 12s
xfs/064 77s
xfs/065 35s
xfs/066 25s
xfs/067 1s ... 1s
xfs/071 5s ... 5s
xfs/072 1s ... 1s
xfs/073 15s ... 22s
xfs/078 65s ... 66s
xfs/084 59s ... 59s
xfs/085 1s ... 1s
xfs/086 63s ... 65s
xfs/087 33s ... 34s
xfs/090 [not run] External volumes not in use, skipped this test
xfs/092 1s ... 1s
xfs/094 [not run] External volumes not in use, skipped this test
xfs/095 [not run] not suitable for this OS: Linux
xfs/096 3s ... 2s
xfs/103 1s ... 0s
xfs/104 96s ... 100s
xfs/108 6s ... 6s
xfs/109 29s ... 28s
xfs/110 12s ... 12s
xfs/116 1s ... 1s
xfs/118 1s ... 2s
xfs/119 4s ... 4s
xfs/121 6s ... 6s
xfs/122 [not run] Could not compile test program (see end of
/root/work/quota/ext4_inode_field/xfstests.git/results//xfs/122.full)
xfs/134 1s ... 1s
xfs/137 12s ... 12s
xfs/138 13s ... 14s
xfs/139 13s ... 13s
xfs/140 13s ... 13s
xfs/148 [not run] parallel repair binary xfs_prepair64 is not installed
xfs/149 [not run] parallel repair binary xfs_prepair is not installed
xfs/164 0s ... 0s
xfs/165 1s ... 0s
xfs/166 1s ... 0s
xfs/167 [not run] This test requires at least 10GB free on
/mnt/scratch to run
xfs/170 9s ... 10s
xfs/174 17s ... 19s
xfs/178 15s ... 15s
xfs/179 39s ... 41s
xfs/180 [not run] This test requires at least 10GB free on
/mnt/scratch to run
xfs/181 12s ... 13s
xfs/182 9s ... 9s
xfs/183 3s ... 3s
xfs/186 1s ... 2s
xfs/187 3s ... 2s
xfs/188 8s ... 7s
xfs/189 [not run] noattr2 mount option not supported on /dev/sdb2
xfs/190 1s ... 1s
xfs/191 [not run] no mkfs support for NFS v4 ACLs
xfs/194 1s ... 1s
xfs/195 [not run] fsgqa user not defined.
xfs/196 3s ... 4s
xfs/197 [not run] This test is only valid on 32 bit machines
xfs/199 1s ... 0s
xfs/200 1s ... 0s
xfs/201 2s ... 2s
xfs/202 1s ... 0s
xfs/203 0s ... 1s
xfs/205 2s ... 2s
xfs/206 31s ... 32s
xfs/216 10s ... 10s
xfs/217 128s ... 130s
xfs/220 1s ... 1s
xfs/222 1s ... 1s
xfs/227 493s ... 507s
xfs/229 134s ... [failed, exit status 23] - output mismatch (see
/root/work/quota/ext4_inode_field/xfstests.git/results//xfs/229.out.bad)
--- tests/xfs/229.out 2014-07-16 10:19:26.215995657 +0800
+++ /root/work/quota/ext4_inode_field/xfstests.git/results//xfs/229.out.bad
2015-04-27 23:25:48.709093428 +0800
@@ -1,4 +1,31 @@
QA output created by 229
generating 10 files
+Write did not return correct amount
+Write did not return correct amount
+Write did not return correct amount
+Write did not return correct amount
comparing files
...
(Run 'diff -u tests/xfs/229.out
/root/work/quota/ext4_inode_field/xfstests.git/results//xfs/229.out.bad'
to see the entire diff)
xfs/238 1s ... 1s
xfs/242 [not run] zero command not supported
xfs/244 2s ... 2s
xfs/250 [failed, exit status 1] - output mismatch (see
/root/work/quota/ext4_inode_field/xfstests.git/results//xfs/250.out.bad)
--- tests/xfs/250.out 2014-07-16 10:19:26.215995657 +0800
+++ /root/work/quota/ext4_inode_field/xfstests.git/results//xfs/250.out.bad
2015-04-27 23:26:15.137452337 +0800
@@ -11,4 +11,4 @@
*** preallocate large file
*** unmount loop filesystem
*** check loop filesystem
-*** done
+_check_xfs_filesystem: filesystem on /mnt/test/250.fs is
inconsistent (r) (see
/root/work/quota/ext4_inode_field/xfstests.git/results//xfs/250.full)
...
(Run 'diff -u tests/xfs/250.out
/root/work/quota/ext4_inode_field/xfstests.git/results//xfs/250.out.bad'
to see the entire diff)
xfs/252 [not run] xfs_io fpunch support is missing
xfs/253 2s ... 3s
xfs/259 33s ... 34s
xfs/261 1s ... 1s
xfs/262 1s ... 1s
xfs/266 [not run] requires xfsdump -D
xfs/278 1s ... 1s
xfs/279 8s ... 8s
xfs/281 [not run] xfsdump -K option required
xfs/282 [not run] xfsdump -K option required
xfs/283 [not run] xfsdump -K option required
xfs/287 2s
xfs/290 [not run] xfs_io zero support is missing
xfs/291 52s ... 54s
xfs/292 4s ... 4s
xfs/293 2s ... 2s
xfs/295 8s ... 7s
xfs/296 12s
xfs/297 306s ... 229s
xfs/298 6s ... 6s
xfs/299 [not run] mkfs.xfs doesn't have crc feature
xfs/300 [not run] SELinux not enabled
xfs/301 - output mismatch (see
/root/work/quota/ext4_inode_field/xfstests.git/results//xfs/301.out.bad)
--- tests/xfs/301.out 2014-07-16 10:19:26.217995657 +0800
+++ /root/work/quota/ext4_inode_field/xfstests.git/results//xfs/301.out.bad
2015-04-27 23:33:33.629182381 +0800
@@ -29,18 +29,21 @@
Attribute "attr4" had a 10 byte value for DUMP_DIR/sub/biggg:
some_text4
EAs on restore
+getfattr: /mnt/scratch/restoredir/dumpdir: No such file or directory
+getfattr: /mnt/scratch/restoredir/dumpdir: No such file or directory
User names
-Attribute "attr5" had a 8 byte value for DUMP_DIR/dir:
...
(Run 'diff -u tests/xfs/301.out
/root/work/quota/ext4_inode_field/xfstests.git/results//xfs/301.out.bad'
to see the entire diff)
xfs/302 [failed, exit status 1] - output mismatch (see
/root/work/quota/ext4_inode_field/xfstests.git/results//xfs/302.out.bad)
--- tests/xfs/302.out 2014-07-16 10:19:26.217995657 +0800
+++ /root/work/quota/ext4_inode_field/xfstests.git/results//xfs/302.out.bad
2015-04-27 23:33:46.102767709 +0800
@@ -1,2 +1,4 @@
QA output created by 302
Silence is golden.
+dump failed
+(see /root/work/quota/ext4_inode_field/xfstests.git/results//xfs/302.full
for details)
...
(Run 'diff -u tests/xfs/302.out
/root/work/quota/ext4_inode_field/xfstests.git/results//xfs/302.out.bad'
to see the entire diff)
xfs/303 0s ... 0s
xfs/304 [not run] mkfs.xfs doesn't have crc feature
xfs/305 [not run] mkfs.xfs doesn't have crc feature
xfs/306 76s ... 76s
Ran: generic/001 generic/002 generic/003 generic/005 generic/006
generic/007 generic/010 generic/011 generic/013 generic/014
generic/015 generic/020 generic/023 generic/024 generic/025
generic/026 generic/027 generic/028 generic/053 generic/062
generic/068 generic/069 generic/070 generic/074 generic/075
generic/076 generic/079 generic/083 generic/088 generic/089
generic/091 generic/100 generic/105 generic/117 generic/120
generic/124 generic/126 generic/127 generic/129 generic/130
generic/131 generic/132 generic/133 generic/135 generic/141
generic/169 generic/184 generic/192 generic/204 generic/213
generic/214 generic/215 generic/221 generic/223 generic/224
generic/225 generic/226 generic/228 generic/232 generic/234
generic/236 generic/237 generic/245 generic/246 generic/247
generic/248 generic/249 generic/257 generic/258 generic/263
generic/269 generic/273 generic/274 generic/275 generic/277
generic/280 generic/285 generic/286 generic/294 generic/306
generic/307 generic/308 generic/309 generic/310 generic/311
generic/313 generic/315 generic/318 generic/319 generic/320
generic/321 generic/322 shared/006 shared/032 shared/051 xfs/003
xfs/004 xfs/006 xfs/007 xfs/008 xfs/009 xfs/011 xfs/012 xfs/016
xfs/017 xfs/019 xfs/021 xfs/026 xfs/027 xfs/028 xfs/029 xfs/030
xfs/031 xfs/033 xfs/034 xfs/041 xfs/042 xfs/045 xfs/046 xfs/047
xfs/048 xfs/049 xfs/050 xfs/052 xfs/054 xfs/056 xfs/061 xfs/063
xfs/064 xfs/065 xfs/066 xfs/067 xfs/071 xfs/072 xfs/073 xfs/078
xfs/084 xfs/085 xfs/086 xfs/087 xfs/092 xfs/096 xfs/103 xfs/104
xfs/108 xfs/109 xfs/110 xfs/116 xfs/118 xfs/119 xfs/121 xfs/134
xfs/137 xfs/138 xfs/139 xfs/140 xfs/164 xfs/165 xfs/166 xfs/170
xfs/174 xfs/178 xfs/179 xfs/181 xfs/182 xfs/183 xfs/186 xfs/187
xfs/188 xfs/190 xfs/194 xfs/196 xfs/199 xfs/200 xfs/201 xfs/202
xfs/203 xfs/205 xfs/206 xfs/216 xfs/217 xfs/220 xfs/222 xfs/227
xfs/229 xfs/238 xfs/244 xfs/250 xfs/253 xfs/259 xfs/261 xfs/262
xfs/278 xfs/279 xfs/287 xfs/291 xfs/292 xfs/293 xfs/295 xfs/296
xfs/297 xfs/298 xfs/301 xfs/302 xfs/303 xfs/306
Not run: generic/004 generic/008 generic/009 generic/012 generic/016
generic/017 generic/018 generic/021 generic/022 generic/077
generic/093 generic/097 generic/099 generic/112 generic/113
generic/123 generic/125 generic/128 generic/193 generic/198
generic/207 generic/208 generic/209 generic/210 generic/211
generic/212 generic/219 generic/230 generic/231 generic/233
generic/235 generic/239 generic/240 generic/241 generic/255
generic/256 generic/260 generic/270 generic/288 generic/299
generic/300 generic/312 generic/314 generic/316 generic/317 shared/272
shared/289 shared/298 xfs/001 xfs/002 xfs/005 xfs/010 xfs/013 xfs/014
xfs/035 xfs/040 xfs/044 xfs/057 xfs/058 xfs/059 xfs/060 xfs/090
xfs/094 xfs/095 xfs/122 xfs/148 xfs/149 xfs/167 xfs/180 xfs/189
xfs/191 xfs/195 xfs/197 xfs/242 xfs/252 xfs/266 xfs/281 xfs/282
xfs/283 xfs/290 xfs/299 xfs/300 xfs/304 xfs/305
Failures: generic/306 xfs/229 xfs/250 xfs/301 xfs/302
Failed 5 of 206 tests
On Mon, Apr 27, 2015 at 7:20 AM, Dave Chinner <david-FqsqvQoI3Ljby3iVrkZq2A@public.gmane.org> wrote:
> On Thu, Apr 23, 2015 at 03:56:36AM +0900, Li Xi wrote:
>> This patch adds FS_IOC_FSSETXATTR/FS_IOC_FSGETXATTR ioctl interface
>> support for ext4. The interface is kept consistent with
>> XFS_IOC_FSGETXATTR/XFS_IOC_FSGETXATTR.
>
> Have you run this patchthrough XFS testing to make sure everything
> sill works?
>
> Cheers,
>
> Dave.
> --
> Dave Chinner
> david-FqsqvQoI3Ljby3iVrkZq2A@public.gmane.org
^ permalink raw reply
* Re: [RFC PATCH 3/3] iio: derive the mounting matrix from ACPI _PLD objects
From: sathyanarayanan kuppuswamy @ 2015-04-27 21:57 UTC (permalink / raw)
To: Octavian Purdila
Cc: Jonathan Cameron, Lars-Peter Clausen, Peter Meerwald,
Robert Moore, Rafael J Wysocki, lenb, linux-api, lkml,
linux-iio@vger.kernel.org, linux-acpi@vger.kernel.org
In-Reply-To: <CAE1zot+YKTPmVbG-_fNRy-E_VCcqq1VE78H3PMSMb5HvsBheQw@mail.gmail.com>
Hi
On 04/27/2015 08:54 AM, Octavian Purdila wrote:
> On Mon, Apr 27, 2015 at 6:42 PM, Kuppuswamy Sathyanarayanan
> <sathyanarayanan.kuppuswamy@linux.intel.com> wrote:
>> Since Acpi framework already exports this info to user space, Why not do
>> this derivation in user space code ? Why do we need new ABI, if the same
>> can be derived from existing one.
>>
> The ABI was added in the previous patch so that we can present the
> sensor orientation information to userspace even in the case of device
> tree.
If the main reason for implementing a new ABI is to support DT
platforms, Why not implement a version of _PLD for device tree ? Don't
you think it would be much better than adding a new ABI to export
redundant information ?
Also the location information of the device is not just specific to iio
drivers. You should consider that we would have similar requirements for
devices implemented as input or platform drivers.
>
> The purpose of this patch is to provide a consistent ABI to userspace,
> i.e. to avoid doing one thing in the ACPI case and another thing in
> the case of device tree.
> --
> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
--
Sathyanarayanan Kuppuswamy
Android kernel developer
^ permalink raw reply
* Re: [PATCH 2/3] uffd: Introduce the v2 API
From: Andrea Arcangeli @ 2015-04-27 21:12 UTC (permalink / raw)
To: Pavel Emelyanov
Cc: Linux Kernel Mailing List, Linux MM, Linux API, Sanidhya Kashyap
In-Reply-To: <55389133.8070701-bzQdu9zFT3WakBO8gow8eQ@public.gmane.org>
Hello,
On Thu, Apr 23, 2015 at 09:29:07AM +0300, Pavel Emelyanov wrote:
> So your proposal is to always report 16 bytes per PF from read() and
> let userspace decide itself how to handle the result?
Reading 16bytes for each userfault (instead of 8) and sharing the same
read(2) protocol (UFFD_API) for both the cooperative and
non-cooperative usages, is something I just suggested for
consideration after reading your patchset.
The pros of using a single protocol for both is that it would reduce
amount of code and there would be just one file operation for the
.read method. The cons is that it will waste 8 bytes per userfault in
terms of memory footprint. The other major cons is that it would force
us to define the format of the non cooperative protocol now despite it's
not fully finished yet.
I'm also ok with two protocols if nobody else objects, but if we use
two protocols, we should at least use different file operation methods
and use __always_inline with constants passed as parameter to optimize
away the branches at build time. This way we get the reduced memory
footprint in the read syscall without other runtime overhead
associated with it.
> >> +struct uffd_v2_msg {
> >> + __u64 type;
> >> + __u64 arg;
> >> +};
> >> +
> >> +#define UFFD_PAGEFAULT 0x1
> >> +
> >> +#define UFFD_PAGEFAULT_BIT (1 << (UFFD_PAGEFAULT - 1))
> >> +#define __UFFD_API_V2_BITS (UFFD_PAGEFAULT_BIT)
> >> +
> >> +/*
> >> + * Lower PAGE_SHIFT bits are used to report those supported
> >> + * by the pagefault message itself. Other bits are used to
> >> + * report the message types v2 API supports
> >> + */
> >> +#define UFFD_API_V2_BITS (__UFFD_API_V2_BITS << 12)
> >> +
> >
> > And why exactly is this 12 hardcoded?
>
> Ah, it should have been the PAGE_SHIFT one, but I was unsure whether it
> would be OK to have different shifts in different arches.
>
> But taking into account your comment that bits field id bad for these
> values, if we introduce the new .features one for api message, then this
> 12 will just go away.
Ok.
> > And which field should be masked
> > with the bits? In the V1 protocol it was the "arg" (userfault address)
> > not the "type". So this is a bit confusing and probably requires
> > simplification.
>
> I see. Actually I decided that since bits higher than 12th (for x86) is
> always 0 in api message (no bits allowed there, since pfn sits in this
> place), it would be OK to put non-PF bits there.
That was ok yes.
> Should I better introduce another .features field in uffd API message?
What about renaming "uffdio_api.bits" to "uffdio_api.features"?
And then we set uffdio_api.features to
UFFD_FEATURE_WRITE|UFFD_FEATURE_WP|UFFD_FEATURE_FORK as needed.
UFFD_FEATURE_WRITE would always be enabled, it's there only in case we
want to disable it later (mostly if some arch has trouble with it,
which is unlikely, but qemu doesn't need that bit of information at
all for example so qemu would be fine if UFFD_FEATURE_WRITE
disappears).
UFFD_FEATURE_WP would signal also that the wrprotection feature (not
implemented yet) is available (then later the register ioctl would
also show the new wrprotection ioctl numbers available to mangle the
wrprotection). The UFFD_FEATURE_WP feature in the cooperative usage
(qemu live snapshotting) can use the UFFD_API first protocol too.
UFFD_FEATURE_FORK would be returned if the UFFD_API_V2 was set in
uffdio.api, and it would be part of the incremental non-cooperative
patchset.
We could also not define "UFFD_FEATURE_FORK" at all and imply that
fork/mremap/MADV_DONTNEED are all available if UFFD_API_V2 uffdio_api
ioctl succeeds... That's only doable if we keep two different read
protocols though. UFFD_FEATURE_FORK (or UFFD_FEATURE_NON_COOPERATIVE)
are really strictly needed only if we share the same read(2) protocol
for both the cooperative and non-cooperative usages.
The idea is that there's not huge benefit of only having the "fork"
feature supported but missing "mremap" and "madv_dontneed".
In fact if a new syscall that works like mremap is added later (call
it mremap2), we would need to fail the UFFDIO_API_V2 and require a
UFFDIO_API_V3 for such kernel that can return a new mremap2 type of
event. Userland couldn't just assume it is ok to use postcopy live
migration for containers, because
UFFD_FEATURE_FORK|MREMAP|MADV_DONTNEED are present in the
uffdio.features when it asked for API_V2. There shall be something
that tells userland "hey there's a new mremap2 that the software
inside the container can run on top of this kernel, so you are going
to get a new mremap2 type of userfault event too".
In any case, regardless of how we solve the above,
"uffdio_api.features" sounds better than ".bits".
If we retain two different UFFD_API, we'll be able to freeze the
current one and decide later if
UFFD_FEATURE_FORK|UFFD_FEATURE_MREMAP|UFFD_FEATURE_MADV_DONTNEED shall
be added to the .features, or if to rely on UFFD_API_V2 succeeding to
let userland know that the non-cooperative usage is fully supported by
the kernel.
Not having to freeze these details now is the main benefit of having
two different UFFD_API after all...
^ permalink raw reply
* Re: Revised futex(2) man page for review
From: Pavel Machek @ 2015-04-27 20:37 UTC (permalink / raw)
To: Peter Zijlstra
Cc: Michael Kerrisk (man-pages), Thomas Gleixner, Darren Hart,
Carlos O'Donell, Ingo Molnar, Jakub Jelinek,
linux-man-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, lkml,
Davidlohr Bueso, Arnd Bergmann, Steven Rostedt, Linux API,
Torvald Riegel, Roland McGrath, Darren Hart, Anton Blanchard,
Eric Dumazet, bill o gallmeister, Jan Kiszka, Daniel Wagner,
Rich Felker, Andy Lutomirski, bert hubert
In-Reply-To: <20150328114725.GJ27490-IIpfhp3q70z/8w/KjCw3T+5/BudmfyzbbVWyRVo5IupeoWH0uzbU5w@public.gmane.org>
Hi!
> The FUTEX_WAIT_OP operation is equivalent to execute the follow???
> ing code atomically and totally ordered with respect to other
> futex operations on any of the two supplied futex words:
"to executing"?
> The operation and comparison that are to be performed are
> encoded in the bits of the argument val3. Pictorially, the
> encoding is:
>
> +---+---+-----------+-----------+
> |op |cmp| oparg | cmparg |
> +---+---+-----------+-----------+
> 4 4 12 12 <== # of bits
>
:-)
> RETURN VALUE
> In the event of an error, all operations return -1 and set errno to
> indicate the cause of the error. The return value on success depends
> on the operation, as described in the following list:
Did you say (at the begining) that there is no glibc wrapper?
> EINVAL The operation in futex_op is one of those that employs a time???
> out, but the supplied timeout argument was invalid (tv_sec was
> less than zero, or tv_nsec was not less than 1000,000,000).
1,000...?
> NOTES
> Glibc does not provide a wrapper for this system call; call it using
> syscall(2).
--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
^ permalink raw reply
* Re: [PATCH v3 2/4] of: overlay: global sysfs enable attribute
From: Pantelis Antoniou @ 2015-04-27 18:43 UTC (permalink / raw)
To: Greg KH
Cc: Rob Herring, Grant Likely, Andrew Morton, Matt Porter, Koen Kooi,
Guenter Roeck, devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-api-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20150427183915.GA29312-U8xfFu+wG4EAvxtiuMwx3w@public.gmane.org>
Hi Greg,
> On Apr 27, 2015, at 21:39 , Greg KH <greg-U8xfFu+wG4EAvxtiuMwx3w@public.gmane.org> wrote:
>
> On Mon, Apr 27, 2015 at 09:13:56PM +0300, Pantelis Antoniou wrote:
>> Hi Greg,
>>
>>> On Apr 24, 2015, at 23:29 , Greg KH <greg-U8xfFu+wG4EAvxtiuMwx3w@public.gmane.org> wrote:
>>>
>>> On Fri, Apr 24, 2015 at 12:45:42PM +0300, Pantelis Antoniou wrote:
>>>> A throw once master enable switch to protect against any
>>>> further overlay applications if the administrator desires so.
>>>>
>>>> Signed-off-by: Pantelis Antoniou <pantelis.antoniou-OWPKS81ov/FWk0Htik3J/w@public.gmane.org>
>>>> ---
>>>> drivers/of/overlay.c | 45 ++++++++++++++++++++++++++++++++++++++++++++-
>>>> 1 file changed, 44 insertions(+), 1 deletion(-)
>>>>
>>>> diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c
>>>> index f17f5ef..c335809 100644
>>>> --- a/drivers/of/overlay.c
>>>> +++ b/drivers/of/overlay.c
>>>> @@ -21,6 +21,7 @@
>>>> #include <linux/err.h>
>>>> #include <linux/idr.h>
>>>> #include <linux/sysfs.h>
>>>> +#include <linux/atomic.h>
>>>>
>>>> #include "of_private.h"
>>>>
>>>> @@ -55,8 +56,12 @@ struct of_overlay {
>>>> struct kobject kobj;
>>>> };
>>>>
>>>> +/* master enable switch; once set to 0 can't be re-enabled */
>>>> +static atomic_t ov_enable = ATOMIC_INIT(1);
>>>> +
>>>> static int of_overlay_apply_one(struct of_overlay *ov,
>>>> struct device_node *target, const struct device_node *overlay);
>>>> +static int overlay_removal_is_ok(struct of_overlay *ov);
>>>>
>>>> static int of_overlay_apply_single_property(struct of_overlay *ov,
>>>> struct device_node *target, struct property *prop)
>>>> @@ -339,6 +344,37 @@ void of_overlay_release(struct kobject *kobj)
>>>> kfree(ov);
>>>> }
>>>>
>>>> +static ssize_t enable_show(struct kobject *kobj,
>>>> + struct kobj_attribute *attr, char *buf)
>>>> +{
>>>> + return snprintf(buf, PAGE_SIZE, "%d\n", atomic_read(&ov_enable));
>>>> +}
>>>> +
>>>> +static ssize_t enable_store(struct kobject *kobj,
>>>> + struct kobj_attribute *attr, const char *buf, size_t count)
>>>> +{
>>>> + int ret;
>>>> + long new_enable;
>>>> +
>>>> + ret = kstrtol(buf, 10, &new_enable);
>>>> + if (ret != 0)
>>>> + return ret;
>>>> + if ((unsigned long)new_enable > 1)
>>>> + return -EINVAL;
>>>> + /* if we've disabled it, no going back */
>>>> + if (atomic_read(&ov_enable) == 0)
>>>> + return -EPERM;
>>>> + atomic_set(&ov_enable, (int)new_enable);
>>>> + return count;
>>>> +}
>>>> +
>>>> +static struct kobj_attribute enable_attr = __ATTR_RW(enable);
>>>> +
>>>> +static const struct attribute *overlay_global_attrs[] = {
>>>> + &enable_attr.attr,
>>>> + NULL
>>>> +};
>>>
>>> Why not make this an attribute group and then attach it to the kobj_type
>>> to create the files in a race-free manner?
>>>
>>
>> Err, these are the global attributes. They are attached to the
>> parent of the overlay objects which is a kset object itself.
>
> Ick, no, never attach attributes to a kobject that you don't create
> yourself, otherwise it's a race that you lost.
>
Err, it is created by me. It’s a kset by the following call:
> ov_kset = kset_create_and_add("overlays", NULL, &of_kset->kobj);
>
What is the problem with this?
>>>> +
>>>> static struct kobj_type of_overlay_ktype = {
>>>> .release = of_overlay_release,
>>>> };
>>>> @@ -360,6 +396,10 @@ int of_overlay_create(struct device_node *tree)
>>>> struct of_overlay *ov;
>>>> int err, id;
>>>>
>>>> + /* administratively disabled */
>>>> + if (!atomic_read(&ov_enable))
>>>> + return -EPERM;
>>>> +
>>>> /* allocate the overlay structure */
>>>> ov = kzalloc(sizeof(*ov), GFP_KERNEL);
>>>> if (ov == NULL)
>>>> @@ -596,5 +636,8 @@ int of_overlay_init(void)
>>>> if (!ov_kset)
>>>> return -ENOMEM;
>>>>
>>>> - return 0;
>>>> + rc = sysfs_create_files(&ov_kset->kobj, overlay_global_attrs);
>>>> + WARN(rc, "%s: error adding global attributes\n", __func__);
>>>
>>> What can a user do with this warning message? If nothing, then don't
>>> print it out, right?
>>>
>>> You are creating sysfs files _after_ the kobject has been announced to
>>> userspace, causing nasty race conditions. Please don't do that.
>>>
>>
>> This is at overlay_init() time, which is way way before userspace ever
>> has a chance to start. If there’s a different way to attach a attribute
>> group to a kset object I’d like to find out how :)
>
> You can't load this as a module? Where exactly in sysfs is this
> kobject, and who creates it?
>
No, there’s no way to load this as a module, it’s in /sys/firmware/devicetree
And it’s created by the call to kset_create_and_add()
> thanks,
>
> greg k-h
Regards
— Pantelis
^ permalink raw reply
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