diff options
-rw-r--r-- | fs/super.c | 11 | ||||
-rw-r--r-- | fs/xfs/xfs_buf.c | 6 | ||||
-rw-r--r-- | fs/xfs/xfs_qm.c | 10 | ||||
-rw-r--r-- | include/linux/list_lru.h | 13 | ||||
-rw-r--r-- | mm/list_lru.c | 14 |
5 files changed, 37 insertions, 17 deletions
diff --git a/fs/super.c b/fs/super.c index 181d42e2abff..269d96857caa 100644 --- a/fs/super.c +++ b/fs/super.c | |||
@@ -195,8 +195,12 @@ static struct super_block *alloc_super(struct file_system_type *type, int flags) | |||
195 | INIT_HLIST_NODE(&s->s_instances); | 195 | INIT_HLIST_NODE(&s->s_instances); |
196 | INIT_HLIST_BL_HEAD(&s->s_anon); | 196 | INIT_HLIST_BL_HEAD(&s->s_anon); |
197 | INIT_LIST_HEAD(&s->s_inodes); | 197 | INIT_LIST_HEAD(&s->s_inodes); |
198 | list_lru_init(&s->s_dentry_lru); | 198 | |
199 | list_lru_init(&s->s_inode_lru); | 199 | if (list_lru_init(&s->s_dentry_lru)) |
200 | goto err_out; | ||
201 | if (list_lru_init(&s->s_inode_lru)) | ||
202 | goto err_out_dentry_lru; | ||
203 | |||
200 | INIT_LIST_HEAD(&s->s_mounts); | 204 | INIT_LIST_HEAD(&s->s_mounts); |
201 | init_rwsem(&s->s_umount); | 205 | init_rwsem(&s->s_umount); |
202 | lockdep_set_class(&s->s_umount, &type->s_umount_key); | 206 | lockdep_set_class(&s->s_umount, &type->s_umount_key); |
@@ -236,6 +240,9 @@ static struct super_block *alloc_super(struct file_system_type *type, int flags) | |||
236 | } | 240 | } |
237 | out: | 241 | out: |
238 | return s; | 242 | return s; |
243 | |||
244 | err_out_dentry_lru: | ||
245 | list_lru_destroy(&s->s_dentry_lru); | ||
239 | err_out: | 246 | err_out: |
240 | security_sb_free(s); | 247 | security_sb_free(s); |
241 | #ifdef CONFIG_SMP | 248 | #ifdef CONFIG_SMP |
diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c index d46f6a3dc1de..49fdb7bed481 100644 --- a/fs/xfs/xfs_buf.c +++ b/fs/xfs/xfs_buf.c | |||
@@ -1592,6 +1592,7 @@ xfs_free_buftarg( | |||
1592 | struct xfs_mount *mp, | 1592 | struct xfs_mount *mp, |
1593 | struct xfs_buftarg *btp) | 1593 | struct xfs_buftarg *btp) |
1594 | { | 1594 | { |
1595 | list_lru_destroy(&btp->bt_lru); | ||
1595 | unregister_shrinker(&btp->bt_shrinker); | 1596 | unregister_shrinker(&btp->bt_shrinker); |
1596 | 1597 | ||
1597 | if (mp->m_flags & XFS_MOUNT_BARRIER) | 1598 | if (mp->m_flags & XFS_MOUNT_BARRIER) |
@@ -1666,9 +1667,12 @@ xfs_alloc_buftarg( | |||
1666 | if (!btp->bt_bdi) | 1667 | if (!btp->bt_bdi) |
1667 | goto error; | 1668 | goto error; |
1668 | 1669 | ||
1669 | list_lru_init(&btp->bt_lru); | ||
1670 | if (xfs_setsize_buftarg_early(btp, bdev)) | 1670 | if (xfs_setsize_buftarg_early(btp, bdev)) |
1671 | goto error; | 1671 | goto error; |
1672 | |||
1673 | if (list_lru_init(&btp->bt_lru)) | ||
1674 | goto error; | ||
1675 | |||
1672 | btp->bt_shrinker.count_objects = xfs_buftarg_shrink_count; | 1676 | btp->bt_shrinker.count_objects = xfs_buftarg_shrink_count; |
1673 | btp->bt_shrinker.scan_objects = xfs_buftarg_shrink_scan; | 1677 | btp->bt_shrinker.scan_objects = xfs_buftarg_shrink_scan; |
1674 | btp->bt_shrinker.seeks = DEFAULT_SEEKS; | 1678 | btp->bt_shrinker.seeks = DEFAULT_SEEKS; |
diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c index a29169b062e3..7f4138629a80 100644 --- a/fs/xfs/xfs_qm.c +++ b/fs/xfs/xfs_qm.c | |||
@@ -831,11 +831,18 @@ xfs_qm_init_quotainfo( | |||
831 | 831 | ||
832 | qinf = mp->m_quotainfo = kmem_zalloc(sizeof(xfs_quotainfo_t), KM_SLEEP); | 832 | qinf = mp->m_quotainfo = kmem_zalloc(sizeof(xfs_quotainfo_t), KM_SLEEP); |
833 | 833 | ||
834 | if ((error = list_lru_init(&qinf->qi_lru))) { | ||
835 | kmem_free(qinf); | ||
836 | mp->m_quotainfo = NULL; | ||
837 | return error; | ||
838 | } | ||
839 | |||
834 | /* | 840 | /* |
835 | * See if quotainodes are setup, and if not, allocate them, | 841 | * See if quotainodes are setup, and if not, allocate them, |
836 | * and change the superblock accordingly. | 842 | * and change the superblock accordingly. |
837 | */ | 843 | */ |
838 | if ((error = xfs_qm_init_quotainos(mp))) { | 844 | if ((error = xfs_qm_init_quotainos(mp))) { |
845 | list_lru_destroy(&qinf->qi_lru); | ||
839 | kmem_free(qinf); | 846 | kmem_free(qinf); |
840 | mp->m_quotainfo = NULL; | 847 | mp->m_quotainfo = NULL; |
841 | return error; | 848 | return error; |
@@ -846,8 +853,6 @@ xfs_qm_init_quotainfo( | |||
846 | INIT_RADIX_TREE(&qinf->qi_pquota_tree, GFP_NOFS); | 853 | INIT_RADIX_TREE(&qinf->qi_pquota_tree, GFP_NOFS); |
847 | mutex_init(&qinf->qi_tree_lock); | 854 | mutex_init(&qinf->qi_tree_lock); |
848 | 855 | ||
849 | list_lru_init(&qinf->qi_lru); | ||
850 | |||
851 | /* mutex used to serialize quotaoffs */ | 856 | /* mutex used to serialize quotaoffs */ |
852 | mutex_init(&qinf->qi_quotaofflock); | 857 | mutex_init(&qinf->qi_quotaofflock); |
853 | 858 | ||
@@ -935,6 +940,7 @@ xfs_qm_destroy_quotainfo( | |||
935 | qi = mp->m_quotainfo; | 940 | qi = mp->m_quotainfo; |
936 | ASSERT(qi != NULL); | 941 | ASSERT(qi != NULL); |
937 | 942 | ||
943 | list_lru_destroy(&qi->qi_lru); | ||
938 | unregister_shrinker(&qi->qi_shrinker); | 944 | unregister_shrinker(&qi->qi_shrinker); |
939 | 945 | ||
940 | if (qi->qi_uquotaip) { | 946 | if (qi->qi_uquotaip) { |
diff --git a/include/linux/list_lru.h b/include/linux/list_lru.h index 4d02ad3badab..3ce541753c88 100644 --- a/include/linux/list_lru.h +++ b/include/linux/list_lru.h | |||
@@ -27,20 +27,11 @@ struct list_lru_node { | |||
27 | } ____cacheline_aligned_in_smp; | 27 | } ____cacheline_aligned_in_smp; |
28 | 28 | ||
29 | struct list_lru { | 29 | struct list_lru { |
30 | /* | 30 | struct list_lru_node *node; |
31 | * Because we use a fixed-size array, this struct can be very big if | ||
32 | * MAX_NUMNODES is big. If this becomes a problem this is fixable by | ||
33 | * turning this into a pointer and dynamically allocating this to | ||
34 | * nr_node_ids. This quantity is firwmare-provided, and still would | ||
35 | * provide room for all nodes at the cost of a pointer lookup and an | ||
36 | * extra allocation. Because that allocation will most likely come from | ||
37 | * a different slab cache than the main structure holding this | ||
38 | * structure, we may very well fail. | ||
39 | */ | ||
40 | struct list_lru_node node[MAX_NUMNODES]; | ||
41 | nodemask_t active_nodes; | 31 | nodemask_t active_nodes; |
42 | }; | 32 | }; |
43 | 33 | ||
34 | void list_lru_destroy(struct list_lru *lru); | ||
44 | int list_lru_init(struct list_lru *lru); | 35 | int list_lru_init(struct list_lru *lru); |
45 | 36 | ||
46 | /** | 37 | /** |
diff --git a/mm/list_lru.c b/mm/list_lru.c index f91c24188573..72467914b856 100644 --- a/mm/list_lru.c +++ b/mm/list_lru.c | |||
@@ -8,6 +8,7 @@ | |||
8 | #include <linux/module.h> | 8 | #include <linux/module.h> |
9 | #include <linux/mm.h> | 9 | #include <linux/mm.h> |
10 | #include <linux/list_lru.h> | 10 | #include <linux/list_lru.h> |
11 | #include <linux/slab.h> | ||
11 | 12 | ||
12 | bool list_lru_add(struct list_lru *lru, struct list_head *item) | 13 | bool list_lru_add(struct list_lru *lru, struct list_head *item) |
13 | { | 14 | { |
@@ -115,9 +116,14 @@ EXPORT_SYMBOL_GPL(list_lru_walk_node); | |||
115 | int list_lru_init(struct list_lru *lru) | 116 | int list_lru_init(struct list_lru *lru) |
116 | { | 117 | { |
117 | int i; | 118 | int i; |
119 | size_t size = sizeof(*lru->node) * nr_node_ids; | ||
120 | |||
121 | lru->node = kzalloc(size, GFP_KERNEL); | ||
122 | if (!lru->node) | ||
123 | return -ENOMEM; | ||
118 | 124 | ||
119 | nodes_clear(lru->active_nodes); | 125 | nodes_clear(lru->active_nodes); |
120 | for (i = 0; i < MAX_NUMNODES; i++) { | 126 | for (i = 0; i < nr_node_ids; i++) { |
121 | spin_lock_init(&lru->node[i].lock); | 127 | spin_lock_init(&lru->node[i].lock); |
122 | INIT_LIST_HEAD(&lru->node[i].list); | 128 | INIT_LIST_HEAD(&lru->node[i].list); |
123 | lru->node[i].nr_items = 0; | 129 | lru->node[i].nr_items = 0; |
@@ -125,3 +131,9 @@ int list_lru_init(struct list_lru *lru) | |||
125 | return 0; | 131 | return 0; |
126 | } | 132 | } |
127 | EXPORT_SYMBOL_GPL(list_lru_init); | 133 | EXPORT_SYMBOL_GPL(list_lru_init); |
134 | |||
135 | void list_lru_destroy(struct list_lru *lru) | ||
136 | { | ||
137 | kfree(lru->node); | ||
138 | } | ||
139 | EXPORT_SYMBOL_GPL(list_lru_destroy); | ||