|
@@ -104,6 +104,18 @@ struct dio {
|
|
unsigned cur_page_len; /* Nr of bytes at cur_page_offset */
|
|
unsigned cur_page_len; /* Nr of bytes at cur_page_offset */
|
|
sector_t cur_page_block; /* Where it starts */
|
|
sector_t cur_page_block; /* Where it starts */
|
|
|
|
|
|
|
|
+ /* BIO completion state */
|
|
|
|
+ spinlock_t bio_lock; /* protects BIO fields below */
|
|
|
|
+ unsigned long refcount; /* direct_io_worker() and bios */
|
|
|
|
+ struct bio *bio_list; /* singly linked via bi_private */
|
|
|
|
+ struct task_struct *waiter; /* waiting task (NULL if none) */
|
|
|
|
+
|
|
|
|
+ /* AIO related stuff */
|
|
|
|
+ struct kiocb *iocb; /* kiocb */
|
|
|
|
+ int is_async; /* is IO async ? */
|
|
|
|
+ int io_error; /* IO error in completion path */
|
|
|
|
+ ssize_t result; /* IO result */
|
|
|
|
+
|
|
/*
|
|
/*
|
|
* Page fetching state. These variables belong to dio_refill_pages().
|
|
* Page fetching state. These variables belong to dio_refill_pages().
|
|
*/
|
|
*/
|
|
@@ -115,22 +127,16 @@ struct dio {
|
|
* Page queue. These variables belong to dio_refill_pages() and
|
|
* Page queue. These variables belong to dio_refill_pages() and
|
|
* dio_get_page().
|
|
* dio_get_page().
|
|
*/
|
|
*/
|
|
- struct page *pages[DIO_PAGES]; /* page buffer */
|
|
|
|
unsigned head; /* next page to process */
|
|
unsigned head; /* next page to process */
|
|
unsigned tail; /* last valid page + 1 */
|
|
unsigned tail; /* last valid page + 1 */
|
|
int page_errors; /* errno from get_user_pages() */
|
|
int page_errors; /* errno from get_user_pages() */
|
|
|
|
|
|
- /* BIO completion state */
|
|
|
|
- spinlock_t bio_lock; /* protects BIO fields below */
|
|
|
|
- unsigned long refcount; /* direct_io_worker() and bios */
|
|
|
|
- struct bio *bio_list; /* singly linked via bi_private */
|
|
|
|
- struct task_struct *waiter; /* waiting task (NULL if none) */
|
|
|
|
-
|
|
|
|
- /* AIO related stuff */
|
|
|
|
- struct kiocb *iocb; /* kiocb */
|
|
|
|
- int is_async; /* is IO async ? */
|
|
|
|
- int io_error; /* IO error in completion path */
|
|
|
|
- ssize_t result; /* IO result */
|
|
|
|
|
|
+ /*
|
|
|
|
+ * pages[] (and any fields placed after it) are not zeroed out at
|
|
|
|
+ * allocation time. Don't add new fields after pages[] unless you
|
|
|
|
+ * wish that they not be zeroed.
|
|
|
|
+ */
|
|
|
|
+ struct page *pages[DIO_PAGES]; /* page buffer */
|
|
};
|
|
};
|
|
|
|
|
|
/*
|
|
/*
|
|
@@ -1151,10 +1157,16 @@ __blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode,
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- dio = kzalloc(sizeof(*dio), GFP_KERNEL);
|
|
|
|
|
|
+ dio = kmalloc(sizeof(*dio), GFP_KERNEL);
|
|
retval = -ENOMEM;
|
|
retval = -ENOMEM;
|
|
if (!dio)
|
|
if (!dio)
|
|
goto out;
|
|
goto out;
|
|
|
|
+ /*
|
|
|
|
+ * Believe it or not, zeroing out the page array caused a .5%
|
|
|
|
+ * performance regression in a database benchmark. So, we take
|
|
|
|
+ * care to only zero out what's needed.
|
|
|
|
+ */
|
|
|
|
+ memset(dio, 0, offsetof(struct dio, pages));
|
|
|
|
|
|
/*
|
|
/*
|
|
* For block device access DIO_NO_LOCKING is used,
|
|
* For block device access DIO_NO_LOCKING is used,
|