ext2 retry code (Was: Re: [patch] preemptive kernel, preemptive-2.3.52-A7)

From: Roger Larsson (roger.larsson@norran.net)
Date: Mon Mar 27 2000 - 16:15:30 EST


Hi,

I made a small calculation of the time required to make a user-kernel
copy
and the amount of data have to be huge to give an impact - unless you
end
up with a page fault, what will happen then? (Something sensible I
guess,
like rescheduling during IO, but while reading code I found this)

from ext2/file.c(280..307) linux-2.2.13
interesting lines marked (a)..(d)

                /* Tricky: what happens if we are writing the complete
                 * contents of a block which is not currently
                 * initialised? We have to obey the same
                 * synchronisation rules as the IO code, to prevent some
                 * other process from stomping on the buffer contents by
                 * refreshing them from disk while we are setting up the
                 * buffer. The copy_from_user() can page fault, after
                 * all. We also have to throw away partially successful
                 * copy_from_users to such buffers, since we can't trust
                 * the rest of the buffer_head in that case. --sct */

(a) new_buffer = (!buffer_uptodate(bh) && !buffer_locked(bh) &&
                              c == sb->s_blocksize);

(b) if (new_buffer) {
                        set_bit(BH_Lock, &bh->b_state);
(c) c -= copy_from_user (bh->b_data + offset, buf, c);
(d) if (c != sb->s_blocksize) {
                                c = 0;
                                unlock_buffer(bh);
                                brelse(bh);
                                if (!written)
                                        written = -EFAULT;
                                break;
                        }
                        mark_buffer_uptodate(bh, 1);
                        unlock_buffer(bh);
                } else {
                  

(a) Only buffers with "c == sb->s_blocksize" can be new_buffers
(b) Test for new buffers
(c.1) copy_from_user(..., c) will return c won't it???
(c.2) c -= c gives c = 0
(d) if (c != sb->s_blocksize) ALWAYS true
  and the buffer gets thrown away...
(d') should not the test be "if (c != 0) then" to catch partial copies

/RogerL

yodaiken@fsmlabs.com wrote:
>
> On Sat, Mar 25, 2000 at 10:38:35PM -0800, David S. Miller wrote:
> > Date: Sat, 25 Mar 2000 23:24:59 -0700
> > From: yodaiken@fsmlabs.com
> >
> > The hidden assumption of the pre-emption patch is that there are kernel
> > paths that take more than 500us to reach a schedule or return to user
> > mode. Obviously there are such paths, but what are they and why can't they
> > be fixed?
> >
> > Just to name a few obvious ones:
> >
> > 1) write(fd, buffer, SOME_LARGE_VALUE);
> > 2) read(fd, buffer, SOME_LARGE_VALUE);
> >
> > I honestly can't think of a way in which we'd want to deal with these
> > cases, except to perhaps check need_resched after or before copying
>
> We have a non-scaling, I/O system where we copy huge
> chunks of data for no reason
> Problem: on large reads/writes, the kernel can spend milliseconds copying
> data into kernel buffers:
> Loss of responsiveness
> Loss of throughput for useful work
> Blow cache.
> Waste memory.
>
>
> - - -

--
Home page:
  http://www.norran.net/nra02596/

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



This archive was generated by hypermail 2b29 : Fri Mar 31 2000 - 21:00:20 EST