All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jan Kara <jack@suse.cz>
To: Amir Goldstein <amir73il@gmail.com>
Cc: Jan Kara <jack@suse.cz>,
	linux-fsdevel <linux-fsdevel@vger.kernel.org>,
	Paul Moore <paul@paul-moore.com>,
	Miklos Szeredi <miklos@szeredi.hu>
Subject: Re: [PATCH 06/22] fsnotify: Attach marks to object via dedicated head structure
Date: Tue, 10 Jan 2017 14:30:27 +0100	[thread overview]
Message-ID: <20170110133027.GO4991@quack2.suse.cz> (raw)
In-Reply-To: <CAOQ4uxgyLkGBR4EczWd7+GJPm0kOQ3w5a5BxALK2oiviCvSP5w@mail.gmail.com>

On Sun 08-01-17 12:18:10, Amir Goldstein wrote:
> On Fri, Jan 6, 2017 at 12:43 PM, Jan Kara <jack@suse.cz> wrote:
> > +static struct inode *fsnotify_detach_from_object(struct fsnotify_mark *mark)
> > +{
> > +       struct fsnotify_mark_connector *conn;
> > +       struct inode *inode = NULL;
> > +       bool free_conn = false;
> > +
> > +       conn = mark->connector;
> > +       spin_lock(&conn->lock);
> > +       hlist_del_init_rcu(&mark->obj_list);
> > +       if (hlist_empty(&conn->list)) {
> > +               if (conn->flags & FSNOTIFY_OBJ_TYPE_INODE) {
> > +                       inode = conn->inode;
> > +                       inode->i_fsnotify_marks = NULL;
> 
> Shouldn't that assignment be done using rcu_assign_pointer() to
> match srcu_dereference(to_tell->i_fsnotify_marks, &fsnotify_mark_srcu); ?

Good catch (although this is only cosmetic - the assignment cannot escape
the conn->lock section and within it it does not matter where it happens
even for unlocked accesses). Done.
  
> > +/*
> > + * Get mark connector, make sure it is alive and return with its lock held.
> > + * This is for users that get connector pointer from inode or mount. Users that
> > + * hold reference to a mark on the list may directly lock connector->lock as
> > + * they are sure list cannot go away under them.
> > + */
> > +static struct fsnotify_mark_connector *fsnotify_grab_connector(
> > +                               struct fsnotify_mark_connector * __rcu *connp)
> > +{
> > +       struct fsnotify_mark_connector *conn;
> > +       int idx;
> > +
> > +       idx = srcu_read_lock(&fsnotify_mark_srcu);
> > +       conn = srcu_dereference(*connp, &fsnotify_mark_srcu);
> > +       if (!conn)
> > +               goto out;
> > +       spin_lock(&conn->lock);
> > +       if (!(conn->flags & (FSNOTIFY_OBJ_TYPE_INODE |
> > +                            FSNOTIFY_OBJ_TYPE_VFSMOUNT))) {
> > +               spin_unlock(&conn->lock);
> > +               srcu_read_unlock(&fsnotify_mark_srcu, idx);
> > +               return NULL;
> > +       }
> > +out:
> > +       srcu_read_unlock(&fsnotify_mark_srcu, idx);
> > +       return conn;
> > +}
> > +
> > +static void fsnotify_put_connector(struct fsnotify_mark_connector *conn)
> > +{
> > +       spin_unlock(&conn->lock);
> > +}
> > +
> 
> Is there a precedent in the kernel for using grab()/put() semantics for
> what is essentially aquire()/release() for exclusive object access?
> 
> The counterpart for grab_cache_page(), for example, is
> unlock_page(page); put_page(page); (and not just put_page()).
> 
> igrab() does not return with i_lock held, so igrab()/iput() sematics
> do not apply to this case.
> 
> I find a function that is called put_connector() and actually does unlock
> to be confusing and if that function is a one liner helper, I prefer that
> it did not exist at all and call site should use spin_unlock(&conn->lock);
> explicitly instead of hiding it.

OK, probably you're right. I'll remove this function.

> > +/*
> > + * Add mark into proper place in given list of marks. These marks may be used
> > + * for the fsnotify backend to determine which event types should be delivered
> > + * to which group and for which inodes. These marks are ordered according to
> > + * priority, highest number first, and then by the group's location in memory.
> > + */
> > +static int fsnotify_add_mark_list(struct fsnotify_mark *mark,
> > +                                 struct inode *inode, struct vfsmount *mnt,
> > +                                 int allow_dups)
> >  {
> >         struct fsnotify_mark *lmark, *last = NULL;
> > +       struct fsnotify_mark_connector *conn;
> > +       struct fsnotify_mark_connector **connp;
> >         int cmp;
> > +       int err = 0;
> > +
> > +       BUG_ON(!inode && !mnt);
> > +       if (inode)
> > +               connp = &inode->i_fsnotify_marks;
> > +       else
> > +               connp = &real_mount(mnt)->mnt_fsnotify_marks;
> > +restart:
> > +       spin_lock(&mark->lock);
> > +       conn = fsnotify_grab_connector(connp);
> > +       if (!conn) {
> > +               spin_unlock(&mark->lock);
> > +               conn = kmem_cache_alloc(fsnotify_mark_connector_cachep,
> > +                                       GFP_KERNEL);
> > +               if (!conn)
> > +                       return -ENOMEM;
> > +               spin_lock_init(&conn->lock);
> > +               INIT_HLIST_HEAD(&conn->list);
> > +               if (inode) {
> > +                       conn->flags = FSNOTIFY_OBJ_TYPE_INODE;
> > +                       conn->inode = igrab(inode);
> > +               } else {
> > +                       conn->flags = FSNOTIFY_OBJ_TYPE_VFSMOUNT;
> > +                       conn->mnt = mnt;
> > +               }
> > +               if (cmpxchg(connp, NULL, conn)) {
> 
> Same question as in fsnotify_detach_from_object()
> Is there a need for any smb_wmb() here to match
> srcu_dereference() in fsnotify(), or is there no need because
> cmpxchg from NULL to a live object is always safe for the reader?

cmpxchg() is already guaranteed to contain the required barrier (see
Documentation/core-api/atomic_ops.rst).

								Honza
-- 
Jan Kara <jack@suse.com>
SUSE Labs, CR

  reply	other threads:[~2017-01-10 13:30 UTC|newest]

Thread overview: 40+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-01-06 10:43 [PATCH 0/22 v2] fsnotify: Avoid SRCU stalls with fanotify permission events Jan Kara
2017-01-06 10:43 ` [PATCH 01/22] fsnotify: Remove unnecessary tests when showing fdinfo Jan Kara
2017-01-06 10:43 ` [PATCH 02/22] inotify: Remove inode pointers from debug messages Jan Kara
2017-01-06 10:43 ` [PATCH 03/22] fanotify: Move recalculation of inode / vfsmount mask under mark_mutex Jan Kara
2017-01-06 10:43 ` [PATCH 04/22] audit: Abstract hash key handling Jan Kara
2017-01-06 10:43 ` [PATCH 05/22] fsnotify: Update comments Jan Kara
2017-01-06 10:43 ` [PATCH 06/22] fsnotify: Attach marks to object via dedicated head structure Jan Kara
2017-01-06 13:12   ` Amir Goldstein
2017-01-08 10:18   ` Amir Goldstein
2017-01-10 13:30     ` Jan Kara [this message]
2017-01-06 10:43 ` [PATCH 07/22] inotify: Do not drop mark reference under idr_lock Jan Kara
2017-01-06 10:43 ` [PATCH 08/22] fsnotify: Move queueing of mark for destruction into fsnotify_put_mark() Jan Kara
2017-01-08 11:15   ` Amir Goldstein
2017-01-06 10:43 ` [PATCH 09/22] fsnotify: Detach mark from object list when last reference is dropped Jan Kara
2017-01-08 12:10   ` Amir Goldstein
2017-01-10 13:47     ` Jan Kara
2017-01-06 10:43 ` [PATCH 10/22] fsnotify: Remove special handling of mark destruction on group shutdown Jan Kara
2017-01-06 10:43 ` [PATCH 11/22] fsnotify: Provide framework for dropping SRCU lock in ->handle_event Jan Kara
2017-01-08  9:02   ` Amir Goldstein
2017-01-10 13:00     ` Jan Kara
2017-01-06 10:43 ` [PATCH 12/22] fsnotify: Pass SRCU index into handle_event handler Jan Kara
2017-01-06 10:43 ` [PATCH 13/22] fanotify: Release SRCU lock when waiting for userspace response Jan Kara
2017-01-06 10:43 ` [PATCH 14/22] fsnotify: Remove fsnotify_set_mark_{,ignored_}mask_locked() Jan Kara
2017-01-06 10:43 ` [PATCH 15/22] fsnotify: Remove fsnotify_recalc_{inode|vfsmount}_mask() Jan Kara
2017-01-06 10:43 ` [PATCH 16/22] fsnotify: Inline fsnotify_clear_{inode|vfsmount}_mark_group() Jan Kara
2017-01-06 10:43 ` [PATCH 17/22] fsnotify: Rename fsnotify_clear_marks_by_group_flags() Jan Kara
2017-01-08 12:17   ` Amir Goldstein
2017-01-06 10:43 ` [PATCH 18/22] fsnotify: Remove fsnotify_detach_group_marks() Jan Kara
2017-01-08 12:26   ` Amir Goldstein
2017-01-06 10:43 ` [PATCH 19/22] fsnotify: Remove fsnotify_find_{inode|vfsmount}_mark() Jan Kara
2017-01-06 10:43 ` [PATCH 20/22] fsnotify: Drop inode_mark.c Jan Kara
2017-01-06 10:44 ` [PATCH 21/22] fsnotify: Add group pointer in fsnotify_init_mark() Jan Kara
2017-01-08 12:35   ` Amir Goldstein
2017-01-10 13:48     ` Jan Kara
2017-01-06 10:44 ` [PATCH 22/22] fsnotify: Move ->free_mark callback to fsnotify_ops Jan Kara
2017-01-08 12:50 ` [PATCH 0/22 v2] fsnotify: Avoid SRCU stalls with fanotify permission events Amir Goldstein
2017-01-20 13:21 [PATCH 0/22 v3] " Jan Kara
2017-01-20 13:21 ` [PATCH 06/22] fsnotify: Attach marks to object via dedicated head structure Jan Kara
2017-01-21 15:52   ` Amir Goldstein
2017-01-25  9:41   ` Miklos Szeredi
2017-01-31 15:41     ` Jan Kara

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20170110133027.GO4991@quack2.suse.cz \
    --to=jack@suse.cz \
    --cc=amir73il@gmail.com \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=miklos@szeredi.hu \
    --cc=paul@paul-moore.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.