Scott Lovenberg | 1 Apr 2008 03:03
Picon
Gravatar

Re: RFC: Writing Solaris Device Drivers in Java - OT

David Miller wrote:
From: Peter Teoh <htmldeveloper <at> gmail.com> Date: Mon, 31 Mar 2008 10:14:55 +0800
Ie, imagine using a drivers written for the Solaris in Linux, won't it be cool?
About as cool as a fart in a spacesuit.
Dave, if I were enjoying my favorite caffeinated beverage, you'd owe me a keyboard!
Peter, April fools isn't until tomorrow ;).
Mulyadi Santosa | 1 Apr 2008 03:33
Picon

Re: blktrace debugging: how to use it

Hi :)

On Mon, Mar 31, 2008 at 10:30 PM, Peter Teoh <htmldeveloper <at> gmail.com> wrote:
> On Mon, Mar 31, 2008 at 12:41 PM, Mulyadi Santosa
>  <mulyadi.santosa <at> gmail.com> wrote:
>  > Hi..
>
> >  All I remember, the user space code is available from Jens Axboe's CVS
>  >  or http://www.kernel.org/pub/linux/kernel/people/axboe/tools/blktrace.c
>  >
>  Thanks Mulyadi Santosa, the link I found was:
>
>  http://www.kernel.org/pub/linux/kernel/people/axboe/tools/old/blktrace.c
>
>  (Jens may have change it immediately u sent out the email :-)).

Somehow in the universe, we are linked to each other :D

regards,

Mulyadi.
Robert P. J. Day | 1 Apr 2008 04:10
Picon
Gravatar

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


  (a bit involved so bear with me, i really want to figure out how
this works.)

  i'm following the sample code in the LDD3 book for the "scull"
driver, and i *think* i know the answer to this but i just want to
make sure.  it has to do with how defining a new character device and
opening it manages to set the i_cdev pointer back in the inode
structure.

  first, from <linux/fs.h>, we have the definition of an inode, with
