All of lore.kernel.org
 help / color / mirror / Atom feed
From: Cong Wang <xiyou.wangcong@gmail.com>
To: Vlad Buslov <vladbu@mellanox.com>
Cc: Linux Kernel Network Developers <netdev@vger.kernel.org>,
	David Miller <davem@davemloft.net>,
	Jamal Hadi Salim <jhs@mojatatu.com>,
	Jiri Pirko <jiri@resnulli.us>,
	Alexei Starovoitov <ast@kernel.org>,
	Daniel Borkmann <daniel@iogearbox.net>,
	Yevgeny Kliteynik <kliteyn@mellanox.com>,
	Jiri Pirko <jiri@mellanox.com>
Subject: Re: [PATCH net-next v6 10/11] net: sched: atomically check-allocate action
Date: Thu, 9 Aug 2018 16:43:29 -0700	[thread overview]
Message-ID: <CAM_iQpU=+gSrmV5+bSekr5SD+PgrYHN6YXsLpRC=_p09m0a0ew@mail.gmail.com> (raw)
In-Reply-To: <vbfpnyt2hbw.fsf@reg-r-vrt-018-180.mtr.labs.mlnx>

On Wed, Aug 8, 2018 at 5:06 AM Vlad Buslov <vladbu@mellanox.com> wrote:
>
>
> On Wed 08 Aug 2018 at 01:20, Cong Wang <xiyou.wangcong@gmail.com> wrote:
> > On Thu, Jul 5, 2018 at 7:24 AM Vlad Buslov <vladbu@mellanox.com> wrote:
> >>
> >> Implement function that atomically checks if action exists and either takes
> >> reference to it, or allocates idr slot for action index to prevent
> >> concurrent allocations of actions with same index. Use EBUSY error pointer
> >> to indicate that idr slot is reserved.
> >
> > A dumb question:
> >
> > How could "concurrent allocations of actions with same index" happen
> > as you already take idrinfo->lock for the whole
> > tcf_idr_check_alloc()??
>
> I guess my changelog is not precise enough in this description.
> Let look into sequence of events of initialization of new action:
> 1) tcf_idr_check_alloc() is called by action init.
> 2) idrinfo->lock is taken.
> 3) Lookup in idr is performed to determine if action with specified
> index already exists.
> 4) EBUSY pointer is inserted to indicate that id is taken.
> 5) idrinfo->lock is released.
> 6) tcf_idr_check_alloc() returns to action init code.
> 7) New action is allocated and initialized.
> 8) tcf_idr_insert() is called.
> 9) idrinfo->lock is taken.
> 10) EBUSY pointer is substituted with pointer to new action.
> 11) idrinfo->lock is released.
> 12) tcf_idr_insert() returns.
>
> So in this case "concurrent allocations of actions with same index"
> means not the allocation with same index during tcf_idr_check_alloc(),
> but during the period when idrinfo->lock was released(6-8).

Yes but it is unnecessary:

a) When adding a new action, you can actually allocate and init it before
touching idrinfo, therefore the check and insert can be done in one step
instead of breaking down it into multiple steps, which means you can
acquire idrinfo->lock once.

b) When updating an existing action, it is slightly complicated.
However, you can still allocate a new one first, then find the old one
and copy it into the new one and finally replace it.

In summary, we can do the following:

1. always allocate a new action
2. acquire idrinfo->lock
3a. if it is an add operation: allocate a new ID and insert the new action
3b. if it is a replace operation: find the old one with ID, copy it into the
new one and replace it
4. release idrinfo->lock
5. If 3a or 3b fails, free the allocation. Otherwise succeed.

I know, the locking scope is now per netns rather than per action,
but this can be optimized for replacing, you can hold the old action
and then release the idrinfo->lock, as idr_replace() later doesn't
require idrinfo->lock AFAIK.

Is there anything I miss here?


>
> >
> > For me, it should be only one allocation could succeed, all others
> > should fail.
>
> Correct! And this change is made specifically to enforce that rule.
>
> Otherwise, multiple processes could try to create new action with same
> id at the same time, and all processes that executed 3, before any
> process reached 10, will "succeed" by overwriting each others action in
> idr. (and leak memory while doing so)

