* [v5,03/78] xarray: Add the xa_lock to the radix_tree_root
@ 2017-12-15 22:03 Matthew Wilcox
0 siblings, 0 replies; 8+ messages in thread
From: Matthew Wilcox @ 2017-12-15 22:03 UTC (permalink / raw)
To: linux-kernel
Cc: Matthew Wilcox, Ross Zwisler, David Howells, Shaohua Li,
Jens Axboe, Rehas Sachdeva, Marc Zyngier, linux-mm, linux-fsdevel,
linux-f2fs-devel, linux-nilfs, linux-btrfs, linux-xfs, linux-usb,
linux-raid
From: Matthew Wilcox <mawilcox@microsoft.com>
This results in no change in structure size on 64-bit x86 as it fits in
the padding between the gfp_t and the void *.
Signed-off-by: Matthew Wilcox <mawilcox@microsoft.com>
---
fs/f2fs/gc.c | 2 +-
include/linux/idr.h | 12 ++++++------
include/linux/radix-tree.h | 7 +++++--
include/linux/xarray.h | 33 +++++++++++++++++++++++++++++++++
kernel/pid.c | 2 +-
tools/include/linux/spinlock.h | 1 +
6 files changed, 47 insertions(+), 10 deletions(-)
create mode 100644 include/linux/xarray.h
diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
index d844dcb80570..aac1e02f75df 100644
--- a/fs/f2fs/gc.c
+++ b/fs/f2fs/gc.c
@@ -991,7 +991,7 @@ int f2fs_gc(struct f2fs_sb_info *sbi, bool sync,
unsigned int init_segno = segno;
struct gc_inode_list gc_list = {
.ilist = LIST_HEAD_INIT(gc_list.ilist),
- .iroot = RADIX_TREE_INIT(GFP_NOFS),
+ .iroot = RADIX_TREE_INIT(gc_list.iroot, GFP_NOFS),
};
trace_f2fs_gc_begin(sbi->sb, sync, background,
diff --git a/include/linux/idr.h b/include/linux/idr.h
index 8432bbfe02ce..45a77d32dcf6 100644
--- a/include/linux/idr.h
+++ b/include/linux/idr.h
@@ -31,11 +31,11 @@ struct idr {
/* Set the IDR flag and the IDR_FREE tag */
#define IDR_RT_MARKER ((__force gfp_t)(3 << __GFP_BITS_SHIFT))
-#define IDR_INIT \
+#define IDR_INIT(name) \
{ \
- .idr_rt = RADIX_TREE_INIT(IDR_RT_MARKER) \
+ .idr_rt = RADIX_TREE_INIT(name, IDR_RT_MARKER) \
}
-#define DEFINE_IDR(name) struct idr name = IDR_INIT
+#define DEFINE_IDR(name) struct idr name = IDR_INIT(name)
/**
* idr_get_cursor - Return the current position of the cyclic allocator
@@ -194,10 +194,10 @@ struct ida {
struct radix_tree_root ida_rt;
};
-#define IDA_INIT { \
- .ida_rt = RADIX_TREE_INIT(IDR_RT_MARKER | GFP_NOWAIT), \
+#define IDA_INIT(name) { \
+ .ida_rt = RADIX_TREE_INIT(name, IDR_RT_MARKER | GFP_NOWAIT), \
}
-#define DEFINE_IDA(name) struct ida name = IDA_INIT
+#define DEFINE_IDA(name) struct ida name = IDA_INIT(name)
int ida_pre_get(struct ida *ida, gfp_t gfp_mask);
int ida_get_new_above(struct ida *ida, int starting_id, int *p_id);
diff --git a/include/linux/radix-tree.h b/include/linux/radix-tree.h
index fc55ff31eca7..d2253b540cd7 100644
--- a/include/linux/radix-tree.h
+++ b/include/linux/radix-tree.h
@@ -109,20 +109,23 @@ struct radix_tree_node {
#define ROOT_TAG_SHIFT (__GFP_BITS_SHIFT + 1)
struct radix_tree_root {
+ spinlock_t xa_lock;
gfp_t gfp_mask;
struct radix_tree_node __rcu *rnode;
};
-#define RADIX_TREE_INIT(mask) { \
+#define RADIX_TREE_INIT(name, mask) { \
+ .xa_lock = __SPIN_LOCK_UNLOCKED(name.xa_lock), \
.gfp_mask = (mask), \
.rnode = NULL, \
}
#define RADIX_TREE(name, mask) \
- struct radix_tree_root name = RADIX_TREE_INIT(mask)
+ struct radix_tree_root name = RADIX_TREE_INIT(name, mask)
#define INIT_RADIX_TREE(root, mask) \
do { \
+ spin_lock_init(&(root)->xa_lock); \
(root)->gfp_mask = (mask); \
(root)->rnode = NULL; \
} while (0)
diff --git a/include/linux/xarray.h b/include/linux/xarray.h
new file mode 100644
index 000000000000..931a0ff61315
--- /dev/null
+++ b/include/linux/xarray.h
@@ -0,0 +1,33 @@
+#ifndef _LINUX_XARRAY_H
+#define _LINUX_XARRAY_H
+/*
+ * eXtensible Arrays
+ * Copyright (c) 2017 Microsoft Corporation
+ * Author: Matthew Wilcox <mawilcox@microsoft.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/spinlock.h>
+
+#define xa_trylock(xa) spin_trylock(&(xa)->xa_lock)
+#define xa_lock(xa) spin_lock(&(xa)->xa_lock)
+#define xa_unlock(xa) spin_unlock(&(xa)->xa_lock)
+#define xa_lock_bh(xa) spin_lock_bh(&(xa)->xa_lock)
+#define xa_unlock_bh(xa) spin_unlock_bh(&(xa)->xa_lock)
+#define xa_lock_irq(xa) spin_lock_irq(&(xa)->xa_lock)
+#define xa_unlock_irq(xa) spin_unlock_irq(&(xa)->xa_lock)
+#define xa_lock_irqsave(xa, flags) \
+ spin_lock_irqsave(&(xa)->xa_lock, flags)
+#define xa_unlock_irqrestore(xa, flags) \
+ spin_unlock_irqrestore(&(xa)->xa_lock, flags)
+
+#endif /* _LINUX_XARRAY_H */
diff --git a/kernel/pid.c b/kernel/pid.c
index b13b624e2c49..b050b4643eee 100644
--- a/kernel/pid.c
+++ b/kernel/pid.c
@@ -58,7 +58,7 @@ int pid_max_max = PID_MAX_LIMIT;
*/
struct pid_namespace init_pid_ns = {
.kref = KREF_INIT(2),
- .idr = IDR_INIT,
+ .idr = IDR_INIT(init_pid_ns.idr),
.pid_allocated = PIDNS_ADDING,
.level = 0,
.child_reaper = &init_task,
diff --git a/tools/include/linux/spinlock.h b/tools/include/linux/spinlock.h
index 4ed569fcb139..b21b586b9854 100644
--- a/tools/include/linux/spinlock.h
+++ b/tools/include/linux/spinlock.h
@@ -7,6 +7,7 @@
#define spinlock_t pthread_mutex_t
#define DEFINE_SPINLOCK(x) pthread_mutex_t x = PTHREAD_MUTEX_INITIALIZER;
+#define __SPIN_LOCK_UNLOCKED(x) (pthread_mutex_t)PTHREAD_MUTEX_INITIALIZER
#define spin_lock_irqsave(x, f) (void)f, pthread_mutex_lock(x)
#define spin_unlock_irqrestore(x, f) (void)f, pthread_mutex_unlock(x)
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [v5,03/78] xarray: Add the xa_lock to the radix_tree_root
@ 2017-12-26 16:54 Kirill A. Shutemov
0 siblings, 0 replies; 8+ messages in thread
From: Kirill A. Shutemov @ 2017-12-26 16:54 UTC (permalink / raw)
To: Matthew Wilcox
Cc: linux-kernel, Matthew Wilcox, Ross Zwisler, David Howells,
Shaohua Li, Jens Axboe, Rehas Sachdeva, Marc Zyngier, linux-mm,
linux-fsdevel, linux-f2fs-devel, linux-nilfs, linux-btrfs,
linux-xfs, linux-usb, linux-raid
On Fri, Dec 15, 2017 at 02:03:35PM -0800, Matthew Wilcox wrote:
> From: Matthew Wilcox <mawilcox@microsoft.com>
>
> This results in no change in structure size on 64-bit x86 as it fits in
> the padding between the gfp_t and the void *.
The patch does more than described in the subject and commit message. At first
I was confused why do you need to touch idr here. It took few minutes to figure
it out.
Could you please add more into commit message about lockname and xa_ locking
interface since you introduce it here?
^ permalink raw reply [flat|nested] 8+ messages in thread
* [v5,03/78] xarray: Add the xa_lock to the radix_tree_root
@ 2017-12-27 3:43 Matthew Wilcox
0 siblings, 0 replies; 8+ messages in thread
From: Matthew Wilcox @ 2017-12-27 3:43 UTC (permalink / raw)
To: Kirill A. Shutemov
Cc: linux-kernel, Matthew Wilcox, Ross Zwisler, David Howells,
Shaohua Li, Jens Axboe, Rehas Sachdeva, Marc Zyngier, linux-mm,
linux-fsdevel, linux-f2fs-devel, linux-nilfs, linux-btrfs,
linux-xfs, linux-usb, linux-raid
On Tue, Dec 26, 2017 at 07:54:40PM +0300, Kirill A. Shutemov wrote:
> On Fri, Dec 15, 2017 at 02:03:35PM -0800, Matthew Wilcox wrote:
> > From: Matthew Wilcox <mawilcox@microsoft.com>
> >
> > This results in no change in structure size on 64-bit x86 as it fits in
> > the padding between the gfp_t and the void *.
>
> The patch does more than described in the subject and commit message. At first
> I was confused why do you need to touch idr here. It took few minutes to figure
> it out.
>
> Could you please add more into commit message about lockname and xa_ locking
> interface since you introduce it here?
Sure! How's this?
xarray: Add the xa_lock to the radix_tree_root
This results in no change in structure size on 64-bit x86 as it fits in
the padding between the gfp_t and the void *.
Initialising the spinlock requires a name for the benefit of lockdep,
so RADIX_TREE_INIT() now needs to know the name of the radix tree it's
initialising, and so do IDR_INIT() and IDA_INIT().
Also add the xa_lock() and xa_unlock() family of wrappers to make it
easier to use the lock. If we could rely on -fplan9-extensions in
the compiler, we could avoid all of this syntactic sugar, but that
wasn't added until gcc 4.6.
---
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 8+ messages in thread
* [v5,03/78] xarray: Add the xa_lock to the radix_tree_root
@ 2017-12-27 3:58 Matthew Wilcox
0 siblings, 0 replies; 8+ messages in thread
From: Matthew Wilcox @ 2017-12-27 3:58 UTC (permalink / raw)
To: Kirill A. Shutemov
Cc: linux-kernel, Matthew Wilcox, Ross Zwisler, David Howells,
Shaohua Li, Jens Axboe, Rehas Sachdeva, Marc Zyngier, linux-mm,
linux-fsdevel, linux-f2fs-devel, linux-nilfs, linux-btrfs,
linux-xfs, linux-usb, linux-raid
On Tue, Dec 26, 2017 at 07:43:40PM -0800, Matthew Wilcox wrote:
> Also add the xa_lock() and xa_unlock() family of wrappers to make it
> easier to use the lock. If we could rely on -fplan9-extensions in
> the compiler, we could avoid all of this syntactic sugar, but that
> wasn't added until gcc 4.6.
Oh, in case anyone's wondering, here's how I'd do it with plan9 extensions:
struct xarray {
spinlock_t;
int xa_flags;
void *xa_head;
};
...
spin_lock_irqsave(&mapping->pages, flags);
__delete_from_page_cache(page, NULL);
spin_unlock_irqrestore(&mapping->pages, flags);
...
The plan9 extensions permit passing a pointer to a struct which has an
unnamed element to a function which is expecting a pointer to the type
of that element. The compiler does any necessary arithmetic to produce
a pointer. It's exactly as if I had written:
spin_lock_irqsave(&mapping->pages.xa_lock, flags);
__delete_from_page_cache(page, NULL);
spin_unlock_irqrestore(&mapping->pages.xa_lock, flags);
More details here: https://9p.io/sys/doc/compiler.html
---
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 8+ messages in thread
* [v5,03/78] xarray: Add the xa_lock to the radix_tree_root
@ 2017-12-27 10:17 Kirill A. Shutemov
0 siblings, 0 replies; 8+ messages in thread
From: Kirill A. Shutemov @ 2017-12-27 10:17 UTC (permalink / raw)
To: Matthew Wilcox
Cc: linux-kernel, Matthew Wilcox, Ross Zwisler, David Howells,
Shaohua Li, Jens Axboe, Rehas Sachdeva, Marc Zyngier, linux-mm,
linux-fsdevel, linux-f2fs-devel, linux-nilfs, linux-btrfs,
linux-xfs, linux-usb, linux-raid
On Tue, Dec 26, 2017 at 07:43:40PM -0800, Matthew Wilcox wrote:
> On Tue, Dec 26, 2017 at 07:54:40PM +0300, Kirill A. Shutemov wrote:
> > On Fri, Dec 15, 2017 at 02:03:35PM -0800, Matthew Wilcox wrote:
> > > From: Matthew Wilcox <mawilcox@microsoft.com>
> > >
> > > This results in no change in structure size on 64-bit x86 as it fits in
> > > the padding between the gfp_t and the void *.
> >
> > The patch does more than described in the subject and commit message. At first
> > I was confused why do you need to touch idr here. It took few minutes to figure
> > it out.
> >
> > Could you please add more into commit message about lockname and xa_ locking
> > interface since you introduce it here?
>
> Sure! How's this?
>
> xarray: Add the xa_lock to the radix_tree_root
>
> This results in no change in structure size on 64-bit x86 as it fits in
> the padding between the gfp_t and the void *.
>
> Initialising the spinlock requires a name for the benefit of lockdep,
> so RADIX_TREE_INIT() now needs to know the name of the radix tree it's
> initialising, and so do IDR_INIT() and IDA_INIT().
>
> Also add the xa_lock() and xa_unlock() family of wrappers to make it
> easier to use the lock. If we could rely on -fplan9-extensions in
> the compiler, we could avoid all of this syntactic sugar, but that
> wasn't added until gcc 4.6.
>
Looks great, thanks.
^ permalink raw reply [flat|nested] 8+ messages in thread
* [v5,03/78] xarray: Add the xa_lock to the radix_tree_root
@ 2017-12-27 10:18 Kirill A. Shutemov
0 siblings, 0 replies; 8+ messages in thread
From: Kirill A. Shutemov @ 2017-12-27 10:18 UTC (permalink / raw)
To: Matthew Wilcox
Cc: linux-kernel, Matthew Wilcox, Ross Zwisler, David Howells,
Shaohua Li, Jens Axboe, Rehas Sachdeva, Marc Zyngier, linux-mm,
linux-fsdevel, linux-f2fs-devel, linux-nilfs, linux-btrfs,
linux-xfs, linux-usb, linux-raid
On Tue, Dec 26, 2017 at 07:58:15PM -0800, Matthew Wilcox wrote:
> On Tue, Dec 26, 2017 at 07:43:40PM -0800, Matthew Wilcox wrote:
> > Also add the xa_lock() and xa_unlock() family of wrappers to make it
> > easier to use the lock. If we could rely on -fplan9-extensions in
> > the compiler, we could avoid all of this syntactic sugar, but that
> > wasn't added until gcc 4.6.
>
> Oh, in case anyone's wondering, here's how I'd do it with plan9 extensions:
>
> struct xarray {
> spinlock_t;
> int xa_flags;
> void *xa_head;
> };
>
> ...
> spin_lock_irqsave(&mapping->pages, flags);
> __delete_from_page_cache(page, NULL);
> spin_unlock_irqrestore(&mapping->pages, flags);
> ...
>
> The plan9 extensions permit passing a pointer to a struct which has an
> unnamed element to a function which is expecting a pointer to the type
> of that element. The compiler does any necessary arithmetic to produce
> a pointer. It's exactly as if I had written:
>
> spin_lock_irqsave(&mapping->pages.xa_lock, flags);
> __delete_from_page_cache(page, NULL);
> spin_unlock_irqrestore(&mapping->pages.xa_lock, flags);
>
> More details here: https://9p.io/sys/doc/compiler.html
Yeah, that's neat.
Dealing with old compilers is frustrating...
^ permalink raw reply [flat|nested] 8+ messages in thread
* [v5,03/78] xarray: Add the xa_lock to the radix_tree_root
@ 2018-01-02 18:01 Darrick J. Wong
0 siblings, 0 replies; 8+ messages in thread
From: Darrick J. Wong @ 2018-01-02 18:01 UTC (permalink / raw)
To: Matthew Wilcox
Cc: Kirill A. Shutemov, linux-kernel, Matthew Wilcox, Ross Zwisler,
David Howells, Shaohua Li, Jens Axboe, Rehas Sachdeva,
Marc Zyngier, linux-mm, linux-fsdevel, linux-f2fs-devel,
linux-nilfs, linux-btrfs, linux-xfs, linux-usb, linux-raid
On Tue, Dec 26, 2017 at 07:58:15PM -0800, Matthew Wilcox wrote:
> On Tue, Dec 26, 2017 at 07:43:40PM -0800, Matthew Wilcox wrote:
> > Also add the xa_lock() and xa_unlock() family of wrappers to make it
> > easier to use the lock. If we could rely on -fplan9-extensions in
> > the compiler, we could avoid all of this syntactic sugar, but that
> > wasn't added until gcc 4.6.
>
> Oh, in case anyone's wondering, here's how I'd do it with plan9 extensions:
>
> struct xarray {
> spinlock_t;
> int xa_flags;
> void *xa_head;
> };
>
> ...
> spin_lock_irqsave(&mapping->pages, flags);
> __delete_from_page_cache(page, NULL);
> spin_unlock_irqrestore(&mapping->pages, flags);
> ...
>
> The plan9 extensions permit passing a pointer to a struct which has an
> unnamed element to a function which is expecting a pointer to the type
> of that element. The compiler does any necessary arithmetic to produce
> a pointer. It's exactly as if I had written:
>
> spin_lock_irqsave(&mapping->pages.xa_lock, flags);
> __delete_from_page_cache(page, NULL);
> spin_unlock_irqrestore(&mapping->pages.xa_lock, flags);
>
> More details here: https://9p.io/sys/doc/compiler.html
I read the link, and I understand (from section 3.3) that replacing
foo.bar.baz.goo with foo.goo is less typing, but otoh the first time I
read your example above I thought "we're passing (an array of pages |
something that doesn't have the word 'lock' in the name) to
spin_lock_irqsave? wtf?"
I suppose it does force me to go dig into whatever mapping->pages is to
figure out that there's an unnamed spinlock_t and that the compiler can
insert the appropriate pointer arithmetic, but now my brain trips over
'pages' being at the end of the selector for parameter 1 which slows
down my review reading...
OTOH I guess it /did/ motivate me to click the link, so well played,
sir. :)
--D
> --
> To unsubscribe from this list: send the line "unsubscribe linux-xfs" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
---
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 8+ messages in thread
* [v5,03/78] xarray: Add the xa_lock to the radix_tree_root
@ 2018-01-02 22:41 Matthew Wilcox
0 siblings, 0 replies; 8+ messages in thread
From: Matthew Wilcox @ 2018-01-02 22:41 UTC (permalink / raw)
To: Darrick J. Wong
Cc: Kirill A. Shutemov, linux-kernel, Matthew Wilcox, Ross Zwisler,
David Howells, Shaohua Li, Jens Axboe, Rehas Sachdeva,
Marc Zyngier, linux-mm, linux-fsdevel, linux-f2fs-devel,
linux-nilfs, linux-btrfs, linux-xfs, linux-usb, linux-raid
On Tue, Jan 02, 2018 at 10:01:55AM -0800, Darrick J. Wong wrote:
> On Tue, Dec 26, 2017 at 07:58:15PM -0800, Matthew Wilcox wrote:
> > spin_lock_irqsave(&mapping->pages, flags);
> > __delete_from_page_cache(page, NULL);
> > spin_unlock_irqrestore(&mapping->pages, flags);
> >
> > More details here: https://9p.io/sys/doc/compiler.html
>
> I read the link, and I understand (from section 3.3) that replacing
> foo.bar.baz.goo with foo.goo is less typing, but otoh the first time I
> read your example above I thought "we're passing (an array of pages |
> something that doesn't have the word 'lock' in the name) to
> spin_lock_irqsave? wtf?"
I can see that being a bit jarring initially. If you think about what
object-oriented languages were offering in the nineties, this is basically
C++ multiple-inheritance / Java interfaces. So when I read the above
example, I think "lock the mapping pages, delete from page cache, unlock
the mapping pages", and I don't have a wtf moment. It's just simpler to
read than "lock the mapping pages lock", and less redundant.
> I suppose it does force me to go dig into whatever mapping->pages is to
> figure out that there's an unnamed spinlock_t and that the compiler can
> insert the appropriate pointer arithmetic, but now my brain trips over
> 'pages' being at the end of the selector for parameter 1 which slows
> down my review reading...
>
> OTOH I guess it /did/ motivate me to click the link, so well played,
> sir. :)
Now if only I can trick you into giving your ACK on patch 1,
"xfs: Rename xa_ elements to ail_"
---
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2018-01-02 22:41 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-01-02 18:01 [v5,03/78] xarray: Add the xa_lock to the radix_tree_root Darrick J. Wong
-- strict thread matches above, loose matches on Subject: below --
2018-01-02 22:41 Matthew Wilcox
2017-12-27 10:18 Kirill A. Shutemov
2017-12-27 10:17 Kirill A. Shutemov
2017-12-27 3:58 Matthew Wilcox
2017-12-27 3:43 Matthew Wilcox
2017-12-26 16:54 Kirill A. Shutemov
2017-12-15 22:03 Matthew Wilcox
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).