only the relevant fields that i care about:

  struct inode {
	...
        union {
                struct pipe_inode_info  *i_pipe;
                struct block_device     *i_bdev;
                struct cdev             *i_cdev;
        };
	...

  so, depending on the type of file, only one of those pointers will
be valid.  but, initially, if nothing has opened the file represented
by this inode yet, none of those pointers will point at anything
meaningful, right?  so, in the beginning, the pointer i_cdev will not
have a valid address.  so far, so good?  now consider how this relates
to the "scull" example from LDD3.

  here's the structure for representing that new kind of character
device:

  struct scull_dev {
        struct scull_qset *data;  /* Pointer to first quantum set */
        int quantum;              /* the current quantum size */
        int qset;                 /* the current array size */
        unsigned long size;       /* amount of data stored here */
        unsigned int access_key;  /* used by sculluid and scullpriv */
        struct semaphore sem;     /* mutual exclusion semaphore     */
        struct cdev cdev;         /* Char device structure     */
  };

and there at the bottom is the embedded "struct cdev" you're supposed
to build in to your new character device.  the question is -- how does
that structure get associated with the structure pointer back in the
inode?  moving on, here's the character device initialization routine
for that sample "scull" char device:

  /*
   * Set up the char_dev structure for this device.
   */
  static void scull_setup_cdev(struct scull_dev *dev, int index)
  {
        int err, devno = MKDEV(scull_major, scull_minor + index);

        cdev_init(&dev->cdev, &scull_fops);
        dev->cdev.owner = THIS_MODULE;
        dev->cdev.ops = &scull_fops;
        err = cdev_add (&dev->cdev, devno, 1);
        /* Fail gracefully if need be */
        if (err)
                printk(KERN_NOTICE "Error %d adding scull%d", err, index);
  }

  so what does this code do?  from fs/char_dev.c, here's the code for
cdev_init():

  void cdev_init(struct cdev *cdev, const struct file_operations *fops)
  {
        memset(cdev, 0, sizeof *cdev);
        INIT_LIST_HEAD(&cdev->list);
        kobject_init(&cdev->kobj, &ktype_cdev_default);
        cdev->ops = fops;
  }

that doesn't appear to link the cdev back to the inode, but it *does*
create an initialized kobject for the character device.  following
that, cdev_add() is run:

  int cdev_add(struct cdev *p, dev_t dev, unsigned count)
  {
        p->dev = dev;
        p->count = count;
        return kobj_map(cdev_map, dev, count, NULL, exact_match, exact_lock, p);
  }

which appears to fill in the new kobject with information
corresponding to this new character device, but *still*, there's no
connection back to the inode for the device file.  finally, it looks
like it happens here:

  /*
   * Called every time a character special file is opened
   */
  static int chrdev_open(struct inode *inode, struct file *filp)
  {
        struct cdev *p;
        struct cdev *new = NULL;
        int ret = 0;

        spin_lock(&cdev_lock);
        p = inode->i_cdev;
        if (!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) {
                        inode->i_cdev = p = new;
                        inode->i_cindex = idx;
                        list_add(&inode->i_devices, &p->list);
                        new = NULL;
                        ... snip ...

that routine might be called every time a char special file is opened
but, at this point, it still seems that the inode "i_cdev" pointer
isn't yet pointing to the "struct cdev" we've created and initialized.
finally, it seems to happen in this routine, where a test is done to
see if that pointer is set yet:

  p = inode->i_cdev;
  if (!p) {

and if it isn't, then:

  kobj = kobj_lookup(cdev_map, inode->i_rdev, &idx);
  if (!kobj)
    return -ENXIO;
  new = container_of(kobj, struct cdev, kobj);

that *appears* to do a wide-ranging kobject lookup, looking for the
kobject that matches the device ID (inode->i_rdev) and, if it finds
it, then the struct cdev we're looking for is simply the container of
that kobject.  and *finally*,

  if (!p) {
          inode->i_cdev = p = new;

the "i_cdev" struct cdev pointer back in the inode is set and can be
used from now on.  does all that make sense?  in short, the very first
time a character device file is opened and it's noticed that the
inode->i_cdev pointer hasn't been set yet, a kobject-based search is
done to find the corresponding "struct cdev" address to fill into the
inode.  does all this seem to follow?

rday

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?

========================================================================
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 <at> nl.linux.org
Please read the FAQ at http://kernelnewbies.org/FAQ

Wu Yu | 1 Apr 2008 03:50
Picon

Re: Question about linux paging mechanism

Thanks very much! This really helps me a lot.

On Tue, Apr 1, 2008 at 3:30 AM, Rik van Riel <riel <at> surriel.com> wrote:
> On Sun, 30 Mar 2008 17:55:26 +0800
>

>  It means that the kernel pretends that the pgd entry points to a
>  pud (with one entry), even though it really points to a page table.
>
>  By pretenting it points to itself unmap_page_range can call the
>  next function down, zap_pud_range.
>
>  We do the same thing in zap_pud_range - it calls zap_pmd_range on
>  the same pgd entry, except now it thinks it points to a pmd.

Does this mean the entries of pud and pmd just have the address of
pgd? So when the function is called ,the pgd just point back to itself?
When pmd point back to pdg, it thinks it get the page table finally. In
fact, it pgd which contains all the page table. Am I right?

>  --
>  All rights reversed.
>

--

-- 
Wu Yu

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

Michael Blizek | 1 Apr 2008 06:46

Re: Building a packet in the driver

On 17:56 Mon 31 Mar     , cool fire wrote:
> Hello,
> 
> This is regarding Wireless LAN driver. I'm working on madwifi and ath5k. I
> understand that the driver processes a packet it receives from the higher
> layer. But I want to make and transmit a packet without involving the higher
> layers using madwifi/ath5k. Could you please tell me how to do it.

Hi!

What headers should this packet have? IP? UDP?
What are you using it for?
	-Michi
--

-- 
programing a layer 3+4 network protocol for mesh networks
see http://michaelblizek.homelinux.net

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

Peter Teoh | 1 Apr 2008 10:54
Picon
Gravatar

RFC: swaptrace tool

Go through this:

http://linux-mm.org/LinuxMMProjects

and u find there is no swaptrace.   What I want is a visualization of
how the swap is being use.   So once the operation is started, all
swap operation will be immediately written to an area in memory,
showing how the swap is written - the destination begin offset /
destination end offset/size info, and by what process/task - and its
correspond source begin offset, and source end offset.   The data
content itself will not be recorded.   Then after some time, via
ioctl() control, it will be stopped, and all that have been written to
memory will be flushed out to a file.   This flushing to external file
only take place after the data collection has stopped, otherwise, the
swap operations itself will affect the behavior of the swap, thus
rendering the data collection invalid.

The purpose of this trace is to see/oberver how the swap is being
used, whether any algor can help to cluster the swap together so as to
enhance swap batch processing etc.

Any comment on this idea?   Will it be useful?

--

-- 
Regards,
Peter Teoh

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

Mulyadi Santosa | 1 Apr 2008 12:26
Picon

Re: RFC: swaptrace tool

hi

On Tue, Apr 1, 2008 at 3:54 PM, Peter Teoh <htmldeveloper <at> gmail.com> wrote:
> Go through this:
>
>  http://linux-mm.org/LinuxMMProjects

once I posted unfinished per process swap usage statistics to
LKML....IIRC around mid 2007. Somebody care to look (again) and helped
me to improve it?

regards,

Mulyadi.

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

Peter Chubb | 1 Apr 2008 11:31
Picon
Picon
Favicon

Re: RFC: swaptrace tool

>>>>> "Peter" == Peter Teoh <htmldeveloper <at> gmail.com> writes:

Peter> Go through this: http://linux-mm.org/LinuxMMProjects

Peter> and u find there is no swaptrace.  What I want is a
Peter> visualization of how the swap is being use.  So once the
Peter> operation is started, all swap operation will be immediately
Peter> written to an area in memory, showing how the swap is written -
Peter> the destination begin offset / destination end offset/size
Peter> info, and by what process/task - and its correspond source
Peter> begin offset, and source end offset.  The data content itself
Peter> will not be recorded.  Then after some time, via ioctl()
Peter> control, it will be stopped, and all that have been written to
Peter> memory will be flushed out to a file.  This flushing to
Peter> external file only take place after the data collection has
Peter> stopped, otherwise, the swap operations itself will affect the
Peter> behavior of the swap, thus rendering the data collection
Peter> invalid.

You could probably do this with blktrace for a swap partition, which
can do exactly this on any block device.   For swap files, it's a bit harder.

--
Dr Peter Chubb  http://www.gelato.unsw.edu.au  peterc AT gelato.unsw.edu.au
http://www.ertos.nicta.com.au           ERTOS within National ICT Australia

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

Robert P. J. Day | 1 Apr 2008 13:38
Picon
Gravatar

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


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.

i'll look at it a bit more carefully.

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 <at> nl.linux.org
Please read the FAQ at http://kernelnewbies.org/FAQ

Matthias Kaehlcke | 1 Apr 2008 12:59

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

El Mon, Mar 31, 2008 at 10:10:41PM -0400 Robert P. J. Day ha dit:

> 
>   (a bit involved so bear with me, i really want to figure out how
> this works.)
> 
>   i'm following the sample code in the LDD3 book for the "scull"
> driver, and i *think* i know the answer to this but i just want to
> make sure.  it has to do with how defining a new character device and
> opening it manages to set the i_cdev pointer back in the inode
> structure.
> 
>   first, from <linux/fs.h>, we have the definition of an inode, with
> only the relevant fields that i care about:
> 
>   struct inode {
> 	...
>         union {
>                 struct pipe_inode_info  *i_pipe;
>                 struct block_device     *i_bdev;
>                 struct cdev             *i_cdev;
>         };
> 	...
> 
>   so, depending on the type of file, only one of those pointers will
> be valid.  but, initially, if nothing has opened the file represented
> by this inode yet, none of those pointers will point at anything
> meaningful, right?  so, in the beginning, the pointer i_cdev will not
> have a valid address.  so far, so good?  now consider how this relates
> to the "scull" example from LDD3.
> 
>   here's the structure for representing that new kind of character
> device:
> 
>   struct scull_dev {
>         struct scull_qset *data;  /* Pointer to first quantum set */
>         int quantum;              /* the current quantum size */
>         int qset;                 /* the current array size */
>         unsigned long size;       /* amount of data stored here */
>         unsigned int access_key;  /* used by sculluid and scullpriv */
>         struct semaphore sem;     /* mutual exclusion semaphore     */
>         struct cdev cdev;         /* Char device structure     */
>   };
> 
> and there at the bottom is the embedded "struct cdev" you're supposed
> to build in to your new character device.  the question is -- how does
> that structure get associated with the structure pointer back in the
> inode?  moving on, here's the character device initialization routine
> for that sample "scull" char device:
> 
>   /*
>    * Set up the char_dev structure for this device.
>    */
>   static void scull_setup_cdev(struct scull_dev *dev, int index)
>   {
>         int err, devno = MKDEV(scull_major, scull_minor + index);
> 
>         cdev_init(&dev->cdev, &scull_fops);
>         dev->cdev.owner = THIS_MODULE;
>         dev->cdev.ops = &scull_fops;
>         err = cdev_add (&dev->cdev, devno, 1);
>         /* Fail gracefully if need be */
>         if (err)
>                 printk(KERN_NOTICE "Error %d adding scull%d", err, index);
>   }
> 
>   so what does this code do?  from fs/char_dev.c, here's the code for
> cdev_init():
> 
>   void cdev_init(struct cdev *cdev, const struct file_operations *fops)
>   {
>         memset(cdev, 0, sizeof *cdev);
>         INIT_LIST_HEAD(&cdev->list);
>         kobject_init(&cdev->kobj, &ktype_cdev_default);
>         cdev->ops = fops;
>   }
> 
> that doesn't appear to link the cdev back to the inode, but it *does*
> create an initialized kobject for the character device.  following
> that, cdev_add() is run:
> 
>   int cdev_add(struct cdev *p, dev_t dev, unsigned count)
>   {
>         p->dev = dev;
>         p->count = count;
>         return kobj_map(cdev_map, dev, count, NULL, exact_match, exact_lock, p);
>   }
> 
> which appears to fill in the new kobject with information
> corresponding to this new character device, but *still*, there's no
> connection back to the inode for the device file.  finally, it looks
> like it happens here:
> 
>   /*
>    * Called every time a character special file is opened
>    */
>   static int chrdev_open(struct inode *inode, struct file *filp)
>   {
>         struct cdev *p;
>         struct cdev *new = NULL;
>         int ret = 0;
> 
>         spin_lock(&cdev_lock);
>         p = inode->i_cdev;
>         if (!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) {
>                         inode->i_cdev = p = new;
>                         inode->i_cindex = idx;
>                         list_add(&inode->i_devices, &p->list);
>                         new = NULL;
>                         ... snip ...
> 
> that routine might be called every time a char special file is opened
> but, at this point, it still seems that the inode "i_cdev" pointer
> isn't yet pointing to the "struct cdev" we've created and initialized.
> finally, it seems to happen in this routine, where a test is done to
> see if that pointer is set yet:
> 
>   p = inode->i_cdev;
>   if (!p) {
> 
> and if it isn't, then:
> 
>   kobj = kobj_lookup(cdev_map, inode->i_rdev, &idx);
>   if (!kobj)
>     return -ENXIO;
>   new = container_of(kobj, struct cdev, kobj);
> 
> that *appears* to do a wide-ranging kobject lookup, looking for the
> kobject that matches the device ID (inode->i_rdev) and, if it finds
> it, then the struct cdev we're looking for is simply the container of
> that kobject.  and *finally*,
> 
>   if (!p) {
>           inode->i_cdev = p = new;
> 
> the "i_cdev" struct cdev pointer back in the inode is set and can be
> used from now on.  does all that make sense?  in short, the very first
> time a character device file is opened and it's noticed that the
> inode->i_cdev pointer hasn't been set yet, a kobject-based search is
> done to find the corresponding "struct cdev" address to fill into the
> inode.  does all this seem to follow?
> 
> rday
> 
> 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.

--

-- 
Matthias Kaehlcke
Linux System Developer
Barcelona

  Control over the use of one's ideas really constitutes control over other
  people's lives; and it is usually used to make their lives more difficult.
                          (Richard Stallman)
                                                                 .''`.
    using free software / Debian GNU/Linux | http://debian.org  : :'  :
                                                                `. `'`
gpg --keyserver pgp.mit.edu --recv-keys 47D8E5D4                  `-

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


Gmane