I know but again it doesn't look necessary to achieve a same goal.


>
> >
> > Maybe you are trying to prevent others treat it like existing one,
> > but in that case you can just hold the idinfo->lock for all idr operations.
> >
> > And more importantly, upper layer is able to tell it is a creation or
> > just replace, you don't have to check this in this complicated way.
> >
> > IOW, all of these complicated code should not exist.
>
> Original code was simpler and didn't involve temporary EBUSY pointer.
> This change was made according to Jiri's request. He wanted to have
> unified API to be used by all actions and suggested this approach
> specifically.

I will work on this, as this is aligned to my work to make
it RCU-complete.

  reply	other threads:[~2018-08-10  2:10 UTC|newest]

Thread overview: 37+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-07-05 14:24 [PATCH net-next v6 00/11] Modify action API for implementing lockless actions Vlad Buslov
2018-07-05 14:24 ` [PATCH net-next v6 01/11] net: sched: use rcu for action cookie update Vlad Buslov
2018-07-13  3:52   ` Cong Wang
2018-07-13 13:30     ` Vlad Buslov
2018-07-13 21:51       ` Cong Wang
2018-07-13 22:11         ` David Miller
2018-07-14  0:14           ` Cong Wang
2018-07-16  8:31         ` Vlad Buslov
2018-07-17 20:46           ` Cong Wang
2018-07-05 14:24 ` [PATCH net-next v6 02/11] net: sched: change type of reference and bind counters Vlad Buslov
2018-07-05 14:24 ` [PATCH net-next v6 03/11] net: sched: implement unlocked action init API Vlad Buslov
2018-07-05 14:24 ` [PATCH net-next v6 04/11] net: sched: always take reference to action Vlad Buslov
2018-07-05 14:24 ` [PATCH net-next v6 05/11] net: sched: implement action API that deletes action by index Vlad Buslov
2018-07-05 14:24 ` [PATCH net-next v6 06/11] net: sched: add 'delete' function to action ops Vlad Buslov
2018-08-09 19:38   ` Cong Wang
2018-08-10  9:41     ` Vlad Buslov
2018-07-05 14:24 ` [PATCH net-next v6 07/11] net: sched: implement reference counted action release Vlad Buslov
2018-07-05 14:24 ` [PATCH net-next v6 08/11] net: sched: don't release reference on action overwrite Vlad Buslov
2018-08-13 23:00   ` Cong Wang
2018-08-14 17:23     ` Vlad Buslov
2018-07-05 14:24 ` [PATCH net-next v6 09/11] net: sched: use reference counting action init Vlad Buslov
2018-07-05 14:24 ` [PATCH net-next v6 10/11] net: sched: atomically check-allocate action Vlad Buslov
2018-08-08  1:20   ` Cong Wang
2018-08-08 12:06     ` Vlad Buslov
2018-08-09 23:43       ` Cong Wang [this message]
2018-08-10 10:29         ` Vlad Buslov
2018-08-10 21:45           ` Cong Wang
2018-08-13  7:55             ` Vlad Buslov
2018-07-05 14:24 ` [PATCH net-next v6 11/11] net: sched: change action API to use array of pointers to actions Vlad Buslov
2018-08-07 23:26   ` Cong Wang
2018-08-08 11:41     ` Vlad Buslov
2018-08-08 18:29       ` Cong Wang
2018-08-09  7:03         ` Vlad Buslov
2018-07-07 11:41 ` [PATCH net-next v6 00/11] Modify action API for implementing lockless actions David Miller
2018-07-08  3:43 ` David Miller
2018-07-13  3:54   ` Cong Wang
2018-07-13 13:40     ` Vlad Buslov

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='CAM_iQpU=+gSrmV5+bSekr5SD+PgrYHN6YXsLpRC=_p09m0a0ew@mail.gmail.com' \
    --to=xiyou.wangcong@gmail.com \
    --cc=ast@kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=davem@davemloft.net \
    --cc=jhs@mojatatu.com \
    --cc=jiri@mellanox.com \
    --cc=jiri@resnulli.us \
    --cc=kliteyn@mellanox.com \
    --cc=netdev@vger.kernel.org \
    --cc=vladbu@mellanox.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.