Driver duplicate?

Kenneth Adam Miller kennethadammiller at gmail.com
Mon Mar 7 16:08:01 EST 2016


On Mon, Mar 7, 2016 at 3:53 PM, Greg KH <greg at kroah.com> 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 at kroah.com> 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 at kroah.com> 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
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.kernelnewbies.org/pipermail/kernelnewbies/attachments/20160307/cd7fa9dd/attachment-0001.html 


More information about the Kernelnewbies mailing list