Re: seq_file and exporting dynamically allocated data

From: Tigran Aivazian
Date: Mon Nov 17 2003 - 03:22:04 EST


On Mon, 17 Nov 2003 viro@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx wrote:
> > a) no "THIS_MODULE" style module refcounting, so I had to do manual
> > MOD_INC_USE_COUNT/MOD_DEC_USE_COUNT in ->open/release. I am aware of the
> > deficiencies of this approach, of course (it's been discussed too many
> > times in the last several years).
>
> You don't need to do that. Look, these ->open() and ->release()
> are not some new methods - they are ->open() and ->release() of your
> struct file. The fact that they happen to call functions from seq_file.c
> doesn't change anything - they are struct file methods, sitting in some
> instance of struct file_operations. And just as with any such instance,
> you have ->owner in struct file_operations. Which will be honoured by
> open(2) - just as with any other file.

Thank you. Yes, I have now changed my code to do what you suggest and
it works fine.

> > b) no way to reset the 'offset' to 0 when the ->next() detects that it is
> > back at the head of linked list, i.e. when it should return NULL. It's OK
>
> Let me get it straight - you want an infinite file, with no EOF anywhere
> and contents more or less repeating itself? _And_ you want a working
> lseek() on that?

I only need lseek to offset 0 and it does work when called from userspace
as lseek(fd, 0, SEEK_SET). But what I wanted is "auto-rewinding read()".
So, when the driver detects that we reached EOF (i.e. hit 'init_task' in
->next()) it should somehow cause the offset to be reset to 0 but return
the read(2) to user as normal. I didn't figure out how to do this. The
intuitive solution *ppos = 0 in ->next() didn't work.

On the other hand, some more thought suggests that even if such
"auto-rewinding read" existed, perhaps it wouldn't help after all.
Because, the user app is doing the following to get information about all
processes efficiently:

first_loop = 1

while(1) {

read as much as can fit in a page (i.e. single read(2) syscall)

if !first_loop and the first element of the page (it can only be
first) is 'swapper'
then
lseek(fd, 0, SEEK_SET);
break;
fi

if (first_loop)
first_loop = 0;
}

So, we read an extra page in vain on each iteration. But this is OK as
performance is not an issue (my module is already 26 times faster than a
highly optimized NT implementation).

Now, since there is no way to detect EOF, other than by reading an extra
page and discovering that it belongs to the next iteration, we have to do
the lseek(fd, 0, SEEK_SET) anyway.

So, the "auto-rewinding" read would only help the cases where application
doesn't need to differentiate between samples and is happy to just
continuously read chunks packed into pages one by one as fast as
possible. In this case it doesn't need to lseek to 0, so auto-rewinding on
kernel side would prevent it from slowing down.

Kind regards
Tigran


-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/