Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 10 Oct 2002 22:30:53 +0200
From:      Stefan Farfeleder <e0026813@stud3.tuwien.ac.at>
To:        Terry Lambert <tlambert2@mindspring.com>
Cc:        Don Lewis <dl-freebsd@catspoiler.org>, jhb@FreeBSD.ORG, jmallett@FreeBSD.ORG, current@FreeBSD.ORG, phk@FreeBSD.ORG
Subject:   Re: [PATCH] Re: Junior Kernel Hacker page updated...
Message-ID:  <20021010203053.GA265@frog.fafoe>
In-Reply-To: <3DA4B6C1.ED1BACEB@mindspring.com>
References:  <20021008204605.GA252@frog.fafoe> <200210090426.g994QTvU037393@gw.catspoiler.org> <20021009225606.GC306@frog.fafoe> <3DA4B6C1.ED1BACEB@mindspring.com>

next in thread | previous in thread | raw e-mail | index | archive | help
On Wed, Oct 09, 2002 at 04:07:45PM -0700, Terry Lambert wrote:
> Stefan Farfeleder wrote:
> > Is it just a warning or does it pose a real problem?
> > 
> > I think the problem with the current code is that knote_{en,de}queue can
> > be executed in parallel (on another CPU, spl*() can't prevent that, can
> > it?) with kqueue_scan and that kq->kq_head thus can be corrupted.
> > Or am I totally wrong?
> 
> My patch would have worked, in that case, since it would ensure
> one marker entry with a unique stack address per simultaneous
> scanner.
> 
> It has to be that the queue itself is being deleted out from
> under it: the problem is not the scan, nor the insert or the
> delete.
> 
> Most likely, this is for an object whose queue is not tracked
> by process, or for a process queue that's being examined by
> another process (e.g. kevent's on fork/exit/etc.).
> 
> You can verify this for your own satisfaction by looking at the
> pointer manipulation order for the insertion and deletion; the
> insertion sets the next pointer before setting the pointer to
> the inserted object, and the deletion sets the pointer that
> used to point to the deleted object to the delete object's next,
> before deleting the object.  Thus, traversals in progress should
> not result in an error.

Imagine this scenario where CPU 0 inserts a knote kn1 (the marker) in
knote_scan and CPU 1 kn2 in kqueue_enqueue:


        CPU 0                   |           CPU 1
--------------------------------+-------------------------------
kn1->kn_tqe.tqe_next = NULL;    |
                                |
--------------------------------+-------------------------------
kn1->kn_tqe.tqe_prev =          |   kn2->kn_tqe.tqe_next = NULL;
    kq_head.tqh_last;           |
--------------------------------+-------------------------------
*kq_head.tqh_last = kn1;        |   kn2->kn_tqe.tqe_prev =
                                |       kq_head.tqh_last;
--------------------------------+-------------------------------
kq_head.tqh_last =              |   *kq_head.tqh_last = kn2;
    &kn1->kn_tqe.tqe_next;      |
--------------------------------+-------------------------------
                                |   kq_head.tqh_last =
                                |       &kn2->kn_tqe.tqe_next;

The marker would never appear on the queue.

Regards,
Stefan Farfeleder

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-current" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20021010203053.GA265>