| Kernel v2.4.13-ac8 /fs/iobuf.c |
|---|
 2.4.13-ac8
 fs
 iobuf.c
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/fs/iobuf.c linux.ac/fs/iobuf.c
--- linux.vanilla/fs/iobuf.c Fri Apr 27 22:23:25 2001
+++ linux.ac/fs/iobuf.c Wed Oct 10 01:48:22 2001
@@ -4,12 +4,19 @@
* Keep track of the general-purpose IO-buffer structures used to track
* abstract kernel-space io buffers.
*
+ * 07/20/01 Rohit Seth <rohit.seth@intel.com> Made the iobuf come from
+ * kiobuf cache instead of vmalloc (that is a killer for most of archs.) These
+ * changes are specifically targeted for increasing raw IO performance.
+ * Introducing the new *_sz functions that take the number of bhs actually
+ * required by kiovec.
*/
#include <linux/iobuf.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
+static kmem_cache_t *kiobuf_cachep;
+
void end_kio_request(struct kiobuf *kiobuf, int uptodate)
{
if ((!uptodate) && !kiobuf->errno)
@@ -22,19 +29,32 @@
}
}
+void __init kiobuf_setup(void)
+{
+ kiobuf_cachep = kmem_cache_create("kiobuf",
+ sizeof(struct kiobuf),
+ 0,
+ SLAB_HWCACHE_ALIGN, NULL, NULL);
+ if(!kiobuf_cachep)
+ panic("Cannot create kernel iobuf cache\n");
+}
+
static void kiobuf_init(struct kiobuf *iobuf)
{
- memset(iobuf, 0, sizeof(*iobuf));
init_waitqueue_head(&iobuf->wait_queue);
iobuf->array_len = KIO_STATIC_PAGES;
iobuf->maplist = iobuf->map_array;
+ iobuf->nr_pages = 0;
+ iobuf->locked = 0;
+ iobuf->io_count.counter = 0;
+ iobuf->end_io = NULL;
}
-int alloc_kiobuf_bhs(struct kiobuf * kiobuf)
+int alloc_kiobuf_bhs_sz(struct kiobuf * kiobuf, int sz)
{
int i;
- for (i = 0; i < KIO_MAX_SECTORS; i++)
+ for (i = 0; i < sz; i++)
if (!(kiobuf->bh[i] = kmem_cache_alloc(bh_cachep, SLAB_KERNEL))) {
while (i--) {
kmem_cache_free(bh_cachep, kiobuf->bh[i]);
@@ -45,40 +65,42 @@
return 0;
}
-void free_kiobuf_bhs(struct kiobuf * kiobuf)
+void free_kiobuf_bhs_sz(struct kiobuf * kiobuf, int sz)
{
int i;
- for (i = 0; i < KIO_MAX_SECTORS; i++) {
+ for (i = 0; i < sz; i++) {
kmem_cache_free(bh_cachep, kiobuf->bh[i]);
kiobuf->bh[i] = NULL;
}
}
-int alloc_kiovec(int nr, struct kiobuf **bufp)
+int alloc_kiovec_sz(int nr, struct kiobuf **bufp, int *szp)
{
int i;
struct kiobuf *iobuf;
+ int *tszp = szp;
for (i = 0; i < nr; i++) {
- iobuf = vmalloc(sizeof(struct kiobuf));
+ iobuf = kmem_cache_alloc(kiobuf_cachep, SLAB_KERNEL);
if (!iobuf) {
- free_kiovec(i, bufp);
+ free_kiovec_sz(i, bufp, szp);
return -ENOMEM;
}
kiobuf_init(iobuf);
- if (alloc_kiobuf_bhs(iobuf)) {
- vfree(iobuf);
- free_kiovec(i, bufp);
+ if (alloc_kiobuf_bhs_sz(iobuf,*tszp)) {
+ kmem_cache_free(kiobuf_cachep, iobuf);
+ free_kiovec_sz(i, bufp, szp);
return -ENOMEM;
}
+ tszp++;
bufp[i] = iobuf;
}
return 0;
}
-void free_kiovec(int nr, struct kiobuf **bufp)
+void free_kiovec_sz(int nr, struct kiobuf **bufp, int *szp)
{
int i;
struct kiobuf *iobuf;
@@ -89,8 +111,9 @@
unlock_kiovec(1, &iobuf);
if (iobuf->array_len > KIO_STATIC_PAGES)
kfree (iobuf->maplist);
- free_kiobuf_bhs(iobuf);
- vfree(bufp[i]);
+ free_kiobuf_bhs_sz(iobuf,*szp);
+ kmem_cache_free(kiobuf_cachep, bufp[i]);
+ szp++;
}
}
@@ -122,7 +145,6 @@
return 0;
}
-
void kiobuf_wait_for_io(struct kiobuf *kiobuf)
{
struct task_struct *tsk = current;
@@ -143,6 +165,5 @@
tsk->state = TASK_RUNNING;
remove_wait_queue(&kiobuf->wait_queue, &wait);
}
-
|