aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristoph Lameter <christoph@lameter.com>2005-06-23 03:08:19 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-06-23 12:45:09 -0400
commit1946089a109251655c5438d92c539bd2930e71ea (patch)
tree819a492d5a7c4e6e695b150a86abeb99d5ac46eb
parent8c5a09082f4e61a176382e96a831a0636b918602 (diff)
[PATCH] NUMA aware block device control structure allocation
Patch to allocate the control structures for for ide devices on the node of the device itself (for NUMA systems). The patch depends on the Slab API change patch by Manfred and me (in mm) and the pcidev_to_node patch that I posted today. Does some realignment too. Signed-off-by: Justin M. Forbes <jmforbes@linuxtx.org> Signed-off-by: Christoph Lameter <christoph@lameter.com> Signed-off-by: Pravin Shelar <pravin@calsoftinc.com> Signed-off-by: Shobhit Dayal <shobhit@calsoftinc.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--drivers/block/as-iosched.c8
-rw-r--r--drivers/block/deadline-iosched.c8
-rw-r--r--drivers/block/genhd.c13
-rw-r--r--drivers/block/ll_rw_blk.c30
-rw-r--r--drivers/ide/ide-disk.c3
-rw-r--r--drivers/ide/ide-probe.c8
-rw-r--r--include/linux/blkdev.h6
-rw-r--r--include/linux/genhd.h1
-rw-r--r--include/linux/ide.h2
-rw-r--r--include/linux/mempool.h11
-rw-r--r--mm/mempool.c17
11 files changed, 77 insertions, 30 deletions
diff --git a/drivers/block/as-iosched.c b/drivers/block/as-iosched.c
index 638db06de2be..3410b4d294b9 100644
--- a/drivers/block/as-iosched.c
+++ b/drivers/block/as-iosched.c
@@ -1871,20 +1871,22 @@ static int as_init_queue(request_queue_t *q, elevator_t *e)
1871 if (!arq_pool) 1871 if (!arq_pool)
1872 return -ENOMEM; 1872 return -ENOMEM;
1873 1873
1874 ad = kmalloc(sizeof(*ad), GFP_KERNEL); 1874 ad = kmalloc_node(sizeof(*ad), GFP_KERNEL, q->node);
1875 if (!ad) 1875 if (!ad)
1876 return -ENOMEM; 1876 return -ENOMEM;
1877 memset(ad, 0, sizeof(*ad)); 1877 memset(ad, 0, sizeof(*ad));
1878 1878
1879 ad->q = q; /* Identify what queue the data belongs to */ 1879 ad->q = q; /* Identify what queue the data belongs to */
1880 1880
1881 ad->hash = kmalloc(sizeof(struct list_head)*AS_HASH_ENTRIES,GFP_KERNEL); 1881 ad->hash = kmalloc_node(sizeof(struct list_head)*AS_HASH_ENTRIES,
1882 GFP_KERNEL, q->node);
1882 if (!ad->hash) { 1883 if (!ad->hash) {
1883 kfree(ad); 1884 kfree(ad);
1884 return -ENOMEM; 1885 return -ENOMEM;
1885 } 1886 }
1886 1887
1887 ad->arq_pool = mempool_create(BLKDEV_MIN_RQ, mempool_alloc_slab, mempool_free_slab, arq_pool); 1888 ad->arq_pool = mempool_create_node(BLKDEV_MIN_RQ, mempool_alloc_slab,
1889 mempool_free_slab, arq_pool, q->node);
1888 if (!ad->arq_pool) { 1890 if (!ad->arq_pool) {
1889 kfree(ad->hash); 1891 kfree(ad->hash);
1890 kfree(ad); 1892 kfree(ad);
diff --git a/drivers/block/deadline-iosched.c b/drivers/block/deadline-iosched.c
index 7f79f3dd0165..4bc2fea73273 100644
--- a/drivers/block/deadline-iosched.c
+++ b/drivers/block/deadline-iosched.c
@@ -711,18 +711,20 @@ static int deadline_init_queue(request_queue_t *q, elevator_t *e)
711 if (!drq_pool) 711 if (!drq_pool)
712 return -ENOMEM; 712 return -ENOMEM;
713 713
714 dd = kmalloc(sizeof(*dd), GFP_KERNEL); 714 dd = kmalloc_node(sizeof(*dd), GFP_KERNEL, q->node);
715 if (!dd) 715 if (!dd)
716 return -ENOMEM; 716 return -ENOMEM;
717 memset(dd, 0, sizeof(*dd)); 717 memset(dd, 0, sizeof(*dd));
718 718
719 dd->hash = kmalloc(sizeof(struct list_head)*DL_HASH_ENTRIES,GFP_KERNEL); 719 dd->hash = kmalloc_node(sizeof(struct list_head)*DL_HASH_ENTRIES,
720 GFP_KERNEL, q->node);
720 if (!dd->hash) { 721 if (!dd->hash) {
721 kfree(dd); 722 kfree(dd);
722 return -ENOMEM; 723 return -ENOMEM;
723 } 724 }
724 725
725 dd->drq_pool = mempool_create(BLKDEV_MIN_RQ, mempool_alloc_slab, mempool_free_slab, drq_pool); 726 dd->drq_pool = mempool_create_node(BLKDEV_MIN_RQ, mempool_alloc_slab,
727 mempool_free_slab, drq_pool, q->node);
726 if (!dd->drq_pool) { 728 if (!dd->drq_pool) {
727 kfree(dd->hash); 729 kfree(dd->hash);
728 kfree(dd); 730 kfree(dd);
diff --git a/drivers/block/genhd.c b/drivers/block/genhd.c
index 53f7d846b747..43805e4d31e9 100644
--- a/drivers/block/genhd.c
+++ b/drivers/block/genhd.c
@@ -582,10 +582,16 @@ struct seq_operations diskstats_op = {
582 .show = diskstats_show 582 .show = diskstats_show
583}; 583};
584 584
585
586struct gendisk *alloc_disk(int minors) 585struct gendisk *alloc_disk(int minors)
587{ 586{
588 struct gendisk *disk = kmalloc(sizeof(struct gendisk), GFP_KERNEL); 587 return alloc_disk_node(minors, -1);
588}
589
590struct gendisk *alloc_disk_node(int minors, int node_id)
591{
592 struct gendisk *disk;
593
594 disk = kmalloc_node(sizeof(struct gendisk), GFP_KERNEL, node_id);
589 if (disk) { 595 if (disk) {
590 memset(disk, 0, sizeof(struct gendisk)); 596 memset(disk, 0, sizeof(struct gendisk));
591 if (!init_disk_stats(disk)) { 597 if (!init_disk_stats(disk)) {
@@ -594,7 +600,7 @@ struct gendisk *alloc_disk(int minors)
594 } 600 }
595 if (minors > 1) { 601 if (minors > 1) {
596 int size = (minors - 1) * sizeof(struct hd_struct *); 602 int size = (minors - 1) * sizeof(struct hd_struct *);
597 disk->part = kmalloc(size, GFP_KERNEL); 603 disk->part = kmalloc_node(size, GFP_KERNEL, node_id);
598 if (!disk->part) { 604 if (!disk->part) {
599 kfree(disk); 605 kfree(disk);
600 return NULL; 606 return NULL;
@@ -610,6 +616,7 @@ struct gendisk *alloc_disk(int minors)
610} 616}
611 617
612EXPORT_SYMBOL(alloc_disk); 618EXPORT_SYMBOL(alloc_disk);
619EXPORT_SYMBOL(alloc_disk_node);
613 620
614struct kobject *get_disk(struct gendisk *disk) 621struct kobject *get_disk(struct gendisk *disk)
615{ 622{
diff --git a/drivers/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c
index 81fe3a0c1fe7..cd8cf302068c 100644
--- a/drivers/block/ll_rw_blk.c
+++ b/drivers/block/ll_rw_blk.c
@@ -28,6 +28,7 @@
28#include <linux/slab.h> 28#include <linux/slab.h>
29#include <linux/swap.h> 29#include <linux/swap.h>
30#include <linux/writeback.h> 30#include <linux/writeback.h>
31#include <linux/blkdev.h>
31 32
32/* 33/*
33 * for max sense size 34 * for max sense size
@@ -1645,7 +1646,8 @@ static int blk_init_free_list(request_queue_t *q)
1645 init_waitqueue_head(&rl->wait[WRITE]); 1646 init_waitqueue_head(&rl->wait[WRITE]);
1646 init_waitqueue_head(&rl->drain); 1647 init_waitqueue_head(&rl->drain);
1647 1648
1648 rl->rq_pool = mempool_create(BLKDEV_MIN_RQ, mempool_alloc_slab, mempool_free_slab, request_cachep); 1649 rl->rq_pool = mempool_create_node(BLKDEV_MIN_RQ, mempool_alloc_slab,
1650 mempool_free_slab, request_cachep, q->node);
1649 1651
1650 if (!rl->rq_pool) 1652 if (!rl->rq_pool)
1651 return -ENOMEM; 1653 return -ENOMEM;
@@ -1657,8 +1659,15 @@ static int __make_request(request_queue_t *, struct bio *);
1657 1659
1658request_queue_t *blk_alloc_queue(int gfp_mask) 1660request_queue_t *blk_alloc_queue(int gfp_mask)
1659{ 1661{
1660 request_queue_t *q = kmem_cache_alloc(requestq_cachep, gfp_mask); 1662 return blk_alloc_queue_node(gfp_mask, -1);
1663}
1664EXPORT_SYMBOL(blk_alloc_queue);
1665
1666request_queue_t *blk_alloc_queue_node(int gfp_mask, int node_id)
1667{
1668 request_queue_t *q;
1661 1669
1670 q = kmem_cache_alloc_node(requestq_cachep, gfp_mask, node_id);
1662 if (!q) 1671 if (!q)
1663 return NULL; 1672 return NULL;
1664 1673
@@ -1671,8 +1680,7 @@ request_queue_t *blk_alloc_queue(int gfp_mask)
1671 1680
1672 return q; 1681 return q;
1673} 1682}
1674 1683EXPORT_SYMBOL(blk_alloc_queue_node);
1675EXPORT_SYMBOL(blk_alloc_queue);
1676 1684
1677/** 1685/**
1678 * blk_init_queue - prepare a request queue for use with a block device 1686 * blk_init_queue - prepare a request queue for use with a block device
@@ -1705,13 +1713,22 @@ EXPORT_SYMBOL(blk_alloc_queue);
1705 * blk_init_queue() must be paired with a blk_cleanup_queue() call 1713 * blk_init_queue() must be paired with a blk_cleanup_queue() call
1706 * when the block device is deactivated (such as at module unload). 1714 * when the block device is deactivated (such as at module unload).
1707 **/ 1715 **/
1716
1708request_queue_t *blk_init_queue(request_fn_proc *rfn, spinlock_t *lock) 1717request_queue_t *blk_init_queue(request_fn_proc *rfn, spinlock_t *lock)
1709{ 1718{
1710 request_queue_t *q = blk_alloc_queue(GFP_KERNEL); 1719 return blk_init_queue_node(rfn, lock, -1);
1720}
1721EXPORT_SYMBOL(blk_init_queue);
1722
1723request_queue_t *
1724blk_init_queue_node(request_fn_proc *rfn, spinlock_t *lock, int node_id)
1725{
1726 request_queue_t *q = blk_alloc_queue_node(GFP_KERNEL, node_id);
1711 1727
1712 if (!q) 1728 if (!q)
1713 return NULL; 1729 return NULL;
1714 1730
1731 q->node = node_id;
1715 if (blk_init_free_list(q)) 1732 if (blk_init_free_list(q))
1716 goto out_init; 1733 goto out_init;
1717 1734
@@ -1754,8 +1771,7 @@ out_init:
1754 kmem_cache_free(requestq_cachep, q); 1771 kmem_cache_free(requestq_cachep, q);
1755 return NULL; 1772 return NULL;
1756} 1773}
1757 1774EXPORT_SYMBOL(blk_init_queue_node);
1758EXPORT_SYMBOL(blk_init_queue);
1759 1775
1760int blk_get_queue(request_queue_t *q) 1776int blk_get_queue(request_queue_t *q)
1761{ 1777{
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c
index 3302cd8eab4c..d6f934886b04 100644
--- a/drivers/ide/ide-disk.c
+++ b/drivers/ide/ide-disk.c
@@ -1215,7 +1215,8 @@ static int ide_disk_probe(struct device *dev)
1215 if (!idkp) 1215 if (!idkp)
1216 goto failed; 1216 goto failed;
1217 1217
1218 g = alloc_disk(1 << PARTN_BITS); 1218 g = alloc_disk_node(1 << PARTN_BITS,
1219 pcibus_to_node(drive->hwif->pci_dev->bus));
1219 if (!g) 1220 if (!g)
1220 goto out_free_idkp; 1221 goto out_free_idkp;
1221 1222
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c
index 5d876f53c697..7df85af75371 100644
--- a/drivers/ide/ide-probe.c
+++ b/drivers/ide/ide-probe.c
@@ -977,8 +977,9 @@ static int ide_init_queue(ide_drive_t *drive)
977 * limits and LBA48 we could raise it but as yet 977 * limits and LBA48 we could raise it but as yet
978 * do not. 978 * do not.
979 */ 979 */
980 980
981 q = blk_init_queue(do_ide_request, &ide_lock); 981 q = blk_init_queue_node(do_ide_request, &ide_lock,
982 pcibus_to_node(drive->hwif->pci_dev->bus));
982 if (!q) 983 if (!q)
983 return 1; 984 return 1;
984 985
@@ -1095,7 +1096,8 @@ static int init_irq (ide_hwif_t *hwif)
1095 hwgroup->hwif->next = hwif; 1096 hwgroup->hwif->next = hwif;
1096 spin_unlock_irq(&ide_lock); 1097 spin_unlock_irq(&ide_lock);
1097 } else { 1098 } else {
1098 hwgroup = kmalloc(sizeof(ide_hwgroup_t),GFP_KERNEL); 1099 hwgroup = kmalloc_node(sizeof(ide_hwgroup_t), GFP_KERNEL,
1100 pcibus_to_node(hwif->drives[0].hwif->pci_dev->bus));
1099 if (!hwgroup) 1101 if (!hwgroup)
1100 goto out_up; 1102 goto out_up;
1101 1103
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 4a99b76c5a33..235c3414d268 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -396,6 +396,7 @@ struct request_queue
396 */ 396 */
397 unsigned int sg_timeout; 397 unsigned int sg_timeout;
398 unsigned int sg_reserved_size; 398 unsigned int sg_reserved_size;
399 int node;
399 400
400 struct list_head drain_list; 401 struct list_head drain_list;
401 402
@@ -615,6 +616,8 @@ static inline void blkdev_dequeue_request(struct request *req)
615/* 616/*
616 * Access functions for manipulating queue properties 617 * Access functions for manipulating queue properties
617 */ 618 */
619extern request_queue_t *blk_init_queue_node(request_fn_proc *rfn,
620 spinlock_t *lock, int node_id);
618extern request_queue_t *blk_init_queue(request_fn_proc *, spinlock_t *); 621extern request_queue_t *blk_init_queue(request_fn_proc *, spinlock_t *);
619extern void blk_cleanup_queue(request_queue_t *); 622extern void blk_cleanup_queue(request_queue_t *);
620extern void blk_queue_make_request(request_queue_t *, make_request_fn *); 623extern void blk_queue_make_request(request_queue_t *, make_request_fn *);
@@ -646,7 +649,8 @@ extern void blk_wait_queue_drained(request_queue_t *, int);
646extern void blk_finish_queue_drain(request_queue_t *); 649extern void blk_finish_queue_drain(request_queue_t *);
647 650
648int blk_get_queue(request_queue_t *); 651int blk_get_queue(request_queue_t *);
649request_queue_t *blk_alloc_queue(int); 652request_queue_t *blk_alloc_queue(int gfp_mask);
653request_queue_t *blk_alloc_queue_node(int,int);
650#define blk_put_queue(q) blk_cleanup_queue((q)) 654#define blk_put_queue(q) blk_cleanup_queue((q))
651 655
652/* 656/*
diff --git a/include/linux/genhd.h b/include/linux/genhd.h
index 47dedaf971d6..af26dc718ef6 100644
--- a/include/linux/genhd.h
+++ b/include/linux/genhd.h
@@ -403,6 +403,7 @@ extern int rescan_partitions(struct gendisk *disk, struct block_device *bdev);
403extern void add_partition(struct gendisk *, int, sector_t, sector_t); 403extern void add_partition(struct gendisk *, int, sector_t, sector_t);
404extern void delete_partition(struct gendisk *, int); 404extern void delete_partition(struct gendisk *, int);
405 405
406extern struct gendisk *alloc_disk_node(int minors, int node_id);
406extern struct gendisk *alloc_disk(int minors); 407extern struct gendisk *alloc_disk(int minors);
407extern struct kobject *get_disk(struct gendisk *disk); 408extern struct kobject *get_disk(struct gendisk *disk);
408extern void put_disk(struct gendisk *disk); 409extern void put_disk(struct gendisk *disk);
diff --git a/include/linux/ide.h b/include/linux/ide.h
index 336d6e509f59..92129078d4f3 100644
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -917,7 +917,7 @@ typedef struct hwif_s {
917 unsigned dma; 917 unsigned dma;
918 918
919 void (*led_act)(void *data, int rw); 919 void (*led_act)(void *data, int rw);
920} ide_hwif_t; 920} ____cacheline_maxaligned_in_smp ide_hwif_t;
921 921
922/* 922/*
923 * internal ide interrupt handler type 923 * internal ide interrupt handler type
diff --git a/include/linux/mempool.h b/include/linux/mempool.h
index 4a36edf1c974..796220ce47cc 100644
--- a/include/linux/mempool.h
+++ b/include/linux/mempool.h
@@ -20,9 +20,14 @@ typedef struct mempool_s {
20 mempool_free_t *free; 20 mempool_free_t *free;
21 wait_queue_head_t wait; 21 wait_queue_head_t wait;
22} mempool_t; 22} mempool_t;
23extern mempool_t * mempool_create(int min_nr, mempool_alloc_t *alloc_fn, 23
24 mempool_free_t *free_fn, void *pool_data); 24extern mempool_t *mempool_create(int min_nr, mempool_alloc_t *alloc_fn,
25extern int mempool_resize(mempool_t *pool, int new_min_nr, unsigned int __nocast gfp_mask); 25 mempool_free_t *free_fn, void *pool_data);
26extern mempool_t *mempool_create_node(int min_nr, mempool_alloc_t *alloc_fn,
27 mempool_free_t *free_fn, void *pool_data, int nid);
28
29extern int mempool_resize(mempool_t *pool, int new_min_nr,
30 unsigned int __nocast gfp_mask);
26extern void mempool_destroy(mempool_t *pool); 31extern void mempool_destroy(mempool_t *pool);
27extern void * mempool_alloc(mempool_t *pool, unsigned int __nocast gfp_mask); 32extern void * mempool_alloc(mempool_t *pool, unsigned int __nocast gfp_mask);
28extern void mempool_free(void *element, mempool_t *pool); 33extern void mempool_free(void *element, mempool_t *pool);
diff --git a/mm/mempool.c b/mm/mempool.c
index c9f3d4620428..920c8c3ab1b8 100644
--- a/mm/mempool.c
+++ b/mm/mempool.c
@@ -51,16 +51,23 @@ static void free_pool(mempool_t *pool)
51 * functions might sleep - as long as the mempool_alloc function is not called 51 * functions might sleep - as long as the mempool_alloc function is not called
52 * from IRQ contexts. 52 * from IRQ contexts.
53 */ 53 */
54mempool_t * mempool_create(int min_nr, mempool_alloc_t *alloc_fn, 54mempool_t *mempool_create(int min_nr, mempool_alloc_t *alloc_fn,
55 mempool_free_t *free_fn, void *pool_data) 55 mempool_free_t *free_fn, void *pool_data)
56{ 56{
57 mempool_t *pool; 57 return mempool_create_node(min_nr,alloc_fn,free_fn, pool_data,-1);
58}
59EXPORT_SYMBOL(mempool_create);
58 60
59 pool = kmalloc(sizeof(*pool), GFP_KERNEL); 61mempool_t *mempool_create_node(int min_nr, mempool_alloc_t *alloc_fn,
62 mempool_free_t *free_fn, void *pool_data, int node_id)
63{
64 mempool_t *pool;
65 pool = kmalloc_node(sizeof(*pool), GFP_KERNEL, node_id);
60 if (!pool) 66 if (!pool)
61 return NULL; 67 return NULL;
62 memset(pool, 0, sizeof(*pool)); 68 memset(pool, 0, sizeof(*pool));
63 pool->elements = kmalloc(min_nr * sizeof(void *), GFP_KERNEL); 69 pool->elements = kmalloc_node(min_nr * sizeof(void *),
70 GFP_KERNEL, node_id);
64 if (!pool->elements) { 71 if (!pool->elements) {
65 kfree(pool); 72 kfree(pool);
66 return NULL; 73 return NULL;
@@ -87,7 +94,7 @@ mempool_t * mempool_create(int min_nr, mempool_alloc_t *alloc_fn,
87 } 94 }
88 return pool; 95 return pool;
89} 96}
90EXPORT_SYMBOL(mempool_create); 97EXPORT_SYMBOL(mempool_create_node);
91 98
92/** 99/**
93 * mempool_resize - resize an existing memory pool 100 * mempool_resize - resize an existing memory pool