Re: Driver duplicate?

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

 





On Mon, Mar 7, 2016 at 3:53 PM, Greg KH <greg@xxxxxxxxx> wrote:
On Mon, Mar 07, 2016 at 03:37:24PM -0500, Kenneth Adam Miller wrote:
>
>
> On Mon, Mar 7, 2016 at 3:29 PM, Greg KH <greg@xxxxxxxxx> wrote:
>
>     On Mon, Mar 07, 2016 at 03:21:44PM -0500, Kenneth Adam Miller wrote:
>     >
>     >
>     > On Mon, Mar 7, 2016 at 3:17 PM, Greg KH <greg@xxxxxxxxx> wrote:
>     >
>     >     On Mon, Mar 07, 2016 at 03:00:50PM -0500, Kenneth Adam Miller wrote:
>     >     > I have a driver that manages three sets of identical data
>     structures that
>     >     > differ only in address values. Currently, I pray that the device
>     file to
>     >     which
>     >     > I have callbacks mapped for the driver gets called sequentially,
>     because
>     >     there
>     >     > are pairs of mmap's that need to be made. I know that this isn't
>     the most
>     >     ideal
>     >     > way to do it, so I'm searching for a better way rather than to swap
>     out
>     >     the
>     >     > values on each method call. 
>     >     >
>     >     > There are several things I am aware of but for each one I have
>     questions:
>     >     > 1) there are kernel module parameters
>     >     > If I use kernel module parameters, I need to be able to insert the
>     kernel
>     >     > module three times in order to have each one have a distinct set of
>     >     global
>     >     > memory and mapped callbacks to distinct files. Can that be done?
>     Second,
>     >     I will
>     >     > need to compile the driver statically later. How can I pass those
>     >     parameters
>     >     > that would otherwise be on the command line in statically?
>     >
>     >     Never use kernel module parameters for a driver, nor for any other
>     >     kernel module you create.  They are global and don't work for
>     >     device-specific issues.
>     >
>     >     > 2) I can compile the driver in three times with a compile time
>     flag. This
>     >     is
>     >     > the simplest and easiest, but it requires some buildroot and
>     makefile foo
>     >     that
>     >     > I think is a dirty hack.
>     >
>     >     It's also never accepted, don't do that.
>     >
>     >     > 3) I could have the init function create three separate files,
>     since it
>     >     is on
>     >     > init that I discover what my values are. But then I have to also
>     >     associate
>     >     > identical functions that reference global variables in the kernel
>     object.
>     >     > Duplicating the code would be worse that compiling the same code
>     three
>     >     times
>     >     > with a kernel parameter, even though that would help me solve my
>     distinct
>     >     > globals problem. So how could I parameterisze a char device with
>     data
>     >     specific
>     >     > to the instance?
>     >
>     >     open() gives you the hook to do so, please just do that.  There's a
>     >     whole kernel tree full of examples of how to do this, take a look at
>     >     existing code please.
>     >
>     >
>     > After I had the idea in the second email, I think that using the kernel
>     api to
>     > distinguish which char device a callback maps to in order to utilize the
>     > corresponding data is the best way.
>     >
>     > If I could do something along the lines of retrieving the file name, as
>     in a
>     > char *,
>
>     There is no such "thing" in the kernel (think of symlinks, or different
>     names for the same major:minor pair).
>
>     > from the file * that is passed in with the callback, or distinguish any
>     > one of these:
>     >
>     > static dev_t LSKSMM_dev;
>     > static struct cdev LSKSMM_cdev;
>     > static struct class *LSKSMM_class;
>     > static struct device *LSKSMM_device;
>
>     Those are all different things, none of them get passed into open().
>
>     I don't think you have thought this through very far, where is your
>     source code to take a look at it?
>
>     > which are also created on module init, it would really make things
>     convenient
>     > and easy. I'm currently digging around in the kernel headers, but I think
>     > probably somebody somewhere knows what I'm looking for. Some unique field
>     that
>     > I can retain on init that I can get back in my mmap/ioctl call to
>     recognize
>     > what data to use.
>
>     Again, it's all provided directly to you in your open() call, what's
>     wrong with that?
>
>
> Currently, my kernel driver is opened twice and mmap'd twice by each process.

Again, any pointers to your source code?

Can't release it. It looks a lot like this though:

https://github.com/claudioscordino/mmap_alloc/blob/master/mmap_alloc.c
 

> I have three processes, but I have to initialize them on startup with
> a startup script.

What does that have to do with the kernel code?

It forces the design of my kernel driver to have to take into consideration how to map associated private data with a particular call, so that a process's pair of mmap calls don't get what some other process should have gotten. 3 processes, 2 items per process that have to match. As in, A1 & A2 to process 1, B1 & B2 to process 2, ect. But since they're racy, A1 could end up going to the first caller; I can't just rotate through a buffer containing the private data items is what I'm saying.
 

> So they come up as daemons, racing, which is a problem. I know that on
> init I can create three entries in /dev/, distinguished by a number or
> something that makes the device unique.

The kernel creates the /dev/ entries, don't do it from userspace, if you
expect things to work properly.

I already have my driver creating the /dev entries correctly. I had mentioned the data types required in the process of doing that:
static dev_t LSKSMM_dev;
static struct cdev LSKSMM_cdev;
static struct class *LSKSMM_class;
static struct device *LSKSMM_device;

If any one of those has a field in it in common with what a file struct has, but that is distinct across files, then that would be perfect.
 

> When a mmap call hits is when I need to know what specific file that
> the mmap corresponds to.

Again, open() is giving you this, why do you keep saying it isn't?

And again, there are at least 3 different ways of determining this at
open() time (5 total I think, last time I looked), each way depends on
your driver structure and how your code needs to work, so I can't just
say "do it this way", sorry.

I know it by file pointer, but not by what I have in dev_t, cdev, class *, or device *. Or possibly it's in one of those but I just don't know where.
 

> I have to identify it associatively by name or by the identifiers that
> the kernel consumes for it's internal class and/or device entry.

Why?

Cannot mmap concurrently, will produce incorrect results.
 

> I don't know that I could do that with what I'm given in open, because
> while I'm sure that provides some information, it doesn't provide the
> the information when I need it.

All of the char drivers in the kernel kind of refute that excuse :)

I don't know that any char device has potentially 6 different data items it has to manage, split between what should be discrete processes. Again, suppose I recorded what I got in open, from inode (and not file pointer, since it for some reason must do it in open). Then how do I associate two otherwise identical calls in mmap without using file pointer to a particular private resource? I create the dev_t, cdev, class and device in my init. I need to associate them with a file pointer, I can't use an inode, unless I have to use an inode in the process of retaining some information in the file structure by pointer. Which will then later be used in mmap.

In any case, inode is contained in file pointer, so if I have everything I need there, then the same associating code would work in either open or mmap.
 

> I don't have anything in my open callback except a printk.

Then fix that!

It would be inappropriate to move all the code in my mmap callback that does most of the work into the open callback.
 
 

> My mmap does all the work, and has to distinguish the right private
> item to use with what device file.

Again, set that in your open() callback, that's what it is there for!

there is a whole kernel tree full of examples of how to do this, please
use them for insight.

Ok, so after digging some this is what I have come up with. Just to checkk - I should look up the inode by the file pointer, then the dev_t, against which I can associate with the dev_t that I create in the init. If those are equal, then I have a way to know what file is being used in the file system since I can retain the dev_t items after init. I can use that knowledge to look up my private data items. Clear?
 

thanks,

greg k-h

_______________________________________________
Kernelnewbies mailing list
Kernelnewbies@xxxxxxxxxxxxxxxxx
http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies

[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