Embedded Linux development
 help / color / mirror / Atom feed
* Re: [ltt-dev] [PATCH] nfs: add support for splice writes
From: Masahiro Tamori @ 2009-04-02 12:42 UTC (permalink / raw)
  To: Suresh Jayaraman, Mathieu Desnoyers
  Cc: linux-nfs, ltt-dev, Trond.Myklebust, LKML, linux-embedded
In-Reply-To: <49D45E42.3050502@suse.de>

Hello Suresh and Mathieu,

2009/4/2 Suresh Jayaraman <sjayaraman@suse.de>:
> Mathieu Desnoyers wrote:
>> * Suresh Jayaraman (sjayaraman@suse.de) wrote:
>>> This patch attempts to add splice writes support. In essence, it just
>>> calls generic_file_splice_write() after doing a little sanity check.
>>> This would allow LTTng users that are using NFS to store trace data.
>>> There could be more applications that could be benefitted too.
>>>
>>> I have tested this using the Jens' test program and have found no
>>> real issues. The test program is inlined below:
>>>
>>
>> There is just a small checkpatch nit that I'll fix directly in place in
>> the LTTng tree.
>>
>> WARNING: %Ld/%Lu are not-standard C, use %lld/%llu
>> #93: FILE: fs/nfs/file.c:564:
>> +   dprintk("NFS splice_write(%s/%s, %lu@%Lu)\n",
>>
>> total: 0 errors, 1 warnings, 42 lines checked
>>
>
> Yes, I noticed it. There are quite a few places in nfs code where we
> happened to use that (that doesn't imply that it shouldn't be fixed), so
> I thought it's OK.
>
>> That's great ! I'll pull it in the LTTng tree so my users can try it.
>> They currently cannot write LTTng traces to NFS mounts anyway.
>
> Yes, please report the test results. Would appreciate it very much.
>
>
> Thanks,

Thank you for creating a patch !!

I tested it, and it works fine.

My environment is following,
LTTV 0.12.10
LTTng 0.100
LTT Control 0.65
Kernles 2.6.29

LTTng version is old now, but the test is passed on ARM11 target.

Furthermore, I run the splice test and the test is passed too.
The test code is copied from
http://kzk9.net/blog/2007/05/splice2.html
(Japanese page)

Thanks all people who commented this issue.

Best regards,
Masahiro Tamori

>
>>>
>>> diff --git a/fs/nfs/file.c b/fs/nfs/file.c
>>> index 90f292b..13d6a00 100644
>>> --- a/fs/nfs/file.c
>>> +++ b/fs/nfs/file.c
>>> @@ -47,6 +47,9 @@ static ssize_t nfs_file_splice_read(struct file *filp, loff_t *ppos,
>>>                   size_t count, unsigned int flags);
>>> static ssize_t nfs_file_read(struct kiocb *, const struct iovec *iov,
>>>               unsigned long nr_segs, loff_t pos);
>>> +static ssize_t nfs_file_splice_write(struct pipe_inode_info *pipe,
>>> +                  struct file *filp, loff_t *ppos,
>>> +                  size_t count, unsigned int flags);
>>> static ssize_t nfs_file_write(struct kiocb *, const struct iovec *iov,
>>>               unsigned long nr_segs, loff_t pos);
>>> static int nfs_file_flush(struct file *, fl_owner_t id);
>>> @@ -76,6 +79,7 @@ const struct file_operations nfs_file_operations = {
>>>   .lock      = nfs_lock,
>>>   .flock     = nfs_flock,
>>>   .splice_read  = nfs_file_splice_read,
>>> +  .splice_write  = nfs_file_splice_write,
>>>   .check_flags  = nfs_check_flags,
>>>   .setlease    = nfs_setlease,
>>> };
>>> @@ -550,6 +554,26 @@ out_swapfile:
>>>   goto out;
>>> }
>>>
>>> +static ssize_t nfs_file_splice_write(struct pipe_inode_info *pipe,
>>> +                 struct file *filp, loff_t *ppos,
>>> +                 size_t count, unsigned int flags)
>>> +{
>>> +  struct dentry *dentry = filp->f_path.dentry;
>>> +  struct inode *inode = dentry->d_inode;
>>> +
>>> +  dprintk("NFS splice_write(%s/%s, %lu@%Lu)\n",
>>> +      dentry->d_parent->d_name.name, dentry->d_name.name,
>>> +      (unsigned long) count, (unsigned long long) *ppos);
>>> +
>>> +  if (IS_SWAPFILE(inode)) {
>>> +      printk(KERN_INFO "NFS: attempt to write to active swap"
>>> +          "file!\n");
>>> +      return -EBUSY;
>>> +  }
>>> +
>>> +  return generic_file_splice_write(pipe, filp, ppos, count, flags);
>>> +}
>>> +
>>> static int do_getlk(struct file *filp, int cmd, struct file_lock *fl)
>>> {
>>>   struct inode *inode = filp->f_mapping->host;
>>>
>>
>
>
> --
> Suresh Jayaraman
>
> _______________________________________________
> ltt-dev mailing list
> ltt-dev@lists.casi.polymtl.ca
> http://lists.casi.polymtl.ca/cgi-bin/mailman/listinfo/ltt-dev
>

^ permalink raw reply

* Re: Sources of entropy?
From: Mike Frysinger @ 2009-04-02 12:03 UTC (permalink / raw)
  To: Nicholas Mc Guire; +Cc: Robin Getz, linux-embedded
In-Reply-To: <20090402114553.GA7568@opentech.at>

On Thu, Apr 2, 2009 at 07:45, Nicholas Mc Guire wrote:
> On Tue, 24 Mar 2009, Robin Getz wrote:
>> I'm just wondering what people using on standard embedded/headless/diskless
>> targets (which do not have hw random number generators) as a source of
>> entropy - since networking was removed as an entropy source circa 2.6.26
>
> without claiming that this is actually usable at this point but a simple
> source of entropy that looks quite good is simply to use the timer-counter/TSC
> or what ever available. The attached trng.c has been tested on a few X86
> systems and produces remarkably good random numbers - this might be suitable
> if you have no other sources available.

unfortunately on Blackfin parts, the TSC (we call it "CYCLES" as that
is the actual register name) is writable from userspace

i have used this in the bootloader as a simple way of getting a little
bit of entropy, but then i found that our system is too reliable in
booting -- it tends to take the exact same amount of time to boot to a
prompt
-mike

^ permalink raw reply

* Re: Sources of entropy?
From: Nicholas Mc Guire @ 2009-04-02 11:45 UTC (permalink / raw)
  To: Robin Getz; +Cc: linux-embedded
In-Reply-To: <200903241847.29104.rgetz@blackfin.uclinux.org>

On Tue, 24 Mar 2009, Robin Getz wrote:

> I'm just wondering what people using on standard embedded/headless/diskless 
> targets (which do not have hw random number generators) as a source of 
> entropy - since networking was removed as an entropy source circa 2.6.26
>
without claiming that this is actually usable at this point but a simple
source of entropy that looks quite good is simply to use the timer-counter/TSC
or what ever available. The attached trng.c has been tested on a few X86
systems and produces remarkably good random numbers - this might be suitable
if you have no other sources available.

The actual source of randomness simply is that sampling the LSB of what ever
timer source is available is of lower granularity than the system jitter 
(scheduling jitter actually) - so this should be quite generally applicable.
In fact on some of the tested X86 system the randomness was good up to the
10 or 11th bit of the TSC.

 
/* naive true random number generator in software - this seems to be doing
 * better than /dev/random on most linux boxes ;)
 *
 * Copyright OpenTech EDV Research GmbH 2009
 * Author Der Herr Hofrat, <der.herr@hofr.at>
 * License GPL V2 - see http://www.gnu.org/copyleft/gpl.html for more
 *
 * cmpile: gcc -O2 trng.c -o trng
 * usage: ./trng > rand_data
 *
 * what is this doing ?
 * Simply take the non-determinism of intel architectures at the instruction
 * level and sample the TSCs LSB - bit shift it into an array and through
 * most of it away again (this could be optimized - but thats not essential
 * here) - the output is by all standards truly random 
 *
 * first "test"
 *
 * aetsch:~# ./trng > 1
 * ls -aetsch:~# ls -l 1
 * -rw-r--r-- 1 root root 8192 2008-10-19 14:03 1
 * aetsch:~# bzip2 1
 * aetsch:~# ls -l 1.bz2
 * -rw-r--r-- 1 root root 8679 2008-10-19 14:03 1.bz2
 *
 * indicate very good randomness as bzip is not able to compress anything!
 */

#include <stdio.h>

/* read the tsc snip of the LSB and shift it into a long long
 * usleep(something) to ensure that the CPU is sufficiently randomized
 * so we have NO deterministic (periodic) and thus non-random access
 */
__inline__ unsigned long long int sample_tsc(void)
{
	unsigned long long int x,res;
	int i;
	res=0;
	for(i=0;i<32;i++){
		__asm__ __volatile__("rdtsc\n\t":"=A" (x));
		res|=((x&0x01LL)<<i);
		usleep(10);
	}
	return res;
}

int main(int argc, char **argv)
{
	unsigned int n;

	n=0;
	/* simply dump the bit patters to stdout */
	while(n++ < 8192){
		printf("%c",(sample_tsc()&0x00FFLL));
	}
	return 0;
}

^ permalink raw reply

* root on Squashfs breaks mknod
From: Markus Brunner @ 2009-04-02 11:40 UTC (permalink / raw)
  To: squashfs-devel; +Cc: linux-embedded

Hi,

I have a problem if I use squashfs as root filesystem. The error occurs at 
least with linux 2.6.11/2.6.29 and squashfs 3.4/4.0 on x86.

I use an initramfs where I mount the squashfs and use run-init from klibc to 
make my squashfs the new root device. I can also copy the devices to a tmpfs 
and bind it to /dev. But after I have left the initramfs newly created 
devices don't work anymore. It doesn't matter if they get created with mknod, 
or copied with "cp -a" from /dev. The devices in /dev still work, regardless 
if they are directly on the squashfs, or on a tmpfs.

The created devices have the same Major/Minor numbers and are special files. 
It is also possible to put the devices in an archive and restore them after 
reboot. But they only work if mknod still works.

Here is the output of strace, reading from the working /dev/zero to the 
broken /tmp/null.

# strace -fff dd if=/dev/zero of=/tmp/null count=1
execve("/bin/dd", ["dd", "if=/dev/zero", "of=/tmp/null", "count=1"], [/* 
16 vars */]) = 0
ioctl(0, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon echo 
...}) = 0
ioctl(1, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon echo 
...}) = 0
getuid()                                = 0
brk(0)                                  = 0x80e6000
brk(0x80e7000)                          = 0x80e7000
open("/dev/zero", O_RDONLY|O_LARGEFILE) = 4
dup2(4, 0)                              = 0
close(4)                                = 0
open("/tmp/null", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 027741600666) = -1 
ENXIO (No such device or address)
brk(0x80e8000)                          = 0x80e8000
ioctl(2147483647, SNDCTL_TMR_TIMEBASE or TCGETS, 0xbf870224) = -1 EBADF 
(Bad file descriptor)
brk(0x80e9000)                          = 0x80e9000
write(2, "dd: can\'t open \'/tmp/null\': No s"..., 54dd: can't open 
'/tmp/null': No such device or address
) = 54
_exit(1)



Any ideas where this bug might came from?

Best Regards

Markus

^ permalink raw reply

* Re: [PATCH] nfs: add support for splice writes
From: Suresh Jayaraman @ 2009-04-02  6:42 UTC (permalink / raw)
  To: Mathieu Desnoyers
  Cc: Trond.Myklebust-HgOvQuBEEgTQT0dZR+AlfA,
	linux-nfs-u79uwXL29TY76Z2rM5mHXA,
	linux-embedded-u79uwXL29TY76Z2rM5mHXA, LKML,
	ltt-dev-33AaDErTWvBVxDZ2/Zk0YoryAYyacSEB
In-Reply-To: <20090402063235.GB24846@Krystal>

Mathieu Desnoyers wrote:
> * Suresh Jayaraman (sjayaraman-l3A5Bk7waGM@public.gmane.org) wrote:
>> This patch attempts to add splice writes support. In essence, it just
>> calls generic_file_splice_write() after doing a little sanity check.
>> This would allow LTTng users that are using NFS to store trace data.
>> There could be more applications that could be benefitted too.
>>
>> I have tested this using the Jens' test program and have found no
>> real issues. The test program is inlined below:
>>
> 
> There is just a small checkpatch nit that I'll fix directly in place in
> the LTTng tree.
> 
> WARNING: %Ld/%Lu are not-standard C, use %lld/%llu
> #93: FILE: fs/nfs/file.c:564:
> +	dprintk("NFS splice_write(%s/%s, %lu@%Lu)\n",
> 
> total: 0 errors, 1 warnings, 42 lines checked
> 

Yes, I noticed it. There are quite a few places in nfs code where we
happened to use that (that doesn't imply that it shouldn't be fixed), so
I thought it's OK.

> That's great ! I'll pull it in the LTTng tree so my users can try it.
> They currently cannot write LTTng traces to NFS mounts anyway.

Yes, please report the test results. Would appreciate it very much.


Thanks,

>>
>> diff --git a/fs/nfs/file.c b/fs/nfs/file.c
>> index 90f292b..13d6a00 100644
>> --- a/fs/nfs/file.c
>> +++ b/fs/nfs/file.c
>> @@ -47,6 +47,9 @@ static ssize_t nfs_file_splice_read(struct file *filp, loff_t *ppos,
>>  					size_t count, unsigned int flags);
>>  static ssize_t nfs_file_read(struct kiocb *, const struct iovec *iov,
>>  				unsigned long nr_segs, loff_t pos);
>> +static ssize_t nfs_file_splice_write(struct pipe_inode_info *pipe,
>> +					struct file *filp, loff_t *ppos,
>> +					size_t count, unsigned int flags);
>>  static ssize_t nfs_file_write(struct kiocb *, const struct iovec *iov,
>>  				unsigned long nr_segs, loff_t pos);
>>  static int  nfs_file_flush(struct file *, fl_owner_t id);
>> @@ -76,6 +79,7 @@ const struct file_operations nfs_file_operations = {
>>  	.lock		= nfs_lock,
>>  	.flock		= nfs_flock,
>>  	.splice_read	= nfs_file_splice_read,
>> +	.splice_write	= nfs_file_splice_write,
>>  	.check_flags	= nfs_check_flags,
>>  	.setlease	= nfs_setlease,
>>  };
>> @@ -550,6 +554,26 @@ out_swapfile:
>>  	goto out;
>>  }
>>  
>> +static ssize_t nfs_file_splice_write(struct pipe_inode_info *pipe,
>> +				     struct file *filp, loff_t *ppos,
>> +				     size_t count, unsigned int flags)
>> +{
>> +	struct dentry *dentry = filp->f_path.dentry;
>> +	struct inode *inode = dentry->d_inode;
>> +
>> +	dprintk("NFS splice_write(%s/%s, %lu@%Lu)\n",
>> +		dentry->d_parent->d_name.name, dentry->d_name.name,
>> +		(unsigned long) count, (unsigned long long) *ppos);
>> +
>> +	if (IS_SWAPFILE(inode)) {
>> +		printk(KERN_INFO "NFS: attempt to write to active swap"
>> +		       "file!\n");
>> +		return -EBUSY;
>> +	}
>> +
>> +	return generic_file_splice_write(pipe, filp, ppos, count, flags);
>> +}
>> +
>>  static int do_getlk(struct file *filp, int cmd, struct file_lock *fl)
>>  {
>>  	struct inode *inode = filp->f_mapping->host;
>>
> 


-- 
Suresh Jayaraman
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH] nfs: add support for splice writes
From: Mathieu Desnoyers @ 2009-04-02  6:32 UTC (permalink / raw)
  To: Suresh Jayaraman
  Cc: Trond.Myklebust-HgOvQuBEEgTQT0dZR+AlfA,
	linux-nfs-u79uwXL29TY76Z2rM5mHXA,
	linux-embedded-u79uwXL29TY76Z2rM5mHXA, LKML,
	ltt-dev-33AaDErTWvBVxDZ2/Zk0YoryAYyacSEB
In-Reply-To: <49D45974.2060202-l3A5Bk7waGM@public.gmane.org>

* Suresh Jayaraman (sjayaraman-l3A5Bk7waGM@public.gmane.org) wrote:
> This patch attempts to add splice writes support. In essence, it just
> calls generic_file_splice_write() after doing a little sanity check.
> This would allow LTTng users that are using NFS to store trace data.
> There could be more applications that could be benefitted too.
> 
> I have tested this using the Jens' test program and have found no
> real issues. The test program is inlined below:
> 

There is just a small checkpatch nit that I'll fix directly in place in
the LTTng tree.

WARNING: %Ld/%Lu are not-standard C, use %lld/%llu
#93: FILE: fs/nfs/file.c:564:
+	dprintk("NFS splice_write(%s/%s, %lu@%Lu)\n",

total: 0 errors, 1 warnings, 42 lines checked

Mathieu

> /*
>  * splice-out.c: Splice stdout to file
>  */
> #include <stdio.h>
> #include <stdlib.h>
> #include <unistd.h>
> #include <fcntl.h>
> 
> #define SPLICE_SIZE (64*1024)
> 
> int main(int argc, char *argv[])
> {
>         int fd;
> 
>         if (argc < 2) {
>                 printf("%s: outfile\n", argv[0]);
>                 return 1;
>         }
> 
>         fd = open(argv[1], O_WRONLY | O_CREAT | O_TRUNC, 0644);
>         if (fd < 0) {
>                 perror("open");
>                 return 1;
>         }
> 
>         do {
>                 int ret = splice(STDIN_FILENO, NULL, fd, NULL, SPLICE_SIZE, 0);
> 
>                 if (ret < 0) {
>                         perror("splice");
>                         break;
>                 } else if (ret < SPLICE_SIZE)
>                         break;
>         } while (1);
> 
>         close(fd);
>         return 0;
> }
> 
> Compile with -D _GNU_SOURCE and do something like:
> 	echo "some stuff" | ./splice-out <outfile>
> 
> Signed-off-by: Suresh Jayaraman <sjayaraman-l3A5Bk7waGM@public.gmane.org>
> ---
>  fs/nfs/file.c |   24 ++++++++++++++++++++++++
>  1 files changed, 24 insertions(+), 0 deletions(-)
> 
> diff --git a/fs/nfs/file.c b/fs/nfs/file.c
> index 90f292b..13d6a00 100644
> --- a/fs/nfs/file.c
> +++ b/fs/nfs/file.c
> @@ -47,6 +47,9 @@ static ssize_t nfs_file_splice_read(struct file *filp, loff_t *ppos,
>  					size_t count, unsigned int flags);
>  static ssize_t nfs_file_read(struct kiocb *, const struct iovec *iov,
>  				unsigned long nr_segs, loff_t pos);
> +static ssize_t nfs_file_splice_write(struct pipe_inode_info *pipe,
> +					struct file *filp, loff_t *ppos,
> +					size_t count, unsigned int flags);
>  static ssize_t nfs_file_write(struct kiocb *, const struct iovec *iov,
>  				unsigned long nr_segs, loff_t pos);
>  static int  nfs_file_flush(struct file *, fl_owner_t id);
> @@ -76,6 +79,7 @@ const struct file_operations nfs_file_operations = {
>  	.lock		= nfs_lock,
>  	.flock		= nfs_flock,
>  	.splice_read	= nfs_file_splice_read,
> +	.splice_write	= nfs_file_splice_write,
>  	.check_flags	= nfs_check_flags,
>  	.setlease	= nfs_setlease,
>  };
> @@ -550,6 +554,26 @@ out_swapfile:
>  	goto out;
>  }
>  
> +static ssize_t nfs_file_splice_write(struct pipe_inode_info *pipe,
> +				     struct file *filp, loff_t *ppos,
> +				     size_t count, unsigned int flags)
> +{
> +	struct dentry *dentry = filp->f_path.dentry;
> +	struct inode *inode = dentry->d_inode;
> +
> +	dprintk("NFS splice_write(%s/%s, %lu@%Lu)\n",
> +		dentry->d_parent->d_name.name, dentry->d_name.name,
> +		(unsigned long) count, (unsigned long long) *ppos);
> +
> +	if (IS_SWAPFILE(inode)) {
> +		printk(KERN_INFO "NFS: attempt to write to active swap"
> +		       "file!\n");
> +		return -EBUSY;
> +	}
> +
> +	return generic_file_splice_write(pipe, filp, ppos, count, flags);
> +}
> +
>  static int do_getlk(struct file *filp, int cmd, struct file_lock *fl)
>  {
>  	struct inode *inode = filp->f_mapping->host;
> 

-- 
Mathieu Desnoyers
OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F  BA06 3F25 A8FE 3BAE 9A68
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH] nfs: add support for splice writes
From: Mathieu Desnoyers @ 2009-04-02  6:29 UTC (permalink / raw)
  To: Suresh Jayaraman
  Cc: Trond.Myklebust-HgOvQuBEEgTQT0dZR+AlfA,
	linux-nfs-u79uwXL29TY76Z2rM5mHXA,
	linux-embedded-u79uwXL29TY76Z2rM5mHXA, LKML,
	ltt-dev-33AaDErTWvBVxDZ2/Zk0YoryAYyacSEB
In-Reply-To: <49D45974.2060202-l3A5Bk7waGM@public.gmane.org>

* Suresh Jayaraman (sjayaraman-l3A5Bk7waGM@public.gmane.org) wrote:
> This patch attempts to add splice writes support. In essence, it just
> calls generic_file_splice_write() after doing a little sanity check.
> This would allow LTTng users that are using NFS to store trace data.
> There could be more applications that could be benefitted too.
> 
> I have tested this using the Jens' test program and have found no
> real issues. The test program is inlined below:
> 

That's great ! I'll pull it in the LTTng tree so my users can try it.
They currently cannot write LTTng traces to NFS mounts anyway.

Thanks !

Mathieu

> /*
>  * splice-out.c: Splice stdout to file
>  */
> #include <stdio.h>
> #include <stdlib.h>
> #include <unistd.h>
> #include <fcntl.h>
> 
> #define SPLICE_SIZE (64*1024)
> 
> int main(int argc, char *argv[])
> {
>         int fd;
> 
>         if (argc < 2) {
>                 printf("%s: outfile\n", argv[0]);
>                 return 1;
>         }
> 
>         fd = open(argv[1], O_WRONLY | O_CREAT | O_TRUNC, 0644);
>         if (fd < 0) {
>                 perror("open");
>                 return 1;
>         }
> 
>         do {
>                 int ret = splice(STDIN_FILENO, NULL, fd, NULL, SPLICE_SIZE, 0);
> 
>                 if (ret < 0) {
>                         perror("splice");
>                         break;
>                 } else if (ret < SPLICE_SIZE)
>                         break;
>         } while (1);
> 
>         close(fd);
>         return 0;
> }
> 
> Compile with -D _GNU_SOURCE and do something like:
> 	echo "some stuff" | ./splice-out <outfile>
> 
> Signed-off-by: Suresh Jayaraman <sjayaraman-l3A5Bk7waGM@public.gmane.org>
> ---
>  fs/nfs/file.c |   24 ++++++++++++++++++++++++
>  1 files changed, 24 insertions(+), 0 deletions(-)
> 
> diff --git a/fs/nfs/file.c b/fs/nfs/file.c
> index 90f292b..13d6a00 100644
> --- a/fs/nfs/file.c
> +++ b/fs/nfs/file.c
> @@ -47,6 +47,9 @@ static ssize_t nfs_file_splice_read(struct file *filp, loff_t *ppos,
>  					size_t count, unsigned int flags);
>  static ssize_t nfs_file_read(struct kiocb *, const struct iovec *iov,
>  				unsigned long nr_segs, loff_t pos);
> +static ssize_t nfs_file_splice_write(struct pipe_inode_info *pipe,
> +					struct file *filp, loff_t *ppos,
> +					size_t count, unsigned int flags);
>  static ssize_t nfs_file_write(struct kiocb *, const struct iovec *iov,
>  				unsigned long nr_segs, loff_t pos);
>  static int  nfs_file_flush(struct file *, fl_owner_t id);
> @@ -76,6 +79,7 @@ const struct file_operations nfs_file_operations = {
>  	.lock		= nfs_lock,
>  	.flock		= nfs_flock,
>  	.splice_read	= nfs_file_splice_read,
> +	.splice_write	= nfs_file_splice_write,
>  	.check_flags	= nfs_check_flags,
>  	.setlease	= nfs_setlease,
>  };
> @@ -550,6 +554,26 @@ out_swapfile:
>  	goto out;
>  }
>  
> +static ssize_t nfs_file_splice_write(struct pipe_inode_info *pipe,
> +				     struct file *filp, loff_t *ppos,
> +				     size_t count, unsigned int flags)
> +{
> +	struct dentry *dentry = filp->f_path.dentry;
> +	struct inode *inode = dentry->d_inode;
> +
> +	dprintk("NFS splice_write(%s/%s, %lu@%Lu)\n",
> +		dentry->d_parent->d_name.name, dentry->d_name.name,
> +		(unsigned long) count, (unsigned long long) *ppos);
> +
> +	if (IS_SWAPFILE(inode)) {
> +		printk(KERN_INFO "NFS: attempt to write to active swap"
> +		       "file!\n");
> +		return -EBUSY;
> +	}
> +
> +	return generic_file_splice_write(pipe, filp, ppos, count, flags);
> +}
> +
>  static int do_getlk(struct file *filp, int cmd, struct file_lock *fl)
>  {
>  	struct inode *inode = filp->f_mapping->host;
> 

-- 
Mathieu Desnoyers
OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F  BA06 3F25 A8FE 3BAE 9A68
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* [PATCH] nfs: add support for splice writes
From: Suresh Jayaraman @ 2009-04-02  6:21 UTC (permalink / raw)
  To: Trond.Myklebust-HgOvQuBEEgTQT0dZR+AlfA
  Cc: linux-nfs-u79uwXL29TY76Z2rM5mHXA,
	mathieu.desnoyers-scC8bbJcJLCw5LPnMra/2Q,
	linux-embedded-u79uwXL29TY76Z2rM5mHXA,
	compudj-vdFpqfd5riKZ9vWoFJJngh2eb7JE58TQ, LKML,
	ltt-dev-33AaDErTWvBVxDZ2/Zk0YoryAYyacSEB

This patch attempts to add splice writes support. In essence, it just
calls generic_file_splice_write() after doing a little sanity check.
This would allow LTTng users that are using NFS to store trace data.
There could be more applications that could be benefitted too.

I have tested this using the Jens' test program and have found no
real issues. The test program is inlined below:

/*
 * splice-out.c: Splice stdout to file
 */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>

#define SPLICE_SIZE (64*1024)

int main(int argc, char *argv[])
{
        int fd;

        if (argc < 2) {
                printf("%s: outfile\n", argv[0]);
                return 1;
        }

        fd = open(argv[1], O_WRONLY | O_CREAT | O_TRUNC, 0644);
        if (fd < 0) {
                perror("open");
                return 1;
        }

        do {
                int ret = splice(STDIN_FILENO, NULL, fd, NULL, SPLICE_SIZE, 0);

                if (ret < 0) {
                        perror("splice");
                        break;
                } else if (ret < SPLICE_SIZE)
                        break;
        } while (1);

        close(fd);
        return 0;
}

Compile with -D _GNU_SOURCE and do something like:
	echo "some stuff" | ./splice-out <outfile>

Signed-off-by: Suresh Jayaraman <sjayaraman-l3A5Bk7waGM@public.gmane.org>
---
 fs/nfs/file.c |   24 ++++++++++++++++++++++++
 1 files changed, 24 insertions(+), 0 deletions(-)

diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index 90f292b..13d6a00 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -47,6 +47,9 @@ static ssize_t nfs_file_splice_read(struct file *filp, loff_t *ppos,
 					size_t count, unsigned int flags);
 static ssize_t nfs_file_read(struct kiocb *, const struct iovec *iov,
 				unsigned long nr_segs, loff_t pos);
+static ssize_t nfs_file_splice_write(struct pipe_inode_info *pipe,
+					struct file *filp, loff_t *ppos,
+					size_t count, unsigned int flags);
 static ssize_t nfs_file_write(struct kiocb *, const struct iovec *iov,
 				unsigned long nr_segs, loff_t pos);
 static int  nfs_file_flush(struct file *, fl_owner_t id);
@@ -76,6 +79,7 @@ const struct file_operations nfs_file_operations = {
 	.lock		= nfs_lock,
 	.flock		= nfs_flock,
 	.splice_read	= nfs_file_splice_read,
+	.splice_write	= nfs_file_splice_write,
 	.check_flags	= nfs_check_flags,
 	.setlease	= nfs_setlease,
 };
@@ -550,6 +554,26 @@ out_swapfile:
 	goto out;
 }
 
+static ssize_t nfs_file_splice_write(struct pipe_inode_info *pipe,
+				     struct file *filp, loff_t *ppos,
+				     size_t count, unsigned int flags)
+{
+	struct dentry *dentry = filp->f_path.dentry;
+	struct inode *inode = dentry->d_inode;
+
+	dprintk("NFS splice_write(%s/%s, %lu@%Lu)\n",
+		dentry->d_parent->d_name.name, dentry->d_name.name,
+		(unsigned long) count, (unsigned long long) *ppos);
+
+	if (IS_SWAPFILE(inode)) {
+		printk(KERN_INFO "NFS: attempt to write to active swap"
+		       "file!\n");
+		return -EBUSY;
+	}
+
+	return generic_file_splice_write(pipe, filp, ppos, count, flags);
+}
+
 static int do_getlk(struct file *filp, int cmd, struct file_lock *fl)
 {
 	struct inode *inode = filp->f_mapping->host;

--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related

* Re: USB console and network devices unsupported for boot
From: VomLehn @ 2009-03-27 19:55 UTC (permalink / raw)
  To: Tim Bird; +Cc: Linux Embedded Mailing List, Tony Colclough, Andrew Morton
In-Reply-To: <49CD2508.10706@am.sony.com>

On Fri, Mar 27, 2009 at 12:12:08PM -0700, Tim Bird wrote:
> VomLehn wrote:
> > My question: are USB serial consoles and auto-configured network devices in
> > common use or is my application a special case? If the former, we need to push
> > for a better resolution. Otherwise, I'll go off and figure out something that
> > works for my application.
> 
> I'd say that they're not uncommon during development, but I
> (personally) don't know of any shipped products with either of
> these.

Good point. This is definitely a question about development phase use of USB.
--
David VomLehn

^ permalink raw reply

* Re: USB console and network devices unsupported for boot
From: Tim Bird @ 2009-03-27 19:12 UTC (permalink / raw)
  To: VomLehn; +Cc: Linux Embedded Mailing List, Tony Colclough, Andrew Morton
In-Reply-To: <20090327182758.GA10454@cuplxvomd02.corp.sa.net>

VomLehn wrote:
> My question: are USB serial consoles and auto-configured network devices in
> common use or is my application a special case? If the former, we need to push
> for a better resolution. Otherwise, I'll go off and figure out something that
> works for my application.

I'd say that they're not uncommon during development, but I
(personally) don't know of any shipped products with either of
these.
 -- Tim

=============================
Tim Bird
Architecture Group Chair, CE Linux Forum
Senior Staff Engineer, Sony Corporation of America
=============================

^ permalink raw reply

* USB console and network devices unsupported for boot
From: VomLehn @ 2009-03-27 18:27 UTC (permalink / raw)
  To: Linux Embedded Mailing List; +Cc: Tony Colclough, Andrew Morton

I've been tracking down a problem with kernels 2.6.28 and 2.6.29 and it looks
like there is a race condition with using USB boot devices. Specifically:

o	The console specified with console=ttyUSB0 does not work
o	Using ip=169.254.0.21::169.254.0.21:255.255.0.0:zeus:eth0: does not
	configure eth0.

Both of these issues arise because the required USB devices aren't ready
when the rest of the kernel wants to initialize them and there is no way
to make the initialization wait for the devices. I opened a bug for this
and you can see the discussion of this issue, with alternative approaches, at:

	http://bugzilla.kernel.org/show_bug.cgi?id=12944

but the bottom line is that this is not regarded as a bug.

My question: are USB serial consoles and auto-configured network devices in
common use or is my application a special case? If the former, we need to push
for a better resolution. Otherwise, I'll go off and figure out something that
works for my application.
--
David VomLehn

^ permalink raw reply

* Re: XZ (LZMA2) decoder
From: Geert Uytterhoeven @ 2009-03-26 15:36 UTC (permalink / raw)
  To: Lasse Collin; +Cc: Leon Woestenberg, linux-embedded
In-Reply-To: <200903261534.41887.lasse.collin@tukaani.org>

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: TEXT/PLAIN; charset="ks_c_5601-1987", Size: 2072 bytes --]

On Thu, 26 Mar 2009, Lasse Collin wrote:
> On 2009-03-25 Leon Woestenberg wrote:
> > Is this something the linux-embedded community must pick up, or maybe
> > even the LKML?
> 
> In December, there was some discussion on linux-embedded about getting 
> LZMA decoder into Linux. I understood that some of the existing patches 
> had trouble meeting the kernel quality standards. There were also 
> requirements like support for multi-call decoding, which should be 
> useful at least in Squashfs. I promised to write a nice-looking .xz file 
> format decoder for Linux (.xz will replace the .lzma format) and post to 
> linux-embedded when I have something to show.

Yes, this is interesting work!

> Assuming there still is interest like there was in December, hope I will 
> get some feedback to know if my code looks promising and possibly how it 
> should be improved to be good for in-kernel use. This is my first Linux 
> kernel related coding project, so there probably are things (other than 
> plain bugs) that need to be fixed before the code can be considered for 
> inclusion.

I gave it a quick test on ppc64, and the kernel part built fine with sparse
checking enabled (make C=1), without any warnings.

> If linux-embedded is not the best list for this, I can post to LKML too. 
> However, since I promised to post at least to linux-embedded, and the 
> discussion on this list in December was very helpful for me to 
> understand what is required from an in-kernel decompressor, starting a 
> new discussion first on linux-embedded sounded obvious to me.

Ccing lkml wouldn't hurt, I think.

With kind regards,

Geert Uytterhoeven
Software Architect

Sony Techsoft Centre Europe
The Corporate Village · Da Vincilaan 7-D1 · B-1935 Zaventem · Belgium

Phone:    +32 (0)2 700 8453
Fax:      +32 (0)2 700 8622
E-mail:   Geert.Uytterhoeven@sonycom.com
Internet: http://www.sony-europe.com/

A division of Sony Europe (Belgium) N.V.
VAT BE 0413.825.160 · RPR Brussels
Fortis · BIC GEBABEBB · IBAN BE41293037680010

^ permalink raw reply

* Re: XZ (LZMA2) decoder
From: Lasse Collin @ 2009-03-26 13:34 UTC (permalink / raw)
  To: Leon Woestenberg; +Cc: linux-embedded
In-Reply-To: <c384c5ea0903251439k2ba46bffq729c013a48e2d6b9@mail.gmail.com>

On 2009-03-25 Leon Woestenberg wrote:
> Is this something the linux-embedded community must pick up, or maybe
> even the LKML?

In December, there was some discussion on linux-embedded about getting 
LZMA decoder into Linux. I understood that some of the existing patches 
had trouble meeting the kernel quality standards. There were also 
requirements like support for multi-call decoding, which should be 
useful at least in Squashfs. I promised to write a nice-looking .xz file 
format decoder for Linux (.xz will replace the .lzma format) and post to 
linux-embedded when I have something to show.

Assuming there still is interest like there was in December, hope I will 
get some feedback to know if my code looks promising and possibly how it 
should be improved to be good for in-kernel use. This is my first Linux 
kernel related coding project, so there probably are things (other than 
plain bugs) that need to be fixed before the code can be considered for 
inclusion.

If linux-embedded is not the best list for this, I can post to LKML too. 
However, since I promised to post at least to linux-embedded, and the 
discussion on this list in December was very helpful for me to 
understand what is required from an in-kernel decompressor, starting a 
new discussion first on linux-embedded sounded obvious to me.

Stable userspace tools to handle .xz files are still not available. I 
simply haven't worked on them much in the past two months. I naturally 
hope to get the stable release out soon, but my ability work on these 
projects depends on a couple of other things in my life, so it's better 
I don't promise anything detailed. On the positive side, the latest XZ 
Utils beta should be quite good already.

-- 
Lasse Collin  |  IRC: Larhzu @ IRCnet & Freenode

^ permalink raw reply

* Re: Sources of entropy?
From: Jamie Lokier @ 2009-03-26 13:25 UTC (permalink / raw)
  To: Robin Getz; +Cc: linux-embedded
In-Reply-To: <200903241847.29104.rgetz@blackfin.uclinux.org>

Robin Getz wrote:
> I'm just wondering what people using on standard embedded/headless/diskless 
> targets (which do not have hw random number generators) as a source of 
> entropy - since networking was removed as an entropy source circa 2.6.26

You might not have much real entropy to use.  I guess networking was
removed because it's an obvious attack vector.

On my devices, I save the entropy pool to flash on shutdown and merge
it back on reboot.  This lets cumulative history build.
    
    [shutdown]
    dd if=/dev/urandom of=$ENTROPY_STORE.new bs=512 count=1 2>/dev/null \
       && mv $ENTROPY_STORE.new $ENTROPY_STORE \
       || rm -f $ENTROPY_STORE.new

    [boot]
    dd if=$ENTROPY_STORE of=/dev/random bs=512 2>/dev/null

You'll still drain the pool quickly so may need to use /dev/urandom
for everything (e.g. by linking /dev/random -> /dev/urandom), but
keeping history does mean you get more real entropy from /dev/urandom,
even though entropy_avail cannot estimate it (and the lower bound is
still zero, if what you did before has always been predictable).

> I have seen rngd, clrngd, audio_entropyd, & video_entroyd - but I was just 
> wondering what others were actually using. (I was cautioned that everything 
> was pretty CPU intensive, since they all have a FIPS testing to ensure 
> randomness)...

You can write anything you think is an entropy source to /dev/random,
and it won't increase the entropy estimate but it will increase real
entropy if your source has any.  So you could add low-order bits from
high-resolution timing data from your network application from time to
time, for example, if you think it's worth it.

That won't make /dev/random show confirmed non-zero entropy, but that
might not be feasible on your device anyway.

-- Jamie

^ permalink raw reply

* Re: XZ (LZMA2) decoder
From: Bernhard Reutner-Fischer @ 2009-03-25 21:41 UTC (permalink / raw)
  To: Leon Woestenberg; +Cc: Lasse Collin, linux-embedded
In-Reply-To: <c384c5ea0903251439k2ba46bffq729c013a48e2d6b9@mail.gmail.com>

On Wed, Mar 25, 2009 at 10:39:06PM +0100, Leon Woestenberg wrote:
>Hello Lasse,
>
>On Sun, Mar 22, 2009 at 2:57 PM, Lasse Collin <lasse.collin@tukaani.org> wrote:
>> (Please CC your replies to me, I'm not on the list.)
>>
>> An initial version of the .xz file format decoder for Linux is now
>> available at <git://ctrl.tukaani.org/xz-embedded.git>. It supports both
>> stateful and single-call decoding using the LZMA2 algorithm.
>>
>Is this something the linux-embedded community must pick up, or maybe
>even the LKML?

This is certainly the way to go, yes.

^ permalink raw reply

* Re: XZ (LZMA2) decoder
From: Leon Woestenberg @ 2009-03-25 21:39 UTC (permalink / raw)
  To: Lasse Collin; +Cc: linux-embedded
In-Reply-To: <200903221557.33588.lasse.collin@tukaani.org>

Hello Lasse,

On Sun, Mar 22, 2009 at 2:57 PM, Lasse Collin <lasse.collin@tukaani.org> wrote:
> (Please CC your replies to me, I'm not on the list.)
>
> An initial version of the .xz file format decoder for Linux is now
> available at <git://ctrl.tukaani.org/xz-embedded.git>. It supports both
> stateful and single-call decoding using the LZMA2 algorithm.
>
Is this something the linux-embedded community must pick up, or maybe
even the LKML?

Regards,
-- 
Leon

^ permalink raw reply

* Re: Sources of entropy?
From: David VomLehn @ 2009-03-25 17:06 UTC (permalink / raw)
  To: Robin Getz; +Cc: linux-embedded
In-Reply-To: <200903241847.29104.rgetz@blackfin.uclinux.org>

Robin Getz wrote:
> I'm just wondering what people using on standard embedded/headless/diskless 
> targets (which do not have hw random number generators) as a source of 
> entropy - since networking was removed as an entropy source circa 2.6.26
> 
> On my target:
> 
> root:/> cat /proc/sys/kernel/random/entropy_avail
> 0
> 
> is about all I get... (since I'm not running any userspace utils yet).
> 
> I have seen rngd, clrngd, audio_entropyd, & video_entroyd - but I was just 
> wondering what others were actually using. (I was cautioned that everything 
> was pretty CPU intensive, since they all have a FIPS testing to ensure 
> randomness)...

The answer on the box I'm working on is: very little. I need to generate 
  an Ethernet MAC address and had to come up with way so that few random 
bits I had were sufficient, in my particular environment, to avoid 
address collisions.

^ permalink raw reply

* Sources of entropy?
From: Robin Getz @ 2009-03-24 22:47 UTC (permalink / raw)
  To: linux-embedded

I'm just wondering what people using on standard embedded/headless/diskless 
targets (which do not have hw random number generators) as a source of 
entropy - since networking was removed as an entropy source circa 2.6.26

On my target:

root:/> cat /proc/sys/kernel/random/entropy_avail
0

is about all I get... (since I'm not running any userspace utils yet).


I have seen rngd, clrngd, audio_entropyd, & video_entroyd - but I was just 
wondering what others were actually using. (I was cautioned that everything 
was pretty CPU intensive, since they all have a FIPS testing to ensure 
randomness)...

Thanks in advance.
-Robin

^ permalink raw reply

* Re: [Patch] ltt-relay-alloc mmap support (due to NFS lack of splice support)
From: Trond Myklebust @ 2009-03-23 19:14 UTC (permalink / raw)
  To: Mathieu Desnoyers
  Cc: Masahiro Tamori, Ingo Molnar, ltt-dev, linux-kernel,
	linux-embedded, linux-nfs, Jens Axboe, Nick Piggin
In-Reply-To: <20090323175820.GH24084@Krystal>

On Mon, 2009-03-23 at 13:58 -0400, Mathieu Desnoyers wrote:
> * Masahiro Tamori (masahiro.tamori@gmail.com) wrote:
> > 2009/3/21 Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>:
> > > * Masahiro Tamori (masahiro.tamori@gmail.com) wrote:
> [...]
> > >> Our customer will use NFS to store trace data not storage device for
> > >> embedded devices.
> > >> Since newer lttng use splice() even if NFS can not support splice(),
> > >> I create a patch to support to mmap of ltt-relay-alloc.
> > >>
> [...]
> > >> ltt-relay-alloc mmap support
> > >>
> > >> Splice syscall does not support NFS. We can not save trace data to
> > >> NFS directory. If this feature is enabled, you can use mmap()
> > >> instead of splice().
> > >>
> > >
> > >
> > > Hi Masahiro,
> > >
> > > Maybe we should consider implementing splice() support in NFS instead ?
> > >
> > > I removed the mmap support from the ltt-relay-alloc files because splice
> > > is more efficient and does not require to vmap the pages.  Unless there
> > > is a strong argument telling what in NFS makes it impossible to
> > > implement splice(), I don't really see the gain in putting back the
> > > old mmap() mechanism we had.
> > >
> > > Maybe the NFS people will have some information about this ?
> > >
> > > Thanks,
> > >
> > > Mathieu
> > >
> > 
> > Hello Mathieu,
> > 
> > I think that the best solution is NFS can support splice() even if
> > it cannot zero copy.
> > 
> > The splice() will be used by any other tools, hence NFS should support
> > it sooner or later.
> > 
> > If technical issue is remained to support splice() in NFS,
> > we should support mmap in LTTng until the problem is resolved.
> > Embedded people will want to use LTTng with NFS,
> > though this is a bad choice.
> > 
> > Thank you,
> > Masahiro Tamori
> > 
> 
> There was a LKML thread on NFS splice support back in 2006 :
> 
> http://lkml.indiana.edu/hypermail/linux/kernel/0603.3/2102.html
> 
> I don't know what happened with this ? I have tested NFS v2 and v3 and
> have seen they do not support splice, but haven't tested NFSv4.
> 
> Mathieu

We do support splice reads and apparently don't support splice writes.
However I don't see what has been stopping anybody from implementing the
latter.

In fact, it looks to me as if we should just be able to use
generic_file_splice_write() as is. There is no O_APPEND support or
anything that would require us to revalidate file lengths; it's just a
perfectly ordinary write into the page cache...

Cheers
   Trond

^ permalink raw reply

* Re: [Patch] ltt-relay-alloc mmap support (due to NFS lack of splice support)
From: Mathieu Desnoyers @ 2009-03-23 17:58 UTC (permalink / raw)
  To: Masahiro Tamori
  Cc: Ingo Molnar, ltt-dev, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-embedded-u79uwXL29TY76Z2rM5mHXA,
	linux-nfs-u79uwXL29TY76Z2rM5mHXA, Jens Axboe, Nick Piggin
In-Reply-To: <91e0b5050903230534g57d1ef8byd14a1fb5ca807192-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>

* Masahiro Tamori (masahiro.tamori-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org) wrote:
> 2009/3/21 Mathieu Desnoyers <mathieu.desnoyers-scC8bbJcJLCw5LPnMra/2Q@public.gmane.org>:
> > * Masahiro Tamori (masahiro.tamori-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org) wrote:
[...]
> >> Our customer will use NFS to store trace data not storage device for
> >> embedded devices.
> >> Since newer lttng use splice() even if NFS can not support splice(),
> >> I create a patch to support to mmap of ltt-relay-alloc.
> >>
[...]
> >> ltt-relay-alloc mmap support
> >>
> >> Splice syscall does not support NFS. We can not save trace data to
> >> NFS directory. If this feature is enabled, you can use mmap()
> >> instead of splice().
> >>
> >
> >
> > Hi Masahiro,
> >
> > Maybe we should consider implementing splice() support in NFS instead ?
> >
> > I removed the mmap support from the ltt-relay-alloc files because splice
> > is more efficient and does not require to vmap the pages.  Unless there
> > is a strong argument telling what in NFS makes it impossible to
> > implement splice(), I don't really see the gain in putting back the
> > old mmap() mechanism we had.
> >
> > Maybe the NFS people will have some information about this ?
> >
> > Thanks,
> >
> > Mathieu
> >
> 
> Hello Mathieu,
> 
> I think that the best solution is NFS can support splice() even if
> it cannot zero copy.
> 
> The splice() will be used by any other tools, hence NFS should support
> it sooner or later.
> 
> If technical issue is remained to support splice() in NFS,
> we should support mmap in LTTng until the problem is resolved.
> Embedded people will want to use LTTng with NFS,
> though this is a bad choice.
> 
> Thank you,
> Masahiro Tamori
> 

There was a LKML thread on NFS splice support back in 2006 :

http://lkml.indiana.edu/hypermail/linux/kernel/0603.3/2102.html

I don't know what happened with this ? I have tested NFS v2 and v3 and
have seen they do not support splice, but haven't tested NFSv4.

Mathieu

-- 
Mathieu Desnoyers
OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F  BA06 3F25 A8FE 3BAE 9A68
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [Patch] ltt-relay-alloc mmap support (due to NFS lack of splice  support)
From: Masahiro Tamori @ 2009-03-23 12:34 UTC (permalink / raw)
  To: Mathieu Desnoyers
  Cc: ltt-dev, linux-kernel-u79uwXL29TY76Z2rM5mHXA, Ingo Molnar,
	linux-nfs-u79uwXL29TY76Z2rM5mHXA,
	linux-embedded-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20090320152857.GB30019@Krystal>

2009/3/21 Mathieu Desnoyers <mathieu.desnoyers-scC8bbJcJLCw5LPnMra/2Q@public.gmane.org>:
> * Masahiro Tamori (masahiro.tamori-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org) wrote:
>> Hello Mathieu,
>>
>> I use the following version.
>> LTTV 0.12.12
>> LTTng 0.110
>> LTT Control 0.67
>> Kernles 2.6.29-rc7
>>
>> The target is ARM RealviewEB.
>>
>> Our customer will use NFS to store trace data not storage device for
>> embedded devices.
>> Since newer lttng use splice() even if NFS can not support splice(),
>> I create a patch to support to mmap of ltt-relay-alloc.
>>
>> I will send a mail to this mailing list for ltt-control patch.
>> I do not know which mailing list should be posted for userland tools.
>>
>> Best Regards,
>> Masahiro Tamori
>>
>>
>> ltt-relay-alloc mmap support
>>
>> Splice syscall does not support NFS. We can not save trace data to
>> NFS directory. If this feature is enabled, you can use mmap()
>> instead of splice().
>>
>
>
> Hi Masahiro,
>
> Maybe we should consider implementing splice() support in NFS instead ?
>
> I removed the mmap support from the ltt-relay-alloc files because splice
> is more efficient and does not require to vmap the pages.  Unless there
> is a strong argument telling what in NFS makes it impossible to
> implement splice(), I don't really see the gain in putting back the
> old mmap() mechanism we had.
>
> Maybe the NFS people will have some information about this ?
>
> Thanks,
>
> Mathieu
>

Hello Mathieu,

I think that the best solution is NFS can support splice() even if
it cannot zero copy.

The splice() will be used by any other tools, hence NFS should support
it sooner or later.

If technical issue is remained to support splice() in NFS,
we should support mmap in LTTng until the problem is resolved.
Embedded people will want to use LTTng with NFS,
though this is a bad choice.

Thank you,
Masahiro Tamori

>
>> For embeded system, NFS must be used. Target board has not enough memory
>> to save trace data and some board can not connect ATA, USB and some strage
>> devices.
>>
>> Signed-off-by: Masahiro.Tamori-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org
>> ---
>>  ltt/Kconfig              |   11      11 +    0 -     0 !
>>  ltt/ltt-relay-alloc.c    |   88      88 +    0 -     0 !
>>  ltt/ltt-relay-lockless.c |   15      15 +    0 -     0 !
>>  3 files changed, 114 insertions(+)
>>
>> Index: b/ltt/Kconfig
>> ===================================================================
>> --- a/ltt/Kconfig
>> +++ b/ltt/Kconfig
>> @@ -66,6 +66,17 @@ choice
>>
>>  endchoice
>>
>> +config LTT_RELAY_ALLOC_MMAP
>> +     bool "Linux Trace Toolkit Relay mmap Support"
>> +     depends on LTT_RELAY_ALLOC
>> +     default y
>> +     help
>> +       Support mmap for ltt-relay.
>> +
>> +       Splice syscall does not support NFS. We can not save trace data to
>> +          NFS directory. If this feature is enabled, you can use mmap()
>> +          instead of splice().
>> +
>>  config LTT_SERIALIZE
>>       tristate "Linux Trace Toolkit Serializer"
>>       depends on LTT_RELAY_ALLOC
>> Index: b/ltt/ltt-relay-alloc.c
>> ===================================================================
>> --- a/ltt/ltt-relay-alloc.c
>> +++ b/ltt/ltt-relay-alloc.c
>> @@ -27,6 +27,74 @@
>>  static DEFINE_MUTEX(relay_channels_mutex);
>>  static LIST_HEAD(relay_channels);
>>
>> +#ifdef CONFIG_LTT_RELAY_ALLOC_MMAP
>> +/*
>> + * close() vm_op implementation for relay file mapping.
>> + */
>> +static void relay_file_mmap_close(struct vm_area_struct *vma)
>> +{
>> +}
>> +
>> +/*
>> + * fault() vm_op implementation for relay file mapping.
>> + */
>> +static int relay_buf_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
>> +{
>> +     struct page *page = NULL;
>> +     struct rchan_buf *buf = vma->vm_private_data;
>> +     pgoff_t pgoff = vmf->pgoff;
>> +     struct page **pages;
>> +
>> +     if (!buf)
>> +             return VM_FAULT_OOM;
>> +
>> +     if (pgoff >= buf->page_count)
>> +             return VM_FAULT_SIGBUS;
>> +
>> +     pages = buf->pages;
>> +     page = pages[pgoff];
>> +     get_page(page);
>> +     vmf->page = page;
>> +
>> +     return 0;
>> +}
>> +
>> +/*
>> + * vm_ops for relay file mappings.
>> + */
>> +static struct vm_operations_struct relay_file_mmap_ops = {
>> +     .fault = relay_buf_fault,
>> +     .close = relay_file_mmap_close,
>> +};
>> +
>> +/**
>> + *   relay_mmap_buf: - mmap channel buffer to process address space
>> + *   @buf: relay channel buffer
>> + *   @vma: vm_area_struct describing memory to be mapped
>> + *
>> + *   Returns 0 if ok, negative on error
>> + *
>> + *   Caller should already have grabbed mmap_sem.
>> + */
>> +static int relay_mmap_buf(struct rchan_buf *buf, struct vm_area_struct *vma)
>> +{
>> +     unsigned long length = vma->vm_end - vma->vm_start;
>> +
>> +     if (!buf)
>> +             return -EBADF;
>> +
>> +     if (length != (unsigned long)buf->chan->alloc_size)
>> +             return -EINVAL;
>> +
>> +     vma->vm_ops = &relay_file_mmap_ops;
>> +     vma->vm_flags |= VM_DONTEXPAND;
>> +     vma->vm_private_data = buf;
>> +
>> +     return 0;
>> +}
>> +
>> +#endif /* CONFIG_LTT_RELAY_ALLOC_MMAP */
>> +
>>  /**
>>   *   relay_alloc_buf - allocate a channel buffer
>>   *   @buf: the buffer struct
>> @@ -601,6 +669,23 @@ static int relay_file_open(struct inode
>>       return nonseekable_open(inode, filp);
>>  }
>>
>> +#ifdef CONFIG_LTT_RELAY_ALLOC_MMAP
>> +
>> +/**
>> + *   relay_file_mmap - mmap file op for relay files
>> + *   @filp: the file
>> + *   @vma: the vma describing what to map
>> + *
>> + *   Calls upon relay_mmap_buf() to map the file into user space.
>> + */
>> +static int relay_file_mmap(struct file *filp, struct vm_area_struct *vma)
>> +{
>> +     struct rchan_buf *buf = filp->private_data;
>> +     return relay_mmap_buf(buf, vma);
>> +}
>> +
>> +#endif /* CONFIG_LTT_RELAY_ALLOC_MMAP */
>> +
>>  /**
>>   *   relay_file_release - release file op for relay files
>>   *   @inode: the inode
>> @@ -619,6 +704,9 @@ static int relay_file_release(struct ino
>>
>>  const struct file_operations ltt_relay_file_operations = {
>>       .open           = relay_file_open,
>> +#ifdef CONFIG_LTT_RELAY_ALLOC_MMAP
>> +     .mmap           = relay_file_mmap,
>> +#endif
>>       .release        = relay_file_release,
>>  };
>>  EXPORT_SYMBOL_GPL(ltt_relay_file_operations);
>> Index: b/ltt/ltt-relay-lockless.c
>> ===================================================================
>> --- a/ltt/ltt-relay-lockless.c
>> +++ b/ltt/ltt-relay-lockless.c
>> @@ -427,6 +427,18 @@ static int ltt_release(struct inode *ino
>>  }
>>
>>  /**
>> + *   ltt_mmap - mmap file op for ltt files
>> + *   @inode: opened inode
>> + *   @file: opened file
>> + *
>> + *   Mmap implementation.
>> + */
>> +static int ltt_mmap(struct file *file,  struct vm_area_struct *vma)
>> +{
>> +     return ltt_relay_file_operations.mmap(file, vma);
>> +}
>> +
>> +/**
>>   *   ltt_poll - file op for ltt files
>>   *   @filp: the file
>>   *   @wait: poll table
>> @@ -1590,6 +1602,9 @@ static struct ltt_transport ltt_relay_tr
>>  static const struct file_operations ltt_file_operations = {
>>       .open = ltt_open,
>>       .release = ltt_release,
>> +#ifdef CONFIG_LTT_RELAY_ALLOC_MMAP
>> +     .mmap           = ltt_mmap,
>> +#endif
>>       .poll = ltt_poll,
>>       .splice_read = ltt_relay_file_splice_read,
>>       .ioctl = ltt_ioctl,
>
> --
> Mathieu Desnoyers
> OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F  BA06 3F25 A8FE 3BAE 9A68
>
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* XZ (LZMA2) decoder
From: Lasse Collin @ 2009-03-22 13:57 UTC (permalink / raw)
  To: linux-embedded

(Please CC your replies to me, I'm not on the list.)

An initial version of the .xz file format decoder for Linux is now 
available at <git://ctrl.tukaani.org/xz-embedded.git>. It supports both 
stateful and single-call decoding using the LZMA2 algorithm.

Two buffers (1.2 KiB and 28 KiB) are allocated with kmalloc() for 
internal data. For stateful decoding, also a dictionary is allocated 
with vmalloc(), which probably will usually be from 64 KiB to 1 MiB. The 
dictionary is allocated when the decoder is created, so the decoder 
never allocates memory in the middle of decoding. This means that if the 
preallocated dictionary was too small for the input stream, decoding 
will fail. In single-call mode, the destination buffer is used as the 
dictionary, thus a separate dictionary doesn't need to be allocated.

On x86, xz_dec.ko is 11-14 KiB. Stack usage is around 120-240 bytes, 
depending on the GCC version and compiler flags. I hope it is not too 
much, but I can try to reduce it slightly if needed.

BCJ filters are not added yet. They will increase the code size a little 
but they should save more space by increasing compression ratio of 
executables (and naturally it will be possible to disable these filters 
in the kernel config).

There is some code (mostly in xz_boot.c), which hopefully makes it 
easier to add support for XZ compressed kernel and initramfs. I hope 
that someone else does the actual work to get XZ support in the arch-
specific trees (IIRC, there were some patches to add bzip2 and LZMA 
support already), but I'm happy to help if my code needs some 
adjustments to support that work.

I have tried to follow to the kernel coding style as well as I can, but 
if there are style issues that should be fixed, please let me know. I 
want to keep the code usable outside Linux, which why there are some 
extra #ifdefs and such. I hope this is OK.

I haven't tested the code much yet. It appears to work in userspace. The 
kernel module compiles cleanly on x86, but I haven't tested it in kernel 
space, because I currently have no code to feed data to the XZ decoder 
in the kernel space.

-- 
Lasse Collin  |  IRC: Larhzu @ IRCnet & Freenode

^ permalink raw reply

* [ANNOUNCE] Embedded Linux Conference 2009
From: Tim Bird @ 2009-03-09 22:00 UTC (permalink / raw)
  To: linux-embedded

My apologies in advance for this notice.  I only do this
a few times a year. Some people on this list may be interested....

Embedded Linux Developers,

Registration for Embedded Linux Conference 2009 -
   "Ubiquity" - is now open!

The conference is coming soon - It will be April 6, 7 and 8
in San Francisco, California.

The program is now available at the conference web site at:
http://www.embeddedlinuxconference.com/elc_2009/
(see the "Program" and "Sessions" tabs).

Here are some highlights:

Keynote speakers Dirk Hohndel and David Woodhouse will talk about
recent trends in Linux development, and what it means now that
Linux has achieved ubiquity in the embedded space.

* Dirk Hohndel is Intel's Chief Linux and Open Source Technologist
and former CTO of SuSE

* David Woodhouse is the official "embedded" maintainer for the mainline
Linux kernel, and the original author of the JFFS2 flash filesystem.

Just a few of the notable speakers presenting at the conference include:

* Jim Ready - Founder and CTO of MontaVista
* Kate Alhola - Maemo chief engineer in Forum Nokia
* Dan Malek - Founder and CTO of Embedded Alley
* Mike Anderson - CTO and Chief Scientist at The PTR Group

Along with these speakers, there will be 3 days of presentations,
tutorials and Bird-of-a-Feather sessions on topics like:

Flash filesystems, real-time Linux, graphics systems for embedded,
mobile and embedded distributions, optimizations for embedded
processors (SH, ARM, MIPS, PPC), security, memory management,
porting and platform bringup, networking, development tools,
compilers, tracing, bootup time reduction, power management,
   and (surprisingly) more!

This is your chance to talk to engineers working on real products at
some of the largest CE companies in the world, describing how they
solved real issues in their own development projects.  Also, meet
leading developers from the embedded Linux community, and learn about
the latest changes in Linux.  The Embedded Linux Conference is one of
the leading events where you can learn directly from the experts.
Just take a look at past conferences to see the technical depth of
this event!
See http://www.embeddedlinuxconference.com/history.html

I know... - In the current economic conditions, it's going to be tough
to convince your management to let you come to a conference - but NOW
is exactly the time to be honing your Linux skills and increasing
the efficiency of your development work.  A 15-minute hallway
conversation with an expert can save you weeks of development effort.
It's happened to me again and again at Embedded Linux Conferences
over the years, which is one of the reasons I keep coming back!

Register now by following the link on the conference page at:
    http://www.embeddedlinuxconference.com/elc_2009/

Please note that this year, we are co-locating with the Linux Foundation
Collaboration Summit.  This event will be held April 8-10 in the same
venue. As a special one-time opportunity, the Linux Foundation has
agreed to allow to ELC attendees to participate in that event as
well (at no charge). The Collaboration Summit is normally an invitation-only
event, so this is a unique opportunity to participate and interact
with additional community and industry Linux developers and leaders!

The website for the Collaboration Summit is:
http://events.linuxfoundation.org/events/collaboration-summit

We've got a great event planned, that we're sure you won't want to miss.
Register now and join us in San Francisco, for more progress towards
embedded Linux "Ubiquity"!

Register by March 20th to receive the "early-bird" (no relation to me)
discount!
 -- Tim

=============================
Tim Bird
Architecture Group Chair, CE Linux Forum
Senior Staff Engineer, Sony Corporation of America
=============================

^ permalink raw reply

* Re: ramfs/tmpfs for application partition
From: Aras Vaichas @ 2009-03-09  6:00 UTC (permalink / raw)
  To: Jacob Avraham; +Cc: linux-embedded@vger.kernel.org
In-Reply-To: <FF584854D6FFE547AB2F7515A798AC3A045716A1B4@venus.imagineil.tv>

Jacob Avraham wrote:
> Hi,
>
> I have a system with 128M RAM and a flash partitioned so that 10M is dedicated to initramfs image,
> 6M to application partition. And another 6M for JFFS2.
> As I have plenty of RAM, I'd like to have my application directory mounted on RAM, from a pre-populated
> filesystem that resides in the 6M application partition.
> So basically I want to use the same mechanism as initramfs, but mounted on /my/app/partition instead of root.
> Does it make sense? How do I go about and do that?
What about unionfs or Aufs?

I think you'd need to have your "original" as a proper filing system. 
Then you'd mount the unionfs over the top of it, but it would be in RAM. 
From the user's point of view, they'd had full read/write access to the 
whole filing system, but unionfs/Aufs would save the changes into RAM, 
not Flash.

This is how Linux Live CDs work. They allow you to "write" to the filing 
system on the CD using UnionsFS, but it's only temporary.

This should be be faster than uncompressing a compressed image into RAM, 
and the kernel will only cache the data that it needs as it accesses it. 
Since all write-backs will occur in RAM then this should be very fast.

Aras




______________________________________________________________________
This email has been scanned by the MessageLabs Email Security System.
For more information please visit http://www.messagelabs.com/email 
______________________________________________________________________

^ permalink raw reply

* Re: [PATCH] mflash: Initial support
From: Andrew Morton @ 2009-02-26 21:35 UTC (permalink / raw)
  Cc: linux-kernel, hch, alan, shdl, linux-arm-kernel, harvey.harrison,
	linux-embedded, minchan.kim, donari75
In-Reply-To: <1235554274-794-1-git-send-email-donari75@gmail.com>

On Wed, 25 Feb 2009 18:31:14 +0900
unsik Kim <donari75@gmail.com> wrote:

> This driver supports mflash IO mode for linux.
> 
> Mflash is embedded flash drive and mainly targeted mobile and consumer
> electronic devices.
> 
> Internally, mflash has nand flash and other hardware logics and supports
> 2 different operation (ATA, IO) modes. ATA mode doesn't need any new
> driver and currently works well under standard IDE subsystem. Actually it's
> one chip SSD. IO mode is ATA-like custom mode for the host that doesn't have
> IDE interface.
> 
> Followings are brief descriptions about IO mode.
> A. IO mode based on ATA protocol and uses some custom command. (read confirm,
> write confirm)
> B. IO mode uses SRAM bus interface.
> C. IO mode supports 4kB boot area, so host can boot from mflash.
> 

Have we fully explored the option of controlling this device with the
current ATA or IDE code, rather than creating a whole new parallel
block device implementation?

>
> ...
>
> --- /dev/null
> +++ b/drivers/block/mg_disk.c
> @@ -0,0 +1,981 @@
> +/*
> + *  drivers/block/mg_disk.c
> + *
> + *  Support for the mGine m[g]flash IO mode.
> + *  Based on legacy hd.c
> + *
> + * (c) 2008 mGine Co.,LTD
> + * (c) 2008 unsik Kim <donari75@gmail.com>
> + *
> + *  This program is free software; you can redistribute it and/or modify
> + *  it under the terms of the GNU General Public License version 2 as
> + *  published by the Free Software Foundation.
> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/fs.h>
> +#include <linux/blkdev.h>
> +#include <linux/hdreg.h>
> +#include <linux/interrupt.h>
> +#include <linux/delay.h>
> +#include <linux/platform_device.h>
> +#include <linux/gpio.h>
> +#include <linux/mg_disk.h>
> +
> +#define MG_RES_SEC (CONFIG_MG_DISK_RES << 1)
> +
> +static void mg_request(struct request_queue *);
> +
> +static void mg_dump_status(const char *msg, unsigned int stat,
> +		struct mg_host *host)
> +{
> +	char *name = MG_DISK_NAME"?";

The "?" seems strange.  Why do we want to print "mgd?" here?

> +	struct request *req;
> +
> +	if (host->breq) {
> +		req = elv_next_request(host->breq);
> +		if (req)
> +			name = req->rq_disk->disk_name;
> +	}
> +
> +	printk(KERN_DEBUG "%s: %s: status=0x%02x { ", name, msg, stat & 0xff);
> +	if (stat & MG_REG_STATUS_BIT_BUSY)
> +		printk("Busy ");
> +	if (stat & MG_REG_STATUS_BIT_READY)
> +		printk("DriveReady ");
> +	if (stat & MG_REG_STATUS_BIT_WRITE_FAULT)
> +		printk("WriteFault ");
> +	if (stat & MG_REG_STATUS_BIT_SEEK_DONE)
> +		printk("SeekComplete ");
> +	if (stat & MG_REG_STATUS_BIT_DATA_REQ)
> +		printk("DataRequest ");
> +	if (stat & MG_REG_STATUS_BIT_CORRECTED_ERROR)
> +		printk("CorrectedError ");
> +	if (stat & MG_REG_STATUS_BIT_ERROR)
> +		printk("Error ");
> +	printk("}\n");
> +	if ((stat & MG_REG_STATUS_BIT_ERROR) == 0) {
> +		host->error = 0;
> +	} else {
> +		host->error = inb(host->dev_base + MG_REG_ERROR);
> +		printk(KERN_DEBUG "%s: %s: error=0x%02x { ", name, msg,
> +				host->error & 0xff);
> +		if (host->error & MG_REG_ERR_BBK)
> +			printk("BadSector ");
> +		if (host->error & MG_REG_ERR_UNC)
> +			printk("UncorrectableError ");
> +		if (host->error & MG_REG_ERR_IDNF)
> +			printk("SectorIdNotFound ");
> +		if (host->error & MG_REG_ERR_ABRT)
> +			printk("DriveStatusError ");
> +		if (host->error & MG_REG_ERR_AMNF)
> +			printk("AddrMarkNotFound ");
> +		printk("}");
> +		if (host->error &
> +				(MG_REG_ERR_BBK | MG_REG_ERR_UNC |
> +				 MG_REG_ERR_IDNF | MG_REG_ERR_AMNF)) {
> +			if (host->breq) {
> +				req = elv_next_request(host->breq);
> +				if (req)
> +					printk(", sector=%ld", req->sector);
> +			}
> +
> +		}
> +		printk("\n");
> +	}
> +}
> +
> +static unsigned int mg_wait(struct mg_host *host, u32 expect, u32 msec)
> +{
> +	u8 status;
> +	u64 expire, cur_jiffies;

cur_jiffies64 would be a clearer name.

> +	host->error = MG_ERR_NONE;
> +	expire = get_jiffies_64() + msecs_to_jiffies(msec);

But why is this code using jiffies_64 at all?  Why not use plain old
jiffies and unsigned longs?


> +	status = inb(host->dev_base + MG_REG_STATUS);
> +	do {
> +		cur_jiffies = get_jiffies_64();
> +		if (status & MG_REG_STATUS_BIT_BUSY) {
> +			if (expect == MG_REG_STATUS_BIT_BUSY)
> +				break;
> +		} else {
> +			/* Check the error condition! */
> +			if (status & MG_REG_STATUS_BIT_ERROR) {
> +				mg_dump_status("mg_wait", status, host);
> +				break;
> +			}
> +
> +			if (expect == MG_STAT_READY)
> +				if (MG_READY_OK(status))
> +					break;
> +
> +			if (expect == MG_REG_STATUS_BIT_DATA_REQ)
> +				if (status & MG_REG_STATUS_BIT_DATA_REQ)
> +					break;
> +		}
> +		status = inb(host->dev_base + MG_REG_STATUS);
> +	} while (cur_jiffies < expire);

This loop will not handle jiffy wrap properly.  Use
time_after/time_before/etc.

> +	if (cur_jiffies >= expire)

ditto.

> +		host->error = MG_ERR_TIMEOUT;
> +
> +	return host->error;
> +}

This function appears to be doing up-to-multi-second busy wait looping.
Bad.

Can we fix this by waiting for some interrupt?  Presumably not.  Can we
at least do something to prevent it from locking up the whole machine
for long periods while it chews up vast amounts of power?  Evan a silly
msleep(1) in there would help tremendously.

> +static void mg_unexpected_intr(struct mg_host *host)
> +{
> +	u32 status = inb(host->dev_base + MG_REG_STATUS);
> +
> +	mg_dump_status("mg_unexpected_intr", status, host);
> +}
> +
> +static irqreturn_t mg_irq(int irq, void *dev_id)
> +{
> +	struct mg_host *host = dev_id;
> +	void (*handler)(struct mg_host *) = host->mg_do_intr;
> +
> +	host->mg_do_intr = 0;
> +	del_timer(&host->timer);
> +	if (!handler)
> +		handler = mg_unexpected_intr;
> +	handler(host);
> +	return IRQ_HANDLED;
> +}
> +
> +static void mg_ide_fixstring(u8 *s, const int bytecount)
> +{
> +	u8 *p, *end = &s[bytecount & ~1]; /* bytecount must be even */
> +
> +	/* convert from big-endian to host byte order */
> +	for (p = s ; p != end ; p += 2)

It's more conventional to omit the space before the semicolon in `for'
statements.

> +		be16_to_cpus((u16 *) p);
> +
> +	/* strip leading blanks */
> +	p = s;
> +	while (s != end && *s == ' ')
> +		++s;
> +	/* compress internal blanks and strip trailing blanks */
> +	while (s != end && *s) {
> +		if (*s++ != ' ' || (s != end && *s && *s != ' '))
> +			*p++ = *(s-1);
> +	}
> +	/* wipe out trailing garbage */
> +	while (p != end)
> +		*p++ = '\0';
> +}

erk, what's this doing?  Regularizing some ID text which it read from
the device, it seems.

It should have a nice comment explaining this, and perhaps explaining
the transformations which it attempts to make.

Because I'm sure that there's library code in the kernel which does at
least some of whatever-this-function-does.  Steve Rostedt presently has
some infrastructure code of this nature under review.

> +static int mg_get_disk_id(struct mg_host *host)
> +{
> +	u32 i, res;
> +	s32 err;
> +	u16 *id = (u16 *)&host->id_data;
> +	struct mg_drv_data *prv_data = host->dev->platform_data;
> +
> +	if (!prv_data->use_polling)
> +		outb(MG_REG_CTRL_INTR_DISABLE,
> +				host->dev_base + MG_REG_DRV_CTRL);
> +
> +	outb(MG_CMD_ID, host->dev_base + MG_REG_COMMAND);
> +	err = mg_wait(host, MG_REG_STATUS_BIT_DATA_REQ, 3000);
> +	if (err)
> +		return err;
> +
> +	for (i = 0; i < (MG_SECTOR_SIZE >> 1); i++)
> +		id[i] = le16_to_cpu(inw(host->dev_base + MG_BUFF_OFFSET +
> +					i * 2));
> +
> +	outb(MG_CMD_RD_CONF, host->dev_base + MG_REG_COMMAND);
> +	err = mg_wait(host, MG_STAT_READY, 3000);
> +	if (err)
> +		return err;
> +
> +	if ((host->id_data.field_valid & 1) == 0)
> +		return MG_ERR_TRANSLATION;
> +
> +#ifdef __BIG_ENDIAN
> +	host->id_data.lba_capacity = (host->id_data.lba_capacity << 16)
> +		| (host->id_data.lba_capacity >> 16);
> +#endif /* __BIG_ENDIAN */
> +	if (MG_RES_SEC) {
> +		/* modify cyls, lba_capacity */
> +		host->id_data.cyls = (host->id_data.lba_capacity - MG_RES_SEC) /
> +			host->id_data.heads / host->id_data.sectors;

Could a bad device trick the kernel into doing a divide-by-zero here?

> +		res = host->id_data.lba_capacity - host->id_data.cyls *
> +			host->id_data.heads * host->id_data.sectors;
> +		host->id_data.lba_capacity -= res;
> +	}
> +	host->tot_sectors = host->id_data.lba_capacity;
> +	mg_ide_fixstring(host->id_data.model,
> +			sizeof(host->id_data.model));
> +	mg_ide_fixstring(host->id_data.serial_no,
> +			sizeof(host->id_data.serial_no));
> +	mg_ide_fixstring(host->id_data.fw_rev,
> +			sizeof(host->id_data.fw_rev));
> +	printk(KERN_INFO "mg_disk: model: %s\n", host->id_data.model);
> +	printk(KERN_INFO "mg_disk: firm: %.8s\n", host->id_data.fw_rev);
> +	printk(KERN_INFO "mg_disk: serial: %s\n",
> +			host->id_data.serial_no);
> +	printk(KERN_INFO "mg_disk: %d + reserved %d sectors\n",
> +			host->tot_sectors, res);
> +
> +	if (!prv_data->use_polling)
> +		outb(MG_REG_CTRL_INTR_ENABLE, host->dev_base + MG_REG_DRV_CTRL);
> +
> +	return err;
> +}
>
> ...
>
> +static int mg_resume(struct platform_device *plat_dev)
> +{
> +	struct mg_drv_data *prv_data = plat_dev->dev.platform_data;
> +	struct mg_host *host = prv_data->host;
> +
> +	if (mg_wait(host, MG_STAT_READY, 3000))
> +		return -EIO;
> +
> +	outb(MG_CMD_WAKEUP, host->dev_base + MG_REG_COMMAND);
> +	mdelay(1);

There's no way in which the reader of this code can determine why this
delay is here, and why it has this duration.  Comments shold be added
to fix this!

Can we avoid using a busy-waiting delay?

> +	if (mg_wait(host, MG_STAT_READY, 3000))
> +		return -EIO;
> +
> +	if (!prv_data->use_polling)
> +		outb(MG_REG_CTRL_INTR_ENABLE, host->dev_base + MG_REG_DRV_CTRL);
> +
> +	return 0;
> +}
> +
> +static int mg_probe(struct platform_device *plat_dev)
> +{
> +	struct mg_host *host;
> +	struct resource *rsc;
> +	struct mg_drv_data *prv_data = plat_dev->dev.platform_data;
> +	int err = 0;
> +
> +	if (!prv_data) {
> +		printk(KERN_ERR	"%s:%d fail (no driver_data)\n",
> +				__func__, __LINE__);
> +		err = -EINVAL;
> +		goto probe_err;
> +	}
> +
> +	/* alloc mg_host */
> +	host = kmalloc(sizeof(struct mg_host), GFP_KERNEL);
> +	if (!host) {
> +		printk(KERN_ERR "%s:%d fail (no memory for mg_host)\n",
> +				__func__, __LINE__);
> +		err = -ENOMEM;
> +		goto probe_err;
> +	}
> +	memset(host, 0, sizeof(struct mg_host));

use kzalloc()

> +	host->major = MG_DISK_MAJ;
> +
> +	/* link each other */
> +	prv_data->host = host;
> +	host->dev = &plat_dev->dev;
> +
> +	/* io remap */
> +	rsc = platform_get_resource(plat_dev, IORESOURCE_MEM, 0);
> +	if (!rsc) {
> +		printk(KERN_ERR "%s:%d platform_get_resource fail\n",
> +				__func__, __LINE__);
> +		err = -EINVAL;
> +		goto probe_err_2;
> +	}
> +	host->dev_base = (unsigned long)ioremap(rsc->start , rsc->end + 1);

ioremap() returns `void __iomem *'.  Casting it into an unsigned long
loses the sparse-checkable annotation and loses the (correct)
information that this is an address.

IOW, host->dev_base has the wrong type, doesn't it?


> +	if (!host->dev_base) {
> +		printk(KERN_ERR "%s:%d ioremap fail\n",
> +				__func__, __LINE__);
> +		err = -EIO;
> +		goto probe_err_2;
> +	}
> +	MG_DBG("dev_base = 0x%x\n", (u32)host->dev_base);
> +
> +	/* get reset pin */
> +	rsc = platform_get_resource(plat_dev, IORESOURCE_IO, 0);
> +	if (!rsc) {
> +		printk(KERN_ERR "%s:%d get reset pin fail\n",
> +				__func__, __LINE__);
> +		err = -EIO;
> +		goto probe_err_3;
> +	}
> +	host->rst = rsc->start;
> +
> +	/* init rst pin */
> +	err = gpio_request(host->rst, "mg_rst");
> +	if (err)
> +		goto probe_err_3;
> +	gpio_direction_output(host->rst, 1);

Did this driver express a dependency on GPIO in its Kconfig?

> +	/* disk init */
> +	err = mg_disk_init(host);
> +	if (err) {
> +		printk(KERN_ERR "%s:%d fail (err code : %d)\n",
> +				__func__, __LINE__, err);
> +		err = -EIO;
> +		goto probe_err_3a;
> +	}
> +
>
> ...
>

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox