Re: how does opening a char device set the cdev pointer in the inode?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, 1 Apr 2008, Matthias Kaehlcke wrote:

> El Tue, Apr 01, 2008 at 07:38:05AM -0400 Robert P. J. Day ha dit:
>
> >
> > regarding the routine "chrdev_open()" in fs/char_dev.c:
> >
> > On Tue, 1 Apr 2008, Matthias Kaehlcke wrote:
> >
> > > El Mon, Mar 31, 2008 at 10:10:41PM -0400 Robert P. J. Day ha dit:
> >
> > > > p.s.  i am a bit confused as to why there are two tests for whether
> > > > inode->i_cdev is non-NULL:
> > > >
> > > >         p = inode->i_cdev;
> > > >         if (!p) {                            <-- first test of p
> > > >                 struct kobject *kobj;
> > > >                 int idx;
> > > >                 spin_unlock(&cdev_lock);
> > > >                 kobj = kobj_lookup(cdev_map, inode->i_rdev, &idx);
> > > >                 if (!kobj)
> > > >                         return -ENXIO;
> > > >                 new = container_of(kobj, struct cdev, kobj);
> > > >                 spin_lock(&cdev_lock);
> > > >                 p = inode->i_cdev;
> > > >                 if (!p) {                    <-- second test of p
> > > >                         inode->i_cdev = p = new;
> > > >
> > > >
> > > > why is that first test being repeated further down?  if p was NULL
> > > > at that first test, how could it possibly have changed before that
> > > > second test?  isn't that second test redundant?  or am i missing
> > > > something?
> > >
> > > if i understand that piece of code correctly inode->i_cdev could
> > > have changed (probably by a concurrent invocation of the same
> > > function) while cdev_lock is not hold and inode->i_cdev is
> > > reassigned to p.
> >
> > possibly, but wouldn't that create an ugly synchronization
> > scenario? say, if two invocations of that routine both arrived at
> > that second test of "p" simultaneously, both found it NULL, and
> > both then tried to set it?  and, in any event, both would
> > technically need to set it to the *same* value, anyway.  so it's
> > still not clear what that second test is for.
>
> they can't arrive at the second test simultaneously cause cdev_lock
> is used for synchronization.
>
> yes, they would set it to the same value, but two calls to
> list_add(&inode->i_devices, &p->list) would result in
> inode->i_devices being added twice to p->list.

yes, of course you're right, but i still can't help feeling that
there's some unnecessary testing happening here.  oh, well ... it
obviously works so i'm not going to agonize over it.

rday
--

========================================================================
Robert P. J. Day
Linux Consulting, Training and Annoying Kernel Pedantry:
    Have classroom, will lecture.

http://crashcourse.ca                          Waterloo, Ontario, CANADA
========================================================================

--
To unsubscribe from this list: send an email with
"unsubscribe kernelnewbies" to ecartis@xxxxxxxxxxxx
Please read the FAQ at http://kernelnewbies.org/FAQ


[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux