linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Dan Carpenter <dan.carpenter@oracle.com>
To: aarcange@redhat.com
Cc: linux-fsdevel@vger.kernel.org
Subject: re: userfaultfd: add new syscall to provide memory externalization
Date: Tue, 26 May 2015 12:03:33 +0300	[thread overview]
Message-ID: <20150526090333.GA6670@mwanda> (raw)

Hello Andrea Arcangeli,

The patch 126710df097a: "userfaultfd: add new syscall to provide
memory externalization" from May 23, 2015, leads to the following
static checker warning:

	fs/userfaultfd.c:567 userfaultfd_ctx_read()
	error:  locking inconsistency.  We assume 'irq:' is both locked and unlocked at the start.

fs/userfaultfd.c
   505  static ssize_t userfaultfd_ctx_read(struct userfaultfd_ctx *ctx, int no_wait,
   506                                      struct uffd_msg *msg)
   507  {
   508          ssize_t ret;
   509          DECLARE_WAITQUEUE(wait, current);
   510          struct userfaultfd_wait_queue *uwq;
   511  
   512          /* always take the fd_wqh lock before the fault_pending_wqh lock */
   513          spin_lock(&ctx->fd_wqh.lock);
   514          __add_wait_queue(&ctx->fd_wqh, &wait);
   515          for (;;) {
   516                  set_current_state(TASK_INTERRUPTIBLE);
   517                  spin_lock(&ctx->fault_pending_wqh.lock);
   518                  uwq = find_userfault(ctx);
   519                  if (uwq) {
   520                          /*
   521                           * The fault_pending_wqh.lock prevents the uwq
   522                           * to disappear from under us.
   523                           *
   524                           * Refile this userfault from
   525                           * fault_pending_wqh to fault_wqh, it's not
   526                           * pending anymore after we read it.
   527                           *
   528                           * Use list_del() by hand (as
   529                           * userfaultfd_wake_function also uses
   530                           * list_del_init() by hand) to be sure nobody
   531                           * changes __remove_wait_queue() to use
   532                           * list_del_init() in turn breaking the
   533                           * !list_empty_careful() check in
   534                           * handle_userfault(). The uwq->wq.task_list
   535                           * must never be empty at any time during the
   536                           * refile, or the waitqueue could disappear
   537                           * from under us. The "wait_queue_head_t"
   538                           * parameter of __remove_wait_queue() is unused
   539                           * anyway.
   540                           */
   541                          list_del(&uwq->wq.task_list);
   542                          __add_wait_queue(&ctx->fault_wqh, &uwq->wq);
   543  
   544                          /* careful to always initialize msg if ret == 0 */
   545                          *msg = uwq->msg;
   546                          spin_unlock(&ctx->fault_pending_wqh.lock);
   547                          ret = 0;
   548                          break;
   549                  }
   550                  spin_unlock(&ctx->fault_pending_wqh.lock);
   551                  if (signal_pending(current)) {
   552                          ret = -ERESTARTSYS;
   553                          break;
   554                  }
   555                  if (no_wait) {
   556                          ret = -EAGAIN;
   557                          break;
   558                  }
   559                  spin_unlock(&ctx->fd_wqh.lock);
   560                  schedule();
   561                  spin_lock_irq(&ctx->fd_wqh.lock);
                                  ^^^
_irq() here.

   562          }
   563          __remove_wait_queue(&ctx->fd_wqh, &wait);
   564          __set_current_state(TASK_RUNNING);
   565          spin_unlock_irq(&ctx->fd_wqh.lock);
                           ^^^^
and here.

   566  
   567          return ret;
   568  }

regards,
dan carpenter

                 reply	other threads:[~2015-05-26 15:53 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

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=20150526090333.GA6670@mwanda \
    --to=dan.carpenter@oracle.com \
    --cc=aarcange@redhat.com \
    --cc=linux-fsdevel@vger.kernel.org \
    /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 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).