aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-08-26 14:48:42 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2018-08-26 14:48:42 -0400
commitaba16dc5cf9318b4e0fe92f8261779cd9f1d2d77 (patch)
tree1f53d2cee40e82efe6a727208307af475327af9a
parentc4726e774ed27680c418e138234dfd2b8e1e89ac (diff)
parent1df895190233fcc30d46beca4550bcafb7b959a6 (diff)
Merge branch 'ida-4.19' of git://git.infradead.org/users/willy/linux-dax
Pull IDA updates from Matthew Wilcox: "A better IDA API: id = ida_alloc(ida, GFP_xxx); ida_free(ida, id); rather than the cumbersome ida_simple_get(), ida_simple_remove(). The new IDA API is similar to ida_simple_get() but better named. The internal restructuring of the IDA code removes the bitmap preallocation nonsense. I hope the net -200 lines of code is convincing" * 'ida-4.19' of git://git.infradead.org/users/willy/linux-dax: (29 commits) ida: Change ida_get_new_above to return the id ida: Remove old API test_ida: check_ida_destroy and check_ida_alloc test_ida: Convert check_ida_conv to new API test_ida: Move ida_check_max test_ida: Move ida_check_leaf idr-test: Convert ida_check_nomem to new API ida: Start new test_ida module target/iscsi: Allocate session IDs from an IDA iscsi target: fix session creation failure handling drm/vmwgfx: Convert to new IDA API dmaengine: Convert to new IDA API ppc: Convert vas ID allocation to new IDA API media: Convert entity ID allocation to new IDA API ppc: Convert mmu context allocation to new IDA API Convert net_namespace to new IDA API cb710: Convert to new IDA API rsxx: Convert to new IDA API osd: Convert to new IDA API sd: Convert to new IDA API ...
-rw-r--r--arch/powerpc/mm/mmu_context_book3s64.c44
-rw-r--r--arch/powerpc/platforms/powernv/vas-window.c26
-rw-r--r--drivers/block/mtip32xx/mtip32xx.c29
-rw-r--r--drivers/block/rsxx/core.c21
-rw-r--r--drivers/dma/dmaengine.c23
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_gmrid_manager.c41
-rw-r--r--drivers/media/media-device.c16
-rw-r--r--drivers/misc/cb710/core.c23
-rw-r--r--drivers/scsi/osd/osd_uld.c22
-rw-r--r--drivers/scsi/sd.c21
-rw-r--r--drivers/target/iscsi/iscsi_target.c10
-rw-r--r--drivers/target/iscsi/iscsi_target.h4
-rw-r--r--drivers/target/iscsi/iscsi_target_login.c41
-rw-r--r--fs/devpts/inode.c47
-rw-r--r--fs/namespace.c50
-rw-r--r--fs/super.c67
-rw-r--r--include/linux/idr.h68
-rw-r--r--lib/Kconfig.debug3
-rw-r--r--lib/Makefile1
-rw-r--r--lib/idr.c155
-rw-r--r--lib/radix-tree.c11
-rw-r--r--lib/test_ida.c177
-rw-r--r--net/core/net_namespace.c16
-rw-r--r--tools/testing/radix-tree/Makefile6
-rw-r--r--tools/testing/radix-tree/idr-test.c214
-rw-r--r--tools/testing/radix-tree/linux/xarray.h2
-rw-r--r--tools/testing/radix-tree/main.c23
-rw-r--r--tools/testing/radix-tree/test.h3
28 files changed, 485 insertions, 679 deletions
diff --git a/arch/powerpc/mm/mmu_context_book3s64.c b/arch/powerpc/mm/mmu_context_book3s64.c
index 4a892d894a0f..dbd8f762140b 100644
--- a/arch/powerpc/mm/mmu_context_book3s64.c
+++ b/arch/powerpc/mm/mmu_context_book3s64.c
@@ -26,48 +26,16 @@
26#include <asm/mmu_context.h> 26#include <asm/mmu_context.h>
27#include <asm/pgalloc.h> 27#include <asm/pgalloc.h>
28 28
29static DEFINE_SPINLOCK(mmu_context_lock);
30static DEFINE_IDA(mmu_context_ida); 29static DEFINE_IDA(mmu_context_ida);
31 30
32static int alloc_context_id(int min_id, int max_id) 31static int alloc_context_id(int min_id, int max_id)
33{ 32{
34 int index, err; 33 return ida_alloc_range(&mmu_context_ida, min_id, max_id, GFP_KERNEL);
35
36again:
37 if (!ida_pre_get(&mmu_context_ida, GFP_KERNEL))
38 return -ENOMEM;
39
40 spin_lock(&mmu_context_lock);
41 err = ida_get_new_above(&mmu_context_ida, min_id, &index);
42 spin_unlock(&mmu_context_lock);
43
44 if (err == -EAGAIN)
45 goto again;
46 else if (err)
47 return err;
48
49 if (index > max_id) {
50 spin_lock(&mmu_context_lock);
51 ida_remove(&mmu_context_ida, index);
52 spin_unlock(&mmu_context_lock);
53 return -ENOMEM;
54 }
55
56 return index;
57} 34}
58 35
59void hash__reserve_context_id(int id) 36void hash__reserve_context_id(int id)
60{ 37{
61 int rc, result = 0; 38 int result = ida_alloc_range(&mmu_context_ida, id, id, GFP_KERNEL);
62
63 do {
64 if (!ida_pre_get(&mmu_context_ida, GFP_KERNEL))
65 break;
66
67 spin_lock(&mmu_context_lock);
68 rc = ida_get_new_above(&mmu_context_ida, id, &result);
69 spin_unlock(&mmu_context_lock);
70 } while (rc == -EAGAIN);
71 39
72 WARN(result != id, "mmu: Failed to reserve context id %d (rc %d)\n", id, result); 40 WARN(result != id, "mmu: Failed to reserve context id %d (rc %d)\n", id, result);
73} 41}
@@ -172,9 +140,7 @@ int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
172 140
173void __destroy_context(int context_id) 141void __destroy_context(int context_id)
174{ 142{
175 spin_lock(&mmu_context_lock); 143 ida_free(&mmu_context_ida, context_id);
176 ida_remove(&mmu_context_ida, context_id);
177 spin_unlock(&mmu_context_lock);
178} 144}
179EXPORT_SYMBOL_GPL(__destroy_context); 145EXPORT_SYMBOL_GPL(__destroy_context);
180 146
@@ -182,13 +148,11 @@ static void destroy_contexts(mm_context_t *ctx)
182{ 148{
183 int index, context_id; 149 int index, context_id;
184 150
185 spin_lock(&mmu_context_lock);
186 for (index = 0; index < ARRAY_SIZE(ctx->extended_id); index++) { 151 for (index = 0; index < ARRAY_SIZE(ctx->extended_id); index++) {
187 context_id = ctx->extended_id[index]; 152 context_id = ctx->extended_id[index];
188 if (context_id) 153 if (context_id)
189 ida_remove(&mmu_context_ida, context_id); 154 ida_free(&mmu_context_ida, context_id);
190 } 155 }
191 spin_unlock(&mmu_context_lock);
192} 156}
193 157
194static void pte_frag_destroy(void *pte_frag) 158static void pte_frag_destroy(void *pte_frag)
diff --git a/arch/powerpc/platforms/powernv/vas-window.c b/arch/powerpc/platforms/powernv/vas-window.c
index ff9f48812331..e59e0e60e5b5 100644
--- a/arch/powerpc/platforms/powernv/vas-window.c
+++ b/arch/powerpc/platforms/powernv/vas-window.c
@@ -515,35 +515,17 @@ int init_winctx_regs(struct vas_window *window, struct vas_winctx *winctx)
515 return 0; 515 return 0;
516} 516}
517 517
518static DEFINE_SPINLOCK(vas_ida_lock);
519
520static void vas_release_window_id(struct ida *ida, int winid) 518static void vas_release_window_id(struct ida *ida, int winid)
521{ 519{
522 spin_lock(&vas_ida_lock); 520 ida_free(ida, winid);
523 ida_remove(ida, winid);
524 spin_unlock(&vas_ida_lock);
525} 521}
526 522
527static int vas_assign_window_id(struct ida *ida) 523static int vas_assign_window_id(struct ida *ida)
528{ 524{
529 int rc, winid; 525 int winid = ida_alloc_max(ida, VAS_WINDOWS_PER_CHIP - 1, GFP_KERNEL);
530
531 do {
532 rc = ida_pre_get(ida, GFP_KERNEL);
533 if (!rc)
534 return -EAGAIN;
535
536 spin_lock(&vas_ida_lock);
537 rc = ida_get_new(ida, &winid);
538 spin_unlock(&vas_ida_lock);
539 } while (rc == -EAGAIN);
540
541 if (rc)
542 return rc;
543 526
544 if (winid > VAS_WINDOWS_PER_CHIP) { 527 if (winid == -ENOSPC) {
545 pr_err("Too many (%d) open windows\n", winid); 528 pr_err("Too many (%d) open windows\n", VAS_WINDOWS_PER_CHIP);
546 vas_release_window_id(ida, winid);
547 return -EAGAIN; 529 return -EAGAIN;
548 } 530 }
549 531
diff --git a/drivers/block/mtip32xx/mtip32xx.c b/drivers/block/mtip32xx/mtip32xx.c
index db253cd5b32a..d0666f5ce003 100644
--- a/drivers/block/mtip32xx/mtip32xx.c
+++ b/drivers/block/mtip32xx/mtip32xx.c
@@ -118,7 +118,6 @@ static struct dentry *dfs_device_status;
118 118
119static u32 cpu_use[NR_CPUS]; 119static u32 cpu_use[NR_CPUS];
120 120
121static DEFINE_SPINLOCK(rssd_index_lock);
122static DEFINE_IDA(rssd_index_ida); 121static DEFINE_IDA(rssd_index_ida);
123 122
124static int mtip_block_initialize(struct driver_data *dd); 123static int mtip_block_initialize(struct driver_data *dd);
@@ -3767,20 +3766,10 @@ static int mtip_block_initialize(struct driver_data *dd)
3767 goto alloc_disk_error; 3766 goto alloc_disk_error;
3768 } 3767 }
3769 3768
3770 /* Generate the disk name, implemented same as in sd.c */ 3769 rv = ida_alloc(&rssd_index_ida, GFP_KERNEL);
3771 do { 3770 if (rv < 0)
3772 if (!ida_pre_get(&rssd_index_ida, GFP_KERNEL)) {
3773 rv = -ENOMEM;
3774 goto ida_get_error;
3775 }
3776
3777 spin_lock(&rssd_index_lock);
3778 rv = ida_get_new(&rssd_index_ida, &index);
3779 spin_unlock(&rssd_index_lock);
3780 } while (rv == -EAGAIN);
3781
3782 if (rv)
3783 goto ida_get_error; 3771 goto ida_get_error;
3772 index = rv;
3784 3773
3785 rv = rssd_disk_name_format("rssd", 3774 rv = rssd_disk_name_format("rssd",
3786 index, 3775 index,
@@ -3922,9 +3911,7 @@ block_queue_alloc_init_error:
3922block_queue_alloc_tag_error: 3911block_queue_alloc_tag_error:
3923 mtip_hw_debugfs_exit(dd); 3912 mtip_hw_debugfs_exit(dd);
3924disk_index_error: 3913disk_index_error:
3925 spin_lock(&rssd_index_lock); 3914 ida_free(&rssd_index_ida, index);
3926 ida_remove(&rssd_index_ida, index);
3927 spin_unlock(&rssd_index_lock);
3928 3915
3929ida_get_error: 3916ida_get_error:
3930 put_disk(dd->disk); 3917 put_disk(dd->disk);
@@ -4012,9 +3999,7 @@ static int mtip_block_remove(struct driver_data *dd)
4012 } 3999 }
4013 dd->disk = NULL; 4000 dd->disk = NULL;
4014 4001
4015 spin_lock(&rssd_index_lock); 4002 ida_free(&rssd_index_ida, dd->index);
4016 ida_remove(&rssd_index_ida, dd->index);
4017 spin_unlock(&rssd_index_lock);
4018 4003
4019 /* De-initialize the protocol layer. */ 4004 /* De-initialize the protocol layer. */
4020 mtip_hw_exit(dd); 4005 mtip_hw_exit(dd);
@@ -4054,9 +4039,7 @@ static int mtip_block_shutdown(struct driver_data *dd)
4054 dd->queue = NULL; 4039 dd->queue = NULL;
4055 } 4040 }
4056 4041
4057 spin_lock(&rssd_index_lock); 4042 ida_free(&rssd_index_ida, dd->index);
4058 ida_remove(&rssd_index_ida, dd->index);
4059 spin_unlock(&rssd_index_lock);
4060 return 0; 4043 return 0;
4061} 4044}
4062 4045
diff --git a/drivers/block/rsxx/core.c b/drivers/block/rsxx/core.c
index b7d71914a32a..f2c631ce793c 100644
--- a/drivers/block/rsxx/core.c
+++ b/drivers/block/rsxx/core.c
@@ -58,7 +58,6 @@ MODULE_PARM_DESC(sync_start, "On by Default: Driver load will not complete "
58 "until the card startup has completed."); 58 "until the card startup has completed.");
59 59
60static DEFINE_IDA(rsxx_disk_ida); 60static DEFINE_IDA(rsxx_disk_ida);
61static DEFINE_SPINLOCK(rsxx_ida_lock);
62 61
63/* --------------------Debugfs Setup ------------------- */ 62/* --------------------Debugfs Setup ------------------- */
64 63
@@ -771,19 +770,10 @@ static int rsxx_pci_probe(struct pci_dev *dev,
771 card->dev = dev; 770 card->dev = dev;
772 pci_set_drvdata(dev, card); 771 pci_set_drvdata(dev, card);
773 772
774 do { 773 st = ida_alloc(&rsxx_disk_ida, GFP_KERNEL);
775 if (!ida_pre_get(&rsxx_disk_ida, GFP_KERNEL)) { 774 if (st < 0)
776 st = -ENOMEM;
777 goto failed_ida_get;
778 }
779
780 spin_lock(&rsxx_ida_lock);
781 st = ida_get_new(&rsxx_disk_ida, &card->disk_id);
782 spin_unlock(&rsxx_ida_lock);
783 } while (st == -EAGAIN);
784
785 if (st)
786 goto failed_ida_get; 775 goto failed_ida_get;
776 card->disk_id = st;
787 777
788 st = pci_enable_device(dev); 778 st = pci_enable_device(dev);
789 if (st) 779 if (st)
@@ -985,9 +975,7 @@ failed_request_regions:
985failed_dma_mask: 975failed_dma_mask:
986 pci_disable_device(dev); 976 pci_disable_device(dev);
987failed_enable: 977failed_enable:
988 spin_lock(&rsxx_ida_lock); 978 ida_free(&rsxx_disk_ida, card->disk_id);
989 ida_remove(&rsxx_disk_ida, card->disk_id);
990 spin_unlock(&rsxx_ida_lock);
991failed_ida_get: 979failed_ida_get:
992 kfree(card); 980 kfree(card);
993 981
@@ -1050,6 +1038,7 @@ static void rsxx_pci_remove(struct pci_dev *dev)
1050 pci_disable_device(dev); 1038 pci_disable_device(dev);
1051 pci_release_regions(dev); 1039 pci_release_regions(dev);
1052 1040
1041 ida_free(&rsxx_disk_ida, card->disk_id);
1053 kfree(card); 1042 kfree(card);
1054} 1043}
1055 1044
diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c
index 272bed6c8ba7..f1a441ab395d 100644
--- a/drivers/dma/dmaengine.c
+++ b/drivers/dma/dmaengine.c
@@ -161,9 +161,7 @@ static void chan_dev_release(struct device *dev)
161 161
162 chan_dev = container_of(dev, typeof(*chan_dev), device); 162 chan_dev = container_of(dev, typeof(*chan_dev), device);
163 if (atomic_dec_and_test(chan_dev->idr_ref)) { 163 if (atomic_dec_and_test(chan_dev->idr_ref)) {
164 mutex_lock(&dma_list_mutex); 164 ida_free(&dma_ida, chan_dev->dev_id);
165 ida_remove(&dma_ida, chan_dev->dev_id);
166 mutex_unlock(&dma_list_mutex);
167 kfree(chan_dev->idr_ref); 165 kfree(chan_dev->idr_ref);
168 } 166 }
169 kfree(chan_dev); 167 kfree(chan_dev);
@@ -898,17 +896,12 @@ static bool device_has_all_tx_types(struct dma_device *device)
898 896
899static int get_dma_id(struct dma_device *device) 897static int get_dma_id(struct dma_device *device)
900{ 898{
901 int rc; 899 int rc = ida_alloc(&dma_ida, GFP_KERNEL);
902
903 do {
904 if (!ida_pre_get(&dma_ida, GFP_KERNEL))
905 return -ENOMEM;
906 mutex_lock(&dma_list_mutex);
907 rc = ida_get_new(&dma_ida, &device->dev_id);
908 mutex_unlock(&dma_list_mutex);
909 } while (rc == -EAGAIN);
910 900
911 return rc; 901 if (rc < 0)
902 return rc;
903 device->dev_id = rc;
904 return 0;
912} 905}
913 906
914/** 907/**
@@ -1092,9 +1085,7 @@ int dma_async_device_register(struct dma_device *device)
1092err_out: 1085err_out:
1093 /* if we never registered a channel just release the idr */ 1086 /* if we never registered a channel just release the idr */
1094 if (atomic_read(idr_ref) == 0) { 1087 if (atomic_read(idr_ref) == 0) {
1095 mutex_lock(&dma_list_mutex); 1088 ida_free(&dma_ida, device->dev_id);
1096 ida_remove(&dma_ida, device->dev_id);
1097 mutex_unlock(&dma_list_mutex);
1098 kfree(idr_ref); 1089 kfree(idr_ref);
1099 return rc; 1090 return rc;
1100 } 1091 }
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_gmrid_manager.c b/drivers/gpu/drm/vmwgfx/vmwgfx_gmrid_manager.c
index ddb1e9365a3e..b93c558dd86e 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_gmrid_manager.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_gmrid_manager.c
@@ -51,51 +51,34 @@ static int vmw_gmrid_man_get_node(struct ttm_mem_type_manager *man,
51{ 51{
52 struct vmwgfx_gmrid_man *gman = 52 struct vmwgfx_gmrid_man *gman =
53 (struct vmwgfx_gmrid_man *)man->priv; 53 (struct vmwgfx_gmrid_man *)man->priv;
54 int ret = 0;
55 int id; 54 int id;
56 55
57 mem->mm_node = NULL; 56 mem->mm_node = NULL;
58 57
58 id = ida_alloc_max(&gman->gmr_ida, gman->max_gmr_ids - 1, GFP_KERNEL);
59 if (id < 0)
60 return id;
61
59 spin_lock(&gman->lock); 62 spin_lock(&gman->lock);
60 63
61 if (gman->max_gmr_pages > 0) { 64 if (gman->max_gmr_pages > 0) {
62 gman->used_gmr_pages += bo->num_pages; 65 gman->used_gmr_pages += bo->num_pages;
63 if (unlikely(gman->used_gmr_pages > gman->max_gmr_pages)) 66 if (unlikely(gman->used_gmr_pages > gman->max_gmr_pages))
64 goto out_err_locked; 67 goto nospace;
65 } 68 }
66 69
67 do { 70 mem->mm_node = gman;
68 spin_unlock(&gman->lock); 71 mem->start = id;
69 if (unlikely(ida_pre_get(&gman->gmr_ida, GFP_KERNEL) == 0)) { 72 mem->num_pages = bo->num_pages;
70 ret = -ENOMEM;
71 goto out_err;
72 }
73 spin_lock(&gman->lock);
74
75 ret = ida_get_new(&gman->gmr_ida, &id);
76 if (unlikely(ret == 0 && id >= gman->max_gmr_ids)) {
77 ida_remove(&gman->gmr_ida, id);
78 ret = 0;
79 goto out_err_locked;
80 }
81 } while (ret == -EAGAIN);
82
83 if (likely(ret == 0)) {
84 mem->mm_node = gman;
85 mem->start = id;
86 mem->num_pages = bo->num_pages;
87 } else
88 goto out_err_locked;
89 73
90 spin_unlock(&gman->lock); 74 spin_unlock(&gman->lock);
91 return 0; 75 return 0;
92 76
93out_err: 77nospace:
94 spin_lock(&gman->lock);
95out_err_locked:
96 gman->used_gmr_pages -= bo->num_pages; 78 gman->used_gmr_pages -= bo->num_pages;
97 spin_unlock(&gman->lock); 79 spin_unlock(&gman->lock);
98 return ret; 80 ida_free(&gman->gmr_ida, id);
81 return 0;
99} 82}
100 83
101static void vmw_gmrid_man_put_node(struct ttm_mem_type_manager *man, 84static void vmw_gmrid_man_put_node(struct ttm_mem_type_manager *man,
@@ -105,8 +88,8 @@ static void vmw_gmrid_man_put_node(struct ttm_mem_type_manager *man,
105 (struct vmwgfx_gmrid_man *)man->priv; 88 (struct vmwgfx_gmrid_man *)man->priv;
106 89
107 if (mem->mm_node) { 90 if (mem->mm_node) {
91 ida_free(&gman->gmr_ida, mem->start);
108 spin_lock(&gman->lock); 92 spin_lock(&gman->lock);
109 ida_remove(&gman->gmr_ida, mem->start);
110 gman->used_gmr_pages -= mem->num_pages; 93 gman->used_gmr_pages -= mem->num_pages;
111 spin_unlock(&gman->lock); 94 spin_unlock(&gman->lock);
112 mem->mm_node = NULL; 95 mem->mm_node = NULL;
diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c
index fcdf3d5dc4b6..3bae24b15eaa 100644
--- a/drivers/media/media-device.c
+++ b/drivers/media/media-device.c
@@ -585,18 +585,12 @@ int __must_check media_device_register_entity(struct media_device *mdev,
585 entity->num_links = 0; 585 entity->num_links = 0;
586 entity->num_backlinks = 0; 586 entity->num_backlinks = 0;
587 587
588 if (!ida_pre_get(&mdev->entity_internal_idx, GFP_KERNEL)) 588 ret = ida_alloc_min(&mdev->entity_internal_idx, 1, GFP_KERNEL);
589 return -ENOMEM; 589 if (ret < 0)
590
591 mutex_lock(&mdev->graph_mutex);
592
593 ret = ida_get_new_above(&mdev->entity_internal_idx, 1,
594 &entity->internal_idx);
595 if (ret < 0) {
596 mutex_unlock(&mdev->graph_mutex);
597 return ret; 590 return ret;
598 } 591 entity->internal_idx = ret;
599 592
593 mutex_lock(&mdev->graph_mutex);
600 mdev->entity_internal_idx_max = 594 mdev->entity_internal_idx_max =
601 max(mdev->entity_internal_idx_max, entity->internal_idx); 595 max(mdev->entity_internal_idx_max, entity->internal_idx);
602 596
@@ -642,7 +636,7 @@ static void __media_device_unregister_entity(struct media_entity *entity)
642 struct media_interface *intf; 636 struct media_interface *intf;
643 unsigned int i; 637 unsigned int i;
644 638
645 ida_simple_remove(&mdev->entity_internal_idx, entity->internal_idx); 639 ida_free(&mdev->entity_internal_idx, entity->internal_idx);
646 640
647 /* Remove all interface links pointing to this entity */ 641 /* Remove all interface links pointing to this entity */
648 list_for_each_entry(intf, &mdev->interfaces, graph_obj.list) { 642 list_for_each_entry(intf, &mdev->interfaces, graph_obj.list) {
diff --git a/drivers/misc/cb710/core.c b/drivers/misc/cb710/core.c
index 4d4acf763b65..2c43fd09d602 100644
--- a/drivers/misc/cb710/core.c
+++ b/drivers/misc/cb710/core.c
@@ -16,7 +16,6 @@
16#include <linux/gfp.h> 16#include <linux/gfp.h>
17 17
18static DEFINE_IDA(cb710_ida); 18static DEFINE_IDA(cb710_ida);
19static DEFINE_SPINLOCK(cb710_ida_lock);
20 19
21void cb710_pci_update_config_reg(struct pci_dev *pdev, 20void cb710_pci_update_config_reg(struct pci_dev *pdev,
22 int reg, uint32_t mask, uint32_t xor) 21 int reg, uint32_t mask, uint32_t xor)
@@ -205,7 +204,6 @@ static int cb710_probe(struct pci_dev *pdev,
205 const struct pci_device_id *ent) 204 const struct pci_device_id *ent)
206{ 205{
207 struct cb710_chip *chip; 206 struct cb710_chip *chip;
208 unsigned long flags;
209 u32 val; 207 u32 val;
210 int err; 208 int err;
211 int n = 0; 209 int n = 0;
@@ -256,18 +254,10 @@ static int cb710_probe(struct pci_dev *pdev,
256 if (err) 254 if (err)
257 return err; 255 return err;
258 256
259 do { 257 err = ida_alloc(&cb710_ida, GFP_KERNEL);
260 if (!ida_pre_get(&cb710_ida, GFP_KERNEL)) 258 if (err < 0)
261 return -ENOMEM; 259 return err;
262 260 chip->platform_id = err;
263 spin_lock_irqsave(&cb710_ida_lock, flags);
264 err = ida_get_new(&cb710_ida, &chip->platform_id);
265 spin_unlock_irqrestore(&cb710_ida_lock, flags);
266
267 if (err && err != -EAGAIN)
268 return err;
269 } while (err);
270
271 261
272 dev_info(&pdev->dev, "id %d, IO 0x%p, IRQ %d\n", 262 dev_info(&pdev->dev, "id %d, IO 0x%p, IRQ %d\n",
273 chip->platform_id, chip->iobase, pdev->irq); 263 chip->platform_id, chip->iobase, pdev->irq);
@@ -308,7 +298,6 @@ unreg_mmc:
308static void cb710_remove_one(struct pci_dev *pdev) 298static void cb710_remove_one(struct pci_dev *pdev)
309{ 299{
310 struct cb710_chip *chip = pci_get_drvdata(pdev); 300 struct cb710_chip *chip = pci_get_drvdata(pdev);
311 unsigned long flags;
312 301
313 cb710_unregister_slot(chip, CB710_SLOT_SM); 302 cb710_unregister_slot(chip, CB710_SLOT_SM);
314 cb710_unregister_slot(chip, CB710_SLOT_MS); 303 cb710_unregister_slot(chip, CB710_SLOT_MS);
@@ -317,9 +306,7 @@ static void cb710_remove_one(struct pci_dev *pdev)
317 BUG_ON(atomic_read(&chip->slot_refs_count) != 0); 306 BUG_ON(atomic_read(&chip->slot_refs_count) != 0);
318#endif 307#endif
319 308
320 spin_lock_irqsave(&cb710_ida_lock, flags); 309 ida_free(&cb710_ida, chip->platform_id);
321 ida_remove(&cb710_ida, chip->platform_id);
322 spin_unlock_irqrestore(&cb710_ida_lock, flags);
323} 310}
324 311
325static const struct pci_device_id cb710_pci_tbl[] = { 312static const struct pci_device_id cb710_pci_tbl[] = {
diff --git a/drivers/scsi/osd/osd_uld.c b/drivers/scsi/osd/osd_uld.c
index 0e56f1eb05dc..eaf36ccf58db 100644
--- a/drivers/scsi/osd/osd_uld.c
+++ b/drivers/scsi/osd/osd_uld.c
@@ -423,19 +423,11 @@ static int osd_probe(struct device *dev)
423 if (scsi_device->type != TYPE_OSD) 423 if (scsi_device->type != TYPE_OSD)
424 return -ENODEV; 424 return -ENODEV;
425 425
426 do { 426 minor = ida_alloc_max(&osd_minor_ida, SCSI_OSD_MAX_MINOR, GFP_KERNEL);
427 if (!ida_pre_get(&osd_minor_ida, GFP_KERNEL)) 427 if (minor == -ENOSPC)
428 return -ENODEV; 428 return -EBUSY;
429 429 if (minor < 0)
430 error = ida_get_new(&osd_minor_ida, &minor); 430 return -ENODEV;
431 } while (error == -EAGAIN);
432
433 if (error)
434 return error;
435 if (minor >= SCSI_OSD_MAX_MINOR) {
436 error = -EBUSY;
437 goto err_retract_minor;
438 }
439 431
440 error = -ENOMEM; 432 error = -ENOMEM;
441 oud = kzalloc(sizeof(*oud), GFP_KERNEL); 433 oud = kzalloc(sizeof(*oud), GFP_KERNEL);
@@ -499,7 +491,7 @@ static int osd_probe(struct device *dev)
499err_free_osd: 491err_free_osd:
500 put_device(&oud->class_dev); 492 put_device(&oud->class_dev);
501err_retract_minor: 493err_retract_minor:
502 ida_remove(&osd_minor_ida, minor); 494 ida_free(&osd_minor_ida, minor);
503 return error; 495 return error;
504} 496}
505 497
@@ -514,7 +506,7 @@ static int osd_remove(struct device *dev)
514 } 506 }
515 507
516 cdev_device_del(&oud->cdev, &oud->class_dev); 508 cdev_device_del(&oud->cdev, &oud->class_dev);
517 ida_remove(&osd_minor_ida, oud->minor); 509 ida_free(&osd_minor_ida, oud->minor);
518 put_device(&oud->class_dev); 510 put_device(&oud->class_dev);
519 511
520 return 0; 512 return 0;
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index a58cee7a85f2..b79b366a94f7 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -123,7 +123,6 @@ static void scsi_disk_release(struct device *cdev);
123static void sd_print_sense_hdr(struct scsi_disk *, struct scsi_sense_hdr *); 123static void sd_print_sense_hdr(struct scsi_disk *, struct scsi_sense_hdr *);
124static void sd_print_result(const struct scsi_disk *, const char *, int); 124static void sd_print_result(const struct scsi_disk *, const char *, int);
125 125
126static DEFINE_SPINLOCK(sd_index_lock);
127static DEFINE_IDA(sd_index_ida); 126static DEFINE_IDA(sd_index_ida);
128 127
129/* This semaphore is used to mediate the 0->1 reference get in the 128/* This semaphore is used to mediate the 0->1 reference get in the
@@ -3340,16 +3339,8 @@ static int sd_probe(struct device *dev)
3340 if (!gd) 3339 if (!gd)
3341 goto out_free; 3340 goto out_free;
3342 3341
3343 do { 3342 index = ida_alloc(&sd_index_ida, GFP_KERNEL);
3344 if (!ida_pre_get(&sd_index_ida, GFP_KERNEL)) 3343 if (index < 0) {
3345 goto out_put;
3346
3347 spin_lock(&sd_index_lock);
3348 error = ida_get_new(&sd_index_ida, &index);
3349 spin_unlock(&sd_index_lock);
3350 } while (error == -EAGAIN);
3351
3352 if (error) {
3353 sdev_printk(KERN_WARNING, sdp, "sd_probe: memory exhausted.\n"); 3344 sdev_printk(KERN_WARNING, sdp, "sd_probe: memory exhausted.\n");
3354 goto out_put; 3345 goto out_put;
3355 } 3346 }
@@ -3393,9 +3384,7 @@ static int sd_probe(struct device *dev)
3393 return 0; 3384 return 0;
3394 3385
3395 out_free_index: 3386 out_free_index:
3396 spin_lock(&sd_index_lock); 3387 ida_free(&sd_index_ida, index);
3397 ida_remove(&sd_index_ida, index);
3398 spin_unlock(&sd_index_lock);
3399 out_put: 3388 out_put:
3400 put_disk(gd); 3389 put_disk(gd);
3401 out_free: 3390 out_free:
@@ -3460,9 +3449,7 @@ static void scsi_disk_release(struct device *dev)
3460 struct scsi_disk *sdkp = to_scsi_disk(dev); 3449 struct scsi_disk *sdkp = to_scsi_disk(dev);
3461 struct gendisk *disk = sdkp->disk; 3450 struct gendisk *disk = sdkp->disk;
3462 3451
3463 spin_lock(&sd_index_lock); 3452 ida_free(&sd_index_ida, sdkp->index);
3464 ida_remove(&sd_index_ida, sdkp->index);
3465 spin_unlock(&sd_index_lock);
3466 3453
3467 disk->private_data = NULL; 3454 disk->private_data = NULL;
3468 put_disk(disk); 3455 put_disk(disk);
diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c
index 8e223799347a..94bad43c41ff 100644
--- a/drivers/target/iscsi/iscsi_target.c
+++ b/drivers/target/iscsi/iscsi_target.c
@@ -57,9 +57,8 @@ static DEFINE_SPINLOCK(tiqn_lock);
57static DEFINE_MUTEX(np_lock); 57static DEFINE_MUTEX(np_lock);
58 58
59static struct idr tiqn_idr; 59static struct idr tiqn_idr;
60struct idr sess_idr; 60DEFINE_IDA(sess_ida);
61struct mutex auth_id_lock; 61struct mutex auth_id_lock;
62spinlock_t sess_idr_lock;
63 62
64struct iscsit_global *iscsit_global; 63struct iscsit_global *iscsit_global;
65 64
@@ -700,9 +699,7 @@ static int __init iscsi_target_init_module(void)
700 699
701 spin_lock_init(&iscsit_global->ts_bitmap_lock); 700 spin_lock_init(&iscsit_global->ts_bitmap_lock);
702 mutex_init(&auth_id_lock); 701 mutex_init(&auth_id_lock);
703 spin_lock_init(&sess_idr_lock);
704 idr_init(&tiqn_idr); 702 idr_init(&tiqn_idr);
705 idr_init(&sess_idr);
706 703
707 ret = target_register_template(&iscsi_ops); 704 ret = target_register_template(&iscsi_ops);
708 if (ret) 705 if (ret)
@@ -4375,10 +4372,7 @@ int iscsit_close_session(struct iscsi_session *sess)
4375 pr_debug("Decremented number of active iSCSI Sessions on" 4372 pr_debug("Decremented number of active iSCSI Sessions on"
4376 " iSCSI TPG: %hu to %u\n", tpg->tpgt, tpg->nsessions); 4373 " iSCSI TPG: %hu to %u\n", tpg->tpgt, tpg->nsessions);
4377 4374
4378 spin_lock(&sess_idr_lock); 4375 ida_free(&sess_ida, sess->session_index);
4379 idr_remove(&sess_idr, sess->session_index);
4380 spin_unlock(&sess_idr_lock);
4381
4382 kfree(sess->sess_ops); 4376 kfree(sess->sess_ops);
4383 sess->sess_ops = NULL; 4377 sess->sess_ops = NULL;
4384 spin_unlock_bh(&se_tpg->session_lock); 4378 spin_unlock_bh(&se_tpg->session_lock);
diff --git a/drivers/target/iscsi/iscsi_target.h b/drivers/target/iscsi/iscsi_target.h
index 42de1843aa40..48bac0acf8c7 100644
--- a/drivers/target/iscsi/iscsi_target.h
+++ b/drivers/target/iscsi/iscsi_target.h
@@ -55,9 +55,7 @@ extern struct kmem_cache *lio_ooo_cache;
55extern struct kmem_cache *lio_qr_cache; 55extern struct kmem_cache *lio_qr_cache;
56extern struct kmem_cache *lio_r2t_cache; 56extern struct kmem_cache *lio_r2t_cache;
57 57
58extern struct idr sess_idr; 58extern struct ida sess_ida;
59extern struct mutex auth_id_lock; 59extern struct mutex auth_id_lock;
60extern spinlock_t sess_idr_lock;
61
62 60
63#endif /*** ISCSI_TARGET_H ***/ 61#endif /*** ISCSI_TARGET_H ***/
diff --git a/drivers/target/iscsi/iscsi_target_login.c b/drivers/target/iscsi/iscsi_target_login.c
index 923b1a9fc3dc..9e74f8bc2963 100644
--- a/drivers/target/iscsi/iscsi_target_login.c
+++ b/drivers/target/iscsi/iscsi_target_login.c
@@ -336,22 +336,15 @@ static int iscsi_login_zero_tsih_s1(
336 timer_setup(&sess->time2retain_timer, 336 timer_setup(&sess->time2retain_timer,
337 iscsit_handle_time2retain_timeout, 0); 337 iscsit_handle_time2retain_timeout, 0);
338 338
339 idr_preload(GFP_KERNEL); 339 ret = ida_alloc(&sess_ida, GFP_KERNEL);
340 spin_lock_bh(&sess_idr_lock);
341 ret = idr_alloc(&sess_idr, NULL, 0, 0, GFP_NOWAIT);
342 if (ret >= 0)
343 sess->session_index = ret;
344 spin_unlock_bh(&sess_idr_lock);
345 idr_preload_end();
346
347 if (ret < 0) { 340 if (ret < 0) {
348 pr_err("idr_alloc() for sess_idr failed\n"); 341 pr_err("Session ID allocation failed %d\n", ret);
349 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR, 342 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
350 ISCSI_LOGIN_STATUS_NO_RESOURCES); 343 ISCSI_LOGIN_STATUS_NO_RESOURCES);
351 kfree(sess); 344 goto free_sess;
352 return -ENOMEM;
353 } 345 }
354 346
347 sess->session_index = ret;
355 sess->creation_time = get_jiffies_64(); 348 sess->creation_time = get_jiffies_64();
356 /* 349 /*
357 * The FFP CmdSN window values will be allocated from the TPG's 350 * The FFP CmdSN window values will be allocated from the TPG's
@@ -365,20 +358,26 @@ static int iscsi_login_zero_tsih_s1(
365 ISCSI_LOGIN_STATUS_NO_RESOURCES); 358 ISCSI_LOGIN_STATUS_NO_RESOURCES);
366 pr_err("Unable to allocate memory for" 359 pr_err("Unable to allocate memory for"
367 " struct iscsi_sess_ops.\n"); 360 " struct iscsi_sess_ops.\n");
368 kfree(sess); 361 goto free_id;
369 return -ENOMEM;
370 } 362 }
371 363
372 sess->se_sess = transport_alloc_session(TARGET_PROT_NORMAL); 364 sess->se_sess = transport_alloc_session(TARGET_PROT_NORMAL);
373 if (IS_ERR(sess->se_sess)) { 365 if (IS_ERR(sess->se_sess)) {
374 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR, 366 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
375 ISCSI_LOGIN_STATUS_NO_RESOURCES); 367 ISCSI_LOGIN_STATUS_NO_RESOURCES);
376 kfree(sess->sess_ops); 368 goto free_ops;
377 kfree(sess);
378 return -ENOMEM;
379 } 369 }
380 370
381 return 0; 371 return 0;
372
373free_ops:
374 kfree(sess->sess_ops);
375free_id:
376 ida_free(&sess_ida, sess->session_index);
377free_sess:
378 kfree(sess);
379 conn->sess = NULL;
380 return -ENOMEM;
382} 381}
383 382
384static int iscsi_login_zero_tsih_s2( 383static int iscsi_login_zero_tsih_s2(
@@ -1161,13 +1160,9 @@ void iscsi_target_login_sess_out(struct iscsi_conn *conn,
1161 ISCSI_LOGIN_STATUS_INIT_ERR); 1160 ISCSI_LOGIN_STATUS_INIT_ERR);
1162 if (!zero_tsih || !conn->sess) 1161 if (!zero_tsih || !conn->sess)
1163 goto old_sess_out; 1162 goto old_sess_out;
1164 if (conn->sess->se_sess) 1163
1165 transport_free_session(conn->sess->se_sess); 1164 transport_free_session(conn->sess->se_sess);
1166 if (conn->sess->session_index != 0) { 1165 ida_free(&sess_ida, conn->sess->session_index);
1167 spin_lock_bh(&sess_idr_lock);
1168 idr_remove(&sess_idr, conn->sess->session_index);
1169 spin_unlock_bh(&sess_idr_lock);
1170 }
1171 kfree(conn->sess->sess_ops); 1166 kfree(conn->sess->sess_ops);
1172 kfree(conn->sess); 1167 kfree(conn->sess);
1173 conn->sess = NULL; 1168 conn->sess = NULL;
diff --git a/fs/devpts/inode.c b/fs/devpts/inode.c
index e072e955ce33..c53814539070 100644
--- a/fs/devpts/inode.c
+++ b/fs/devpts/inode.c
@@ -46,7 +46,7 @@ static int pty_limit = NR_UNIX98_PTY_DEFAULT;
46static int pty_reserve = NR_UNIX98_PTY_RESERVE; 46static int pty_reserve = NR_UNIX98_PTY_RESERVE;
47static int pty_limit_min; 47static int pty_limit_min;
48static int pty_limit_max = INT_MAX; 48static int pty_limit_max = INT_MAX;
49static int pty_count; 49static atomic_t pty_count = ATOMIC_INIT(0);
50 50
51static struct ctl_table pty_table[] = { 51static struct ctl_table pty_table[] = {
52 { 52 {
@@ -93,8 +93,6 @@ static struct ctl_table pty_root_table[] = {
93 {} 93 {}
94}; 94};
95 95
96static DEFINE_MUTEX(allocated_ptys_lock);
97
98struct pts_mount_opts { 96struct pts_mount_opts {
99 int setuid; 97 int setuid;
100 int setgid; 98 int setgid;
@@ -533,44 +531,25 @@ static struct file_system_type devpts_fs_type = {
533 531
534int devpts_new_index(struct pts_fs_info *fsi) 532int devpts_new_index(struct pts_fs_info *fsi)
535{ 533{
536 int index; 534 int index = -ENOSPC;
537 int ida_ret;
538
539retry:
540 if (!ida_pre_get(&fsi->allocated_ptys, GFP_KERNEL))
541 return -ENOMEM;
542
543 mutex_lock(&allocated_ptys_lock);
544 if (pty_count >= (pty_limit -
545 (fsi->mount_opts.reserve ? 0 : pty_reserve))) {
546 mutex_unlock(&allocated_ptys_lock);
547 return -ENOSPC;
548 }
549 535
550 ida_ret = ida_get_new(&fsi->allocated_ptys, &index); 536 if (atomic_inc_return(&pty_count) >= (pty_limit -
551 if (ida_ret < 0) { 537 (fsi->mount_opts.reserve ? 0 : pty_reserve)))
552 mutex_unlock(&allocated_ptys_lock); 538 goto out;
553 if (ida_ret == -EAGAIN)
554 goto retry;
555 return -EIO;
556 }
557 539
558 if (index >= fsi->mount_opts.max) { 540 index = ida_alloc_max(&fsi->allocated_ptys, fsi->mount_opts.max - 1,
559 ida_remove(&fsi->allocated_ptys, index); 541 GFP_KERNEL);
560 mutex_unlock(&allocated_ptys_lock); 542
561 return -ENOSPC; 543out:
562 } 544 if (index < 0)
563 pty_count++; 545 atomic_dec(&pty_count);
564 mutex_unlock(&allocated_ptys_lock);
565 return index; 546 return index;
566} 547}
567 548
568void devpts_kill_index(struct pts_fs_info *fsi, int idx) 549void devpts_kill_index(struct pts_fs_info *fsi, int idx)
569{ 550{
570 mutex_lock(&allocated_ptys_lock); 551 ida_free(&fsi->allocated_ptys, idx);
571 ida_remove(&fsi->allocated_ptys, idx); 552 atomic_dec(&pty_count);
572 pty_count--;
573 mutex_unlock(&allocated_ptys_lock);
574} 553}
575 554
576/** 555/**
diff --git a/fs/namespace.c b/fs/namespace.c
index 725d6935fab9..99186556f8d3 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -61,9 +61,6 @@ __setup("mphash_entries=", set_mphash_entries);
61static u64 event; 61static u64 event;
62static DEFINE_IDA(mnt_id_ida); 62static DEFINE_IDA(mnt_id_ida);
63static DEFINE_IDA(mnt_group_ida); 63static DEFINE_IDA(mnt_group_ida);
64static DEFINE_SPINLOCK(mnt_id_lock);
65static int mnt_id_start = 0;
66static int mnt_group_start = 1;
67 64
68static struct hlist_head *mount_hashtable __read_mostly; 65static struct hlist_head *mount_hashtable __read_mostly;
69static struct hlist_head *mountpoint_hashtable __read_mostly; 66static struct hlist_head *mountpoint_hashtable __read_mostly;
@@ -101,50 +98,30 @@ static inline struct hlist_head *mp_hash(struct dentry *dentry)
101 98
102static int mnt_alloc_id(struct mount *mnt) 99static int mnt_alloc_id(struct mount *mnt)
103{ 100{
104 int res; 101 int res = ida_alloc(&mnt_id_ida, GFP_KERNEL);
105 102
106retry: 103 if (res < 0)
107 ida_pre_get(&mnt_id_ida, GFP_KERNEL); 104 return res;
108 spin_lock(&mnt_id_lock); 105 mnt->mnt_id = res;
109 res = ida_get_new_above(&mnt_id_ida, mnt_id_start, &mnt->mnt_id); 106 return 0;
110 if (!res)
111 mnt_id_start = mnt->mnt_id + 1;
112 spin_unlock(&mnt_id_lock);
113 if (res == -EAGAIN)
114 goto retry;
115
116 return res;
117} 107}
118 108
119static void mnt_free_id(struct mount *mnt) 109static void mnt_free_id(struct mount *mnt)
120{ 110{
121 int id = mnt->mnt_id; 111 ida_free(&mnt_id_ida, mnt->mnt_id);
122 spin_lock(&mnt_id_lock);
123 ida_remove(&mnt_id_ida, id);
124 if (mnt_id_start > id)
125 mnt_id_start = id;
126 spin_unlock(&mnt_id_lock);
127} 112}
128 113
129/* 114/*
130 * Allocate a new peer group ID 115 * Allocate a new peer group ID
131 *
132 * mnt_group_ida is protected by namespace_sem
133 */ 116 */
134static int mnt_alloc_group_id(struct mount *mnt) 117static int mnt_alloc_group_id(struct mount *mnt)
135{ 118{
136 int res; 119 int res = ida_alloc_min(&mnt_group_ida, 1, GFP_KERNEL);
137 120
138 if (!ida_pre_get(&mnt_group_ida, GFP_KERNEL)) 121 if (res < 0)
139 return -ENOMEM; 122 return res;
140 123 mnt->mnt_group_id = res;
141 res = ida_get_new_above(&mnt_group_ida, 124 return 0;
142 mnt_group_start,
143 &mnt->mnt_group_id);
144 if (!res)
145 mnt_group_start = mnt->mnt_group_id + 1;
146
147 return res;
148} 125}
149 126
150/* 127/*
@@ -152,10 +129,7 @@ static int mnt_alloc_group_id(struct mount *mnt)
152 */ 129 */
153void mnt_release_group_id(struct mount *mnt) 130void mnt_release_group_id(struct mount *mnt)
154{ 131{
155 int id = mnt->mnt_group_id; 132 ida_free(&mnt_group_ida, mnt->mnt_group_id);
156 ida_remove(&mnt_group_ida, id);
157 if (mnt_group_start > id)
158 mnt_group_start = id;
159 mnt->mnt_group_id = 0; 133 mnt->mnt_group_id = 0;
160} 134}
161 135
diff --git a/fs/super.c b/fs/super.c
index 7429588d6b49..f3a8c008e164 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -981,58 +981,42 @@ void emergency_thaw_all(void)
981 } 981 }
982} 982}
983 983
984/*
985 * Unnamed block devices are dummy devices used by virtual
986 * filesystems which don't use real block-devices. -- jrs
987 */
988
989static DEFINE_IDA(unnamed_dev_ida); 984static DEFINE_IDA(unnamed_dev_ida);
990static DEFINE_SPINLOCK(unnamed_dev_lock);/* protects the above */
991/* Many userspace utilities consider an FSID of 0 invalid.
992 * Always return at least 1 from get_anon_bdev.
993 */
994static int unnamed_dev_start = 1;
995 985
986/**
987 * get_anon_bdev - Allocate a block device for filesystems which don't have one.
988 * @p: Pointer to a dev_t.
989 *
990 * Filesystems which don't use real block devices can call this function
991 * to allocate a virtual block device.
992 *
993 * Context: Any context. Frequently called while holding sb_lock.
994 * Return: 0 on success, -EMFILE if there are no anonymous bdevs left
995 * or -ENOMEM if memory allocation failed.
996 */
996int get_anon_bdev(dev_t *p) 997int get_anon_bdev(dev_t *p)
997{ 998{
998 int dev; 999 int dev;
999 int error;
1000 1000
1001 retry: 1001 /*
1002 if (ida_pre_get(&unnamed_dev_ida, GFP_ATOMIC) == 0) 1002 * Many userspace utilities consider an FSID of 0 invalid.
1003 return -ENOMEM; 1003 * Always return at least 1 from get_anon_bdev.
1004 spin_lock(&unnamed_dev_lock); 1004 */
1005 error = ida_get_new_above(&unnamed_dev_ida, unnamed_dev_start, &dev); 1005 dev = ida_alloc_range(&unnamed_dev_ida, 1, (1 << MINORBITS) - 1,
1006 if (!error) 1006 GFP_ATOMIC);
1007 unnamed_dev_start = dev + 1; 1007 if (dev == -ENOSPC)
1008 spin_unlock(&unnamed_dev_lock); 1008 dev = -EMFILE;
1009 if (error == -EAGAIN) 1009 if (dev < 0)
1010 /* We raced and lost with another CPU. */ 1010 return dev;
1011 goto retry; 1011
1012 else if (error) 1012 *p = MKDEV(0, dev);
1013 return -EAGAIN;
1014
1015 if (dev >= (1 << MINORBITS)) {
1016 spin_lock(&unnamed_dev_lock);
1017 ida_remove(&unnamed_dev_ida, dev);
1018 if (unnamed_dev_start > dev)
1019 unnamed_dev_start = dev;
1020 spin_unlock(&unnamed_dev_lock);
1021 return -EMFILE;
1022 }
1023 *p = MKDEV(0, dev & MINORMASK);
1024 return 0; 1013 return 0;
1025} 1014}
1026EXPORT_SYMBOL(get_anon_bdev); 1015EXPORT_SYMBOL(get_anon_bdev);
1027 1016
1028void free_anon_bdev(dev_t dev) 1017void free_anon_bdev(dev_t dev)
1029{ 1018{
1030 int slot = MINOR(dev); 1019 ida_free(&unnamed_dev_ida, MINOR(dev));
1031 spin_lock(&unnamed_dev_lock);
1032 ida_remove(&unnamed_dev_ida, slot);
1033 if (slot < unnamed_dev_start)
1034 unnamed_dev_start = slot;
1035 spin_unlock(&unnamed_dev_lock);
1036} 1020}
1037EXPORT_SYMBOL(free_anon_bdev); 1021EXPORT_SYMBOL(free_anon_bdev);
1038 1022
@@ -1040,7 +1024,6 @@ int set_anon_super(struct super_block *s, void *data)
1040{ 1024{
1041 return get_anon_bdev(&s->s_dev); 1025 return get_anon_bdev(&s->s_dev);
1042} 1026}
1043
1044EXPORT_SYMBOL(set_anon_super); 1027EXPORT_SYMBOL(set_anon_super);
1045 1028
1046void kill_anon_super(struct super_block *sb) 1029void kill_anon_super(struct super_block *sb)
@@ -1049,7 +1032,6 @@ void kill_anon_super(struct super_block *sb)
1049 generic_shutdown_super(sb); 1032 generic_shutdown_super(sb);
1050 free_anon_bdev(dev); 1033 free_anon_bdev(dev);
1051} 1034}
1052
1053EXPORT_SYMBOL(kill_anon_super); 1035EXPORT_SYMBOL(kill_anon_super);
1054 1036
1055void kill_litter_super(struct super_block *sb) 1037void kill_litter_super(struct super_block *sb)
@@ -1058,7 +1040,6 @@ void kill_litter_super(struct super_block *sb)
1058 d_genocide(sb->s_root); 1040 d_genocide(sb->s_root);
1059 kill_anon_super(sb); 1041 kill_anon_super(sb);
1060} 1042}
1061
1062EXPORT_SYMBOL(kill_litter_super); 1043EXPORT_SYMBOL(kill_litter_super);
1063 1044
1064static int ns_test_super(struct super_block *sb, void *data) 1045static int ns_test_super(struct super_block *sb, void *data)
diff --git a/include/linux/idr.h b/include/linux/idr.h
index 3e8215b2c371..3ec8628ce17f 100644
--- a/include/linux/idr.h
+++ b/include/linux/idr.h
@@ -236,34 +236,74 @@ struct ida {
236} 236}
237#define DEFINE_IDA(name) struct ida name = IDA_INIT(name) 237#define DEFINE_IDA(name) struct ida name = IDA_INIT(name)
238 238
239int ida_pre_get(struct ida *ida, gfp_t gfp_mask); 239int ida_alloc_range(struct ida *, unsigned int min, unsigned int max, gfp_t);
240int ida_get_new_above(struct ida *ida, int starting_id, int *p_id); 240void ida_free(struct ida *, unsigned int id);
241void ida_remove(struct ida *ida, int id);
242void ida_destroy(struct ida *ida); 241void ida_destroy(struct ida *ida);
243 242
244int ida_simple_get(struct ida *ida, unsigned int start, unsigned int end, 243/**
245 gfp_t gfp_mask); 244 * ida_alloc() - Allocate an unused ID.
246void ida_simple_remove(struct ida *ida, unsigned int id); 245 * @ida: IDA handle.
246 * @gfp: Memory allocation flags.
247 *
248 * Allocate an ID between 0 and %INT_MAX, inclusive.
249 *
250 * Context: Any context.
251 * Return: The allocated ID, or %-ENOMEM if memory could not be allocated,
252 * or %-ENOSPC if there are no free IDs.
253 */
254static inline int ida_alloc(struct ida *ida, gfp_t gfp)
255{
256 return ida_alloc_range(ida, 0, ~0, gfp);
257}
247 258
248static inline void ida_init(struct ida *ida) 259/**
260 * ida_alloc_min() - Allocate an unused ID.
261 * @ida: IDA handle.
262 * @min: Lowest ID to allocate.
263 * @gfp: Memory allocation flags.
264 *
265 * Allocate an ID between @min and %INT_MAX, inclusive.
266 *
267 * Context: Any context.
268 * Return: The allocated ID, or %-ENOMEM if memory could not be allocated,
269 * or %-ENOSPC if there are no free IDs.
270 */
271static inline int ida_alloc_min(struct ida *ida, unsigned int min, gfp_t gfp)
249{ 272{
250 INIT_RADIX_TREE(&ida->ida_rt, IDR_RT_MARKER | GFP_NOWAIT); 273 return ida_alloc_range(ida, min, ~0, gfp);
251} 274}
252 275
253/** 276/**
254 * ida_get_new - allocate new ID 277 * ida_alloc_max() - Allocate an unused ID.
255 * @ida: idr handle 278 * @ida: IDA handle.
256 * @p_id: pointer to the allocated handle 279 * @max: Highest ID to allocate.
280 * @gfp: Memory allocation flags.
281 *
282 * Allocate an ID between 0 and @max, inclusive.
257 * 283 *
258 * Simple wrapper around ida_get_new_above() w/ @starting_id of zero. 284 * Context: Any context.
285 * Return: The allocated ID, or %-ENOMEM if memory could not be allocated,
286 * or %-ENOSPC if there are no free IDs.
259 */ 287 */
260static inline int ida_get_new(struct ida *ida, int *p_id) 288static inline int ida_alloc_max(struct ida *ida, unsigned int max, gfp_t gfp)
261{ 289{
262 return ida_get_new_above(ida, 0, p_id); 290 return ida_alloc_range(ida, 0, max, gfp);
263} 291}
264 292
293static inline void ida_init(struct ida *ida)
294{
295 INIT_RADIX_TREE(&ida->ida_rt, IDR_RT_MARKER | GFP_NOWAIT);
296}
297
298#define ida_simple_get(ida, start, end, gfp) \
299 ida_alloc_range(ida, start, (end) - 1, gfp)
300#define ida_simple_remove(ida, id) ida_free(ida, id)
301
265static inline bool ida_is_empty(const struct ida *ida) 302static inline bool ida_is_empty(const struct ida *ida)
266{ 303{
267 return radix_tree_empty(&ida->ida_rt); 304 return radix_tree_empty(&ida->ida_rt);
268} 305}
306
307/* in lib/radix-tree.c */
308int ida_pre_get(struct ida *ida, gfp_t gfp_mask);
269#endif /* __IDR_H__ */ 309#endif /* __IDR_H__ */
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 3589765141a8..613316724c6a 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -1833,6 +1833,9 @@ config TEST_HASH
1833 This is intended to help people writing architecture-specific 1833 This is intended to help people writing architecture-specific
1834 optimized versions. If unsure, say N. 1834 optimized versions. If unsure, say N.
1835 1835
1836config TEST_IDA
1837 tristate "Perform selftest on IDA functions"
1838
1836config TEST_PARMAN 1839config TEST_PARMAN
1837 tristate "Perform selftest on priority array manager" 1840 tristate "Perform selftest on priority array manager"
1838 depends on PARMAN 1841 depends on PARMAN
diff --git a/lib/Makefile b/lib/Makefile
index 9baefb6cb1a1..ca3f7ebb900d 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -50,6 +50,7 @@ obj-$(CONFIG_TEST_BPF) += test_bpf.o
50obj-$(CONFIG_TEST_FIRMWARE) += test_firmware.o 50obj-$(CONFIG_TEST_FIRMWARE) += test_firmware.o
51obj-$(CONFIG_TEST_SYSCTL) += test_sysctl.o 51obj-$(CONFIG_TEST_SYSCTL) += test_sysctl.o
52obj-$(CONFIG_TEST_HASH) += test_hash.o test_siphash.o 52obj-$(CONFIG_TEST_HASH) += test_hash.o test_siphash.o
53obj-$(CONFIG_TEST_IDA) += test_ida.o
53obj-$(CONFIG_TEST_KASAN) += test_kasan.o 54obj-$(CONFIG_TEST_KASAN) += test_kasan.o
54CFLAGS_test_kasan.o += -fno-builtin 55CFLAGS_test_kasan.o += -fno-builtin
55obj-$(CONFIG_TEST_UBSAN) += test_ubsan.o 56obj-$(CONFIG_TEST_UBSAN) += test_ubsan.o
diff --git a/lib/idr.c b/lib/idr.c
index ed9c169c12bd..fab2fd5bc326 100644
--- a/lib/idr.c
+++ b/lib/idr.c
@@ -317,18 +317,12 @@ EXPORT_SYMBOL(idr_replace);
317 * bit per ID, and so is more space efficient than an IDR. To use an IDA, 317 * bit per ID, and so is more space efficient than an IDR. To use an IDA,
318 * define it using DEFINE_IDA() (or embed a &struct ida in a data structure, 318 * define it using DEFINE_IDA() (or embed a &struct ida in a data structure,
319 * then initialise it using ida_init()). To allocate a new ID, call 319 * then initialise it using ida_init()). To allocate a new ID, call
320 * ida_simple_get(). To free an ID, call ida_simple_remove(). 320 * ida_alloc(), ida_alloc_min(), ida_alloc_max() or ida_alloc_range().
321 * To free an ID, call ida_free().
321 * 322 *
322 * If you have more complex locking requirements, use a loop around 323 * ida_destroy() can be used to dispose of an IDA without needing to
323 * ida_pre_get() and ida_get_new() to allocate a new ID. Then use 324 * free the individual IDs in it. You can use ida_is_empty() to find
324 * ida_remove() to free an ID. You must make sure that ida_get_new() and 325 * out whether the IDA has any IDs currently allocated.
325 * ida_remove() cannot be called at the same time as each other for the
326 * same IDA.
327 *
328 * You can also use ida_get_new_above() if you need an ID to be allocated
329 * above a particular number. ida_destroy() can be used to dispose of an
330 * IDA without needing to free the individual IDs in it. You can use
331 * ida_is_empty() to find out whether the IDA has any IDs currently allocated.
332 * 326 *
333 * IDs are currently limited to the range [0-INT_MAX]. If this is an awkward 327 * IDs are currently limited to the range [0-INT_MAX]. If this is an awkward
334 * limitation, it should be quite straightforward to raise the maximum. 328 * limitation, it should be quite straightforward to raise the maximum.
@@ -369,25 +363,7 @@ EXPORT_SYMBOL(idr_replace);
369 363
370#define IDA_MAX (0x80000000U / IDA_BITMAP_BITS - 1) 364#define IDA_MAX (0x80000000U / IDA_BITMAP_BITS - 1)
371 365
372/** 366static int ida_get_new_above(struct ida *ida, int start)
373 * ida_get_new_above - allocate new ID above or equal to a start id
374 * @ida: ida handle
375 * @start: id to start search at
376 * @id: pointer to the allocated handle
377 *
378 * Allocate new ID above or equal to @start. It should be called
379 * with any required locks to ensure that concurrent calls to
380 * ida_get_new_above() / ida_get_new() / ida_remove() are not allowed.
381 * Consider using ida_simple_get() if you do not have complex locking
382 * requirements.
383 *
384 * If memory is required, it will return %-EAGAIN, you should unlock
385 * and go back to the ida_pre_get() call. If the ida is full, it will
386 * return %-ENOSPC. On success, it will return 0.
387 *
388 * @id returns a value in the range @start ... %0x7fffffff.
389 */
390int ida_get_new_above(struct ida *ida, int start, int *id)
391{ 367{
392 struct radix_tree_root *root = &ida->ida_rt; 368 struct radix_tree_root *root = &ida->ida_rt;
393 void __rcu **slot; 369 void __rcu **slot;
@@ -426,8 +402,8 @@ int ida_get_new_above(struct ida *ida, int start, int *id)
426 if (ebit < BITS_PER_LONG) { 402 if (ebit < BITS_PER_LONG) {
427 tmp |= 1UL << ebit; 403 tmp |= 1UL << ebit;
428 rcu_assign_pointer(*slot, (void *)tmp); 404 rcu_assign_pointer(*slot, (void *)tmp);
429 *id = new + ebit - RADIX_TREE_EXCEPTIONAL_SHIFT; 405 return new + ebit -
430 return 0; 406 RADIX_TREE_EXCEPTIONAL_SHIFT;
431 } 407 }
432 bitmap = this_cpu_xchg(ida_bitmap, NULL); 408 bitmap = this_cpu_xchg(ida_bitmap, NULL);
433 if (!bitmap) 409 if (!bitmap)
@@ -458,8 +434,7 @@ int ida_get_new_above(struct ida *ida, int start, int *id)
458 RADIX_TREE_EXCEPTIONAL_ENTRY); 434 RADIX_TREE_EXCEPTIONAL_ENTRY);
459 radix_tree_iter_replace(root, &iter, slot, 435 radix_tree_iter_replace(root, &iter, slot,
460 bitmap); 436 bitmap);
461 *id = new; 437 return new;
462 return 0;
463 } 438 }
464 bitmap = this_cpu_xchg(ida_bitmap, NULL); 439 bitmap = this_cpu_xchg(ida_bitmap, NULL);
465 if (!bitmap) 440 if (!bitmap)
@@ -468,20 +443,11 @@ int ida_get_new_above(struct ida *ida, int start, int *id)
468 radix_tree_iter_replace(root, &iter, slot, bitmap); 443 radix_tree_iter_replace(root, &iter, slot, bitmap);
469 } 444 }
470 445
471 *id = new; 446 return new;
472 return 0;
473 } 447 }
474} 448}
475EXPORT_SYMBOL(ida_get_new_above);
476 449
477/** 450static void ida_remove(struct ida *ida, int id)
478 * ida_remove - Free the given ID
479 * @ida: ida handle
480 * @id: ID to free
481 *
482 * This function should not be called at the same time as ida_get_new_above().
483 */
484void ida_remove(struct ida *ida, int id)
485{ 451{
486 unsigned long index = id / IDA_BITMAP_BITS; 452 unsigned long index = id / IDA_BITMAP_BITS;
487 unsigned offset = id % IDA_BITMAP_BITS; 453 unsigned offset = id % IDA_BITMAP_BITS;
@@ -518,99 +484,90 @@ void ida_remove(struct ida *ida, int id)
518 } 484 }
519 return; 485 return;
520 err: 486 err:
521 WARN(1, "ida_remove called for id=%d which is not allocated.\n", id); 487 WARN(1, "ida_free called for id=%d which is not allocated.\n", id);
522} 488}
523EXPORT_SYMBOL(ida_remove);
524 489
525/** 490/**
526 * ida_destroy - Free the contents of an ida 491 * ida_destroy() - Free all IDs.
527 * @ida: ida handle 492 * @ida: IDA handle.
493 *
494 * Calling this function frees all IDs and releases all resources used
495 * by an IDA. When this call returns, the IDA is empty and can be reused
496 * or freed. If the IDA is already empty, there is no need to call this
497 * function.
528 * 498 *
529 * Calling this function releases all resources associated with an IDA. When 499 * Context: Any context.
530 * this call returns, the IDA is empty and can be reused or freed. The caller
531 * should not allow ida_remove() or ida_get_new_above() to be called at the
532 * same time.
533 */ 500 */
534void ida_destroy(struct ida *ida) 501void ida_destroy(struct ida *ida)
535{ 502{
503 unsigned long flags;
536 struct radix_tree_iter iter; 504 struct radix_tree_iter iter;
537 void __rcu **slot; 505 void __rcu **slot;
538 506
507 xa_lock_irqsave(&ida->ida_rt, flags);
539 radix_tree_for_each_slot(slot, &ida->ida_rt, &iter, 0) { 508 radix_tree_for_each_slot(slot, &ida->ida_rt, &iter, 0) {
540 struct ida_bitmap *bitmap = rcu_dereference_raw(*slot); 509 struct ida_bitmap *bitmap = rcu_dereference_raw(*slot);
541 if (!radix_tree_exception(bitmap)) 510 if (!radix_tree_exception(bitmap))
542 kfree(bitmap); 511 kfree(bitmap);
543 radix_tree_iter_delete(&ida->ida_rt, &iter, slot); 512 radix_tree_iter_delete(&ida->ida_rt, &iter, slot);
544 } 513 }
514 xa_unlock_irqrestore(&ida->ida_rt, flags);
545} 515}
546EXPORT_SYMBOL(ida_destroy); 516EXPORT_SYMBOL(ida_destroy);
547 517
548/** 518/**
549 * ida_simple_get - get a new id. 519 * ida_alloc_range() - Allocate an unused ID.
550 * @ida: the (initialized) ida. 520 * @ida: IDA handle.
551 * @start: the minimum id (inclusive, < 0x8000000) 521 * @min: Lowest ID to allocate.
552 * @end: the maximum id (exclusive, < 0x8000000 or 0) 522 * @max: Highest ID to allocate.
553 * @gfp_mask: memory allocation flags 523 * @gfp: Memory allocation flags.
554 *
555 * Allocates an id in the range start <= id < end, or returns -ENOSPC.
556 * On memory allocation failure, returns -ENOMEM.
557 * 524 *
558 * Compared to ida_get_new_above() this function does its own locking, and 525 * Allocate an ID between @min and @max, inclusive. The allocated ID will
559 * should be used unless there are special requirements. 526 * not exceed %INT_MAX, even if @max is larger.
560 * 527 *
561 * Use ida_simple_remove() to get rid of an id. 528 * Context: Any context.
529 * Return: The allocated ID, or %-ENOMEM if memory could not be allocated,
530 * or %-ENOSPC if there are no free IDs.
562 */ 531 */
563int ida_simple_get(struct ida *ida, unsigned int start, unsigned int end, 532int ida_alloc_range(struct ida *ida, unsigned int min, unsigned int max,
564 gfp_t gfp_mask) 533 gfp_t gfp)
565{ 534{
566 int ret, id; 535 int id = 0;
567 unsigned int max;
568 unsigned long flags; 536 unsigned long flags;
569 537
570 BUG_ON((int)start < 0); 538 if ((int)min < 0)
571 BUG_ON((int)end < 0); 539 return -ENOSPC;
572 540
573 if (end == 0) 541 if ((int)max < 0)
574 max = 0x80000000; 542 max = INT_MAX;
575 else {
576 BUG_ON(end < start);
577 max = end - 1;
578 }
579 543
580again: 544again:
581 if (!ida_pre_get(ida, gfp_mask))
582 return -ENOMEM;
583
584 xa_lock_irqsave(&ida->ida_rt, flags); 545 xa_lock_irqsave(&ida->ida_rt, flags);
585 ret = ida_get_new_above(ida, start, &id); 546 id = ida_get_new_above(ida, min);
586 if (!ret) { 547 if (id > (int)max) {
587 if (id > max) { 548 ida_remove(ida, id);
588 ida_remove(ida, id); 549 id = -ENOSPC;
589 ret = -ENOSPC;
590 } else {
591 ret = id;
592 }
593 } 550 }
594 xa_unlock_irqrestore(&ida->ida_rt, flags); 551 xa_unlock_irqrestore(&ida->ida_rt, flags);
595 552
596 if (unlikely(ret == -EAGAIN)) 553 if (unlikely(id == -EAGAIN)) {
554 if (!ida_pre_get(ida, gfp))
555 return -ENOMEM;
597 goto again; 556 goto again;
557 }
598 558
599 return ret; 559 return id;
600} 560}
601EXPORT_SYMBOL(ida_simple_get); 561EXPORT_SYMBOL(ida_alloc_range);
602 562
603/** 563/**
604 * ida_simple_remove - remove an allocated id. 564 * ida_free() - Release an allocated ID.
605 * @ida: the (initialized) ida. 565 * @ida: IDA handle.
606 * @id: the id returned by ida_simple_get. 566 * @id: Previously allocated ID.
607 *
608 * Use to release an id allocated with ida_simple_get().
609 * 567 *
610 * Compared to ida_remove() this function does its own locking, and should be 568 * Context: Any context.
611 * used unless there are special requirements.
612 */ 569 */
613void ida_simple_remove(struct ida *ida, unsigned int id) 570void ida_free(struct ida *ida, unsigned int id)
614{ 571{
615 unsigned long flags; 572 unsigned long flags;
616 573
@@ -619,4 +576,4 @@ void ida_simple_remove(struct ida *ida, unsigned int id)
619 ida_remove(ida, id); 576 ida_remove(ida, id);
620 xa_unlock_irqrestore(&ida->ida_rt, flags); 577 xa_unlock_irqrestore(&ida->ida_rt, flags);
621} 578}
622EXPORT_SYMBOL(ida_simple_remove); 579EXPORT_SYMBOL(ida_free);
diff --git a/lib/radix-tree.c b/lib/radix-tree.c
index a9e41aed6de4..bc03ecc4dfd2 100644
--- a/lib/radix-tree.c
+++ b/lib/radix-tree.c
@@ -120,7 +120,7 @@ bool is_sibling_entry(const struct radix_tree_node *parent, void *node)
120static inline unsigned long 120static inline unsigned long
121get_slot_offset(const struct radix_tree_node *parent, void __rcu **slot) 121get_slot_offset(const struct radix_tree_node *parent, void __rcu **slot)
122{ 122{
123 return slot - parent->slots; 123 return parent ? slot - parent->slots : 0;
124} 124}
125 125
126static unsigned int radix_tree_descend(const struct radix_tree_node *parent, 126static unsigned int radix_tree_descend(const struct radix_tree_node *parent,
@@ -2106,14 +2106,6 @@ void idr_preload(gfp_t gfp_mask)
2106} 2106}
2107EXPORT_SYMBOL(idr_preload); 2107EXPORT_SYMBOL(idr_preload);
2108 2108
2109/**
2110 * ida_pre_get - reserve resources for ida allocation
2111 * @ida: ida handle
2112 * @gfp: memory allocation flags
2113 *
2114 * This function should be called before calling ida_get_new_above(). If it
2115 * is unable to allocate memory, it will return %0. On success, it returns %1.
2116 */
2117int ida_pre_get(struct ida *ida, gfp_t gfp) 2109int ida_pre_get(struct ida *ida, gfp_t gfp)
2118{ 2110{
2119 /* 2111 /*
@@ -2134,7 +2126,6 @@ int ida_pre_get(struct ida *ida, gfp_t gfp)
2134 2126
2135 return 1; 2127 return 1;
2136} 2128}
2137EXPORT_SYMBOL(ida_pre_get);
2138 2129
2139void __rcu **idr_get_free(struct radix_tree_root *root, 2130void __rcu **idr_get_free(struct radix_tree_root *root,
2140 struct radix_tree_iter *iter, gfp_t gfp, 2131 struct radix_tree_iter *iter, gfp_t gfp,
diff --git a/lib/test_ida.c b/lib/test_ida.c
new file mode 100644
index 000000000000..2d1637d8136b
--- /dev/null
+++ b/lib/test_ida.c
@@ -0,0 +1,177 @@
1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * test_ida.c: Test the IDA API
4 * Copyright (c) 2016-2018 Microsoft Corporation
5 * Copyright (c) 2018 Oracle Corporation
6 * Author: Matthew Wilcox <willy@infradead.org>
7 */
8
9#include <linux/idr.h>
10#include <linux/module.h>
11
12static unsigned int tests_run;
13static unsigned int tests_passed;
14
15#ifdef __KERNEL__
16void ida_dump(struct ida *ida) { }
17#endif
18#define IDA_BUG_ON(ida, x) do { \
19 tests_run++; \
20 if (x) { \
21 ida_dump(ida); \
22 dump_stack(); \
23 } else { \
24 tests_passed++; \
25 } \
26} while (0)
27
28/*
29 * Straightforward checks that allocating and freeing IDs work.
30 */
31static void ida_check_alloc(struct ida *ida)
32{
33 int i, id;
34
35 for (i = 0; i < 10000; i++)
36 IDA_BUG_ON(ida, ida_alloc(ida, GFP_KERNEL) != i);
37
38 ida_free(ida, 20);
39 ida_free(ida, 21);
40 for (i = 0; i < 3; i++) {
41 id = ida_alloc(ida, GFP_KERNEL);
42 IDA_BUG_ON(ida, id < 0);
43 if (i == 2)
44 IDA_BUG_ON(ida, id != 10000);
45 }
46
47 for (i = 0; i < 5000; i++)
48 ida_free(ida, i);
49
50 IDA_BUG_ON(ida, ida_alloc_min(ida, 5000, GFP_KERNEL) != 10001);
51 ida_destroy(ida);
52
53 IDA_BUG_ON(ida, !ida_is_empty(ida));
54}
55
56/* Destroy an IDA with a single entry at @base */
57static void ida_check_destroy_1(struct ida *ida, unsigned int base)
58{
59 IDA_BUG_ON(ida, ida_alloc_min(ida, base, GFP_KERNEL) != base);
60 IDA_BUG_ON(ida, ida_is_empty(ida));
61 ida_destroy(ida);
62 IDA_BUG_ON(ida, !ida_is_empty(ida));
63}
64
65/* Check that ida_destroy and ida_is_empty work */
66static void ida_check_destroy(struct ida *ida)
67{
68 /* Destroy an already-empty IDA */
69 IDA_BUG_ON(ida, !ida_is_empty(ida));
70 ida_destroy(ida);
71 IDA_BUG_ON(ida, !ida_is_empty(ida));
72
73 ida_check_destroy_1(ida, 0);
74 ida_check_destroy_1(ida, 1);
75 ida_check_destroy_1(ida, 1023);
76 ida_check_destroy_1(ida, 1024);
77 ida_check_destroy_1(ida, 12345678);
78}
79
80/*
81 * Check what happens when we fill a leaf and then delete it. This may
82 * discover mishandling of IDR_FREE.
83 */
84static void ida_check_leaf(struct ida *ida, unsigned int base)
85{
86 unsigned long i;
87
88 for (i = 0; i < IDA_BITMAP_BITS; i++) {
89 IDA_BUG_ON(ida, ida_alloc_min(ida, base, GFP_KERNEL) !=
90 base + i);
91 }
92
93 ida_destroy(ida);
94 IDA_BUG_ON(ida, !ida_is_empty(ida));
95
96 IDA_BUG_ON(ida, ida_alloc(ida, GFP_KERNEL) != 0);
97 IDA_BUG_ON(ida, ida_is_empty(ida));
98 ida_free(ida, 0);
99 IDA_BUG_ON(ida, !ida_is_empty(ida));
100}
101
102/*
103 * Check allocations up to and slightly above the maximum allowed (2^31-1) ID.
104 * Allocating up to 2^31-1 should succeed, and then allocating the next one
105 * should fail.
106 */
107static void ida_check_max(struct ida *ida)
108{
109 unsigned long i, j;
110
111 for (j = 1; j < 65537; j *= 2) {
112 unsigned long base = (1UL << 31) - j;
113 for (i = 0; i < j; i++) {
114 IDA_BUG_ON(ida, ida_alloc_min(ida, base, GFP_KERNEL) !=
115 base + i);
116 }
117 IDA_BUG_ON(ida, ida_alloc_min(ida, base, GFP_KERNEL) !=
118 -ENOSPC);
119 ida_destroy(ida);
120 IDA_BUG_ON(ida, !ida_is_empty(ida));
121 }
122}
123
124/*
125 * Check handling of conversions between exceptional entries and full bitmaps.
126 */
127static void ida_check_conv(struct ida *ida)
128{
129 unsigned long i;
130
131 for (i = 0; i < IDA_BITMAP_BITS * 2; i += IDA_BITMAP_BITS) {
132 IDA_BUG_ON(ida, ida_alloc_min(ida, i + 1, GFP_KERNEL) != i + 1);
133 IDA_BUG_ON(ida, ida_alloc_min(ida, i + BITS_PER_LONG,
134 GFP_KERNEL) != i + BITS_PER_LONG);
135 ida_free(ida, i + 1);
136 ida_free(ida, i + BITS_PER_LONG);
137 IDA_BUG_ON(ida, !ida_is_empty(ida));
138 }
139
140 for (i = 0; i < IDA_BITMAP_BITS * 2; i++)
141 IDA_BUG_ON(ida, ida_alloc(ida, GFP_KERNEL) != i);
142 for (i = IDA_BITMAP_BITS * 2; i > 0; i--)
143 ida_free(ida, i - 1);
144 IDA_BUG_ON(ida, !ida_is_empty(ida));
145
146 for (i = 0; i < IDA_BITMAP_BITS + BITS_PER_LONG - 4; i++)
147 IDA_BUG_ON(ida, ida_alloc(ida, GFP_KERNEL) != i);
148 for (i = IDA_BITMAP_BITS + BITS_PER_LONG - 4; i > 0; i--)
149 ida_free(ida, i - 1);
150 IDA_BUG_ON(ida, !ida_is_empty(ida));
151}
152
153static int ida_checks(void)
154{
155 DEFINE_IDA(ida);
156
157 IDA_BUG_ON(&ida, !ida_is_empty(&ida));
158 ida_check_alloc(&ida);
159 ida_check_destroy(&ida);
160 ida_check_leaf(&ida, 0);
161 ida_check_leaf(&ida, 1024);
162 ida_check_leaf(&ida, 1024 * 64);
163 ida_check_max(&ida);
164 ida_check_conv(&ida);
165
166 printk("IDA: %u of %u tests passed\n", tests_passed, tests_run);
167 return (tests_run != tests_passed) ? 0 : -EINVAL;
168}
169
170static void ida_exit(void)
171{
172}
173
174module_init(ida_checks);
175module_exit(ida_exit);
176MODULE_AUTHOR("Matthew Wilcox <willy@infradead.org>");
177MODULE_LICENSE("GPL");
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c
index 738871af5efa..670c84b1bfc2 100644
--- a/net/core/net_namespace.c
+++ b/net/core/net_namespace.c
@@ -1001,22 +1001,18 @@ static int register_pernet_operations(struct list_head *list,
1001 int error; 1001 int error;
1002 1002
1003 if (ops->id) { 1003 if (ops->id) {
1004again: 1004 error = ida_alloc_min(&net_generic_ids, MIN_PERNET_OPS_ID,
1005 error = ida_get_new_above(&net_generic_ids, MIN_PERNET_OPS_ID, ops->id); 1005 GFP_KERNEL);
1006 if (error < 0) { 1006 if (error < 0)
1007 if (error == -EAGAIN) {
1008 ida_pre_get(&net_generic_ids, GFP_KERNEL);
1009 goto again;
1010 }
1011 return error; 1007 return error;
1012 } 1008 *ops->id = error;
1013 max_gen_ptrs = max(max_gen_ptrs, *ops->id + 1); 1009 max_gen_ptrs = max(max_gen_ptrs, *ops->id + 1);
1014 } 1010 }
1015 error = __register_pernet_operations(list, ops); 1011 error = __register_pernet_operations(list, ops);
1016 if (error) { 1012 if (error) {
1017 rcu_barrier(); 1013 rcu_barrier();
1018 if (ops->id) 1014 if (ops->id)
1019 ida_remove(&net_generic_ids, *ops->id); 1015 ida_free(&net_generic_ids, *ops->id);
1020 } 1016 }
1021 1017
1022 return error; 1018 return error;
@@ -1027,7 +1023,7 @@ static void unregister_pernet_operations(struct pernet_operations *ops)
1027 __unregister_pernet_operations(ops); 1023 __unregister_pernet_operations(ops);
1028 rcu_barrier(); 1024 rcu_barrier();
1029 if (ops->id) 1025 if (ops->id)
1030 ida_remove(&net_generic_ids, *ops->id); 1026 ida_free(&net_generic_ids, *ops->id);
1031} 1027}
1032 1028
1033/** 1029/**
diff --git a/tools/testing/radix-tree/Makefile b/tools/testing/radix-tree/Makefile
index db66f8a0d4be..37baecc3766f 100644
--- a/tools/testing/radix-tree/Makefile
+++ b/tools/testing/radix-tree/Makefile
@@ -1,7 +1,8 @@
1# SPDX-License-Identifier: GPL-2.0 1# SPDX-License-Identifier: GPL-2.0
2 2
3CFLAGS += -I. -I../../include -g -O2 -Wall -D_LGPL_SOURCE -fsanitize=address 3CFLAGS += -I. -I../../include -g -Og -Wall -D_LGPL_SOURCE -fsanitize=address \
4LDFLAGS += -fsanitize=address 4 -fsanitize=undefined
5LDFLAGS += -fsanitize=address -fsanitize=undefined
5LDLIBS+= -lpthread -lurcu 6LDLIBS+= -lpthread -lurcu
6TARGETS = main idr-test multiorder 7TARGETS = main idr-test multiorder
7CORE_OFILES := radix-tree.o idr.o linux.o test.o find_bit.o 8CORE_OFILES := radix-tree.o idr.o linux.o test.o find_bit.o
@@ -21,6 +22,7 @@ targets: generated/map-shift.h $(TARGETS)
21 22
22main: $(OFILES) 23main: $(OFILES)
23 24
25idr-test.o: ../../../lib/test_ida.c
24idr-test: idr-test.o $(CORE_OFILES) 26idr-test: idr-test.o $(CORE_OFILES)
25 27
26multiorder: multiorder.o $(CORE_OFILES) 28multiorder: multiorder.o $(CORE_OFILES)
diff --git a/tools/testing/radix-tree/idr-test.c b/tools/testing/radix-tree/idr-test.c
index ee820fcc29b0..321ba92c70d2 100644
--- a/tools/testing/radix-tree/idr-test.c
+++ b/tools/testing/radix-tree/idr-test.c
@@ -309,141 +309,61 @@ void idr_checks(void)
309 idr_u32_test(0); 309 idr_u32_test(0);
310} 310}
311 311
312#define module_init(x)
313#define module_exit(x)
314#define MODULE_AUTHOR(x)
315#define MODULE_LICENSE(x)
316#define dump_stack() assert(0)
317void ida_dump(struct ida *);
318
319#include "../../../lib/test_ida.c"
320
312/* 321/*
313 * Check that we get the correct error when we run out of memory doing 322 * Check that we get the correct error when we run out of memory doing
314 * allocations. To ensure we run out of memory, just "forget" to preload. 323 * allocations. In userspace, GFP_NOWAIT will always fail an allocation.
315 * The first test is for not having a bitmap available, and the second test 324 * The first test is for not having a bitmap available, and the second test
316 * is for not being able to allocate a level of the radix tree. 325 * is for not being able to allocate a level of the radix tree.
317 */ 326 */
318void ida_check_nomem(void) 327void ida_check_nomem(void)
319{ 328{
320 DEFINE_IDA(ida); 329 DEFINE_IDA(ida);
321 int id, err;
322
323 err = ida_get_new_above(&ida, 256, &id);
324 assert(err == -EAGAIN);
325 err = ida_get_new_above(&ida, 1UL << 30, &id);
326 assert(err == -EAGAIN);
327}
328
329/*
330 * Check what happens when we fill a leaf and then delete it. This may
331 * discover mishandling of IDR_FREE.
332 */
333void ida_check_leaf(void)
334{
335 DEFINE_IDA(ida);
336 int id; 330 int id;
337 unsigned long i;
338 331
339 for (i = 0; i < IDA_BITMAP_BITS; i++) { 332 id = ida_alloc_min(&ida, 256, GFP_NOWAIT);
340 assert(ida_pre_get(&ida, GFP_KERNEL)); 333 IDA_BUG_ON(&ida, id != -ENOMEM);
341 assert(!ida_get_new(&ida, &id)); 334 id = ida_alloc_min(&ida, 1UL << 30, GFP_NOWAIT);
342 assert(id == i); 335 IDA_BUG_ON(&ida, id != -ENOMEM);
343 } 336 IDA_BUG_ON(&ida, !ida_is_empty(&ida));
344
345 ida_destroy(&ida);
346 assert(ida_is_empty(&ida));
347
348 assert(ida_pre_get(&ida, GFP_KERNEL));
349 assert(!ida_get_new(&ida, &id));
350 assert(id == 0);
351 ida_destroy(&ida);
352 assert(ida_is_empty(&ida));
353} 337}
354 338
355/* 339/*
356 * Check handling of conversions between exceptional entries and full bitmaps. 340 * Check handling of conversions between exceptional entries and full bitmaps.
357 */ 341 */
358void ida_check_conv(void) 342void ida_check_conv_user(void)
359{ 343{
360 DEFINE_IDA(ida); 344 DEFINE_IDA(ida);
361 int id;
362 unsigned long i; 345 unsigned long i;
363 346
364 for (i = 0; i < IDA_BITMAP_BITS * 2; i += IDA_BITMAP_BITS) {
365 assert(ida_pre_get(&ida, GFP_KERNEL));
366 assert(!ida_get_new_above(&ida, i + 1, &id));
367 assert(id == i + 1);
368 assert(!ida_get_new_above(&ida, i + BITS_PER_LONG, &id));
369 assert(id == i + BITS_PER_LONG);
370 ida_remove(&ida, i + 1);
371 ida_remove(&ida, i + BITS_PER_LONG);
372 assert(ida_is_empty(&ida));
373 }
374
375 assert(ida_pre_get(&ida, GFP_KERNEL));
376
377 for (i = 0; i < IDA_BITMAP_BITS * 2; i++) {
378 assert(ida_pre_get(&ida, GFP_KERNEL));
379 assert(!ida_get_new(&ida, &id));
380 assert(id == i);
381 }
382
383 for (i = IDA_BITMAP_BITS * 2; i > 0; i--) {
384 ida_remove(&ida, i - 1);
385 }
386 assert(ida_is_empty(&ida));
387
388 for (i = 0; i < IDA_BITMAP_BITS + BITS_PER_LONG - 4; i++) {
389 assert(ida_pre_get(&ida, GFP_KERNEL));
390 assert(!ida_get_new(&ida, &id));
391 assert(id == i);
392 }
393
394 for (i = IDA_BITMAP_BITS + BITS_PER_LONG - 4; i > 0; i--) {
395 ida_remove(&ida, i - 1);
396 }
397 assert(ida_is_empty(&ida));
398
399 radix_tree_cpu_dead(1); 347 radix_tree_cpu_dead(1);
400 for (i = 0; i < 1000000; i++) { 348 for (i = 0; i < 1000000; i++) {
401 int err = ida_get_new(&ida, &id); 349 int id = ida_alloc(&ida, GFP_NOWAIT);
402 if (err == -EAGAIN) { 350 if (id == -ENOMEM) {
403 assert((i % IDA_BITMAP_BITS) == (BITS_PER_LONG - 2)); 351 IDA_BUG_ON(&ida, (i % IDA_BITMAP_BITS) !=
404 assert(ida_pre_get(&ida, GFP_KERNEL)); 352 BITS_PER_LONG - 2);
405 err = ida_get_new(&ida, &id); 353 id = ida_alloc(&ida, GFP_KERNEL);
406 } else { 354 } else {
407 assert((i % IDA_BITMAP_BITS) != (BITS_PER_LONG - 2)); 355 IDA_BUG_ON(&ida, (i % IDA_BITMAP_BITS) ==
356 BITS_PER_LONG - 2);
408 } 357 }
409 assert(!err); 358 IDA_BUG_ON(&ida, id != i);
410 assert(id == i);
411 } 359 }
412 ida_destroy(&ida); 360 ida_destroy(&ida);
413} 361}
414 362
415/*
416 * Check allocations up to and slightly above the maximum allowed (2^31-1) ID.
417 * Allocating up to 2^31-1 should succeed, and then allocating the next one
418 * should fail.
419 */
420void ida_check_max(void)
421{
422 DEFINE_IDA(ida);
423 int id, err;
424 unsigned long i, j;
425
426 for (j = 1; j < 65537; j *= 2) {
427 unsigned long base = (1UL << 31) - j;
428 for (i = 0; i < j; i++) {
429 assert(ida_pre_get(&ida, GFP_KERNEL));
430 assert(!ida_get_new_above(&ida, base, &id));
431 assert(id == base + i);
432 }
433 assert(ida_pre_get(&ida, GFP_KERNEL));
434 err = ida_get_new_above(&ida, base, &id);
435 assert(err == -ENOSPC);
436 ida_destroy(&ida);
437 assert(ida_is_empty(&ida));
438 rcu_barrier();
439 }
440}
441
442void ida_check_random(void) 363void ida_check_random(void)
443{ 364{
444 DEFINE_IDA(ida); 365 DEFINE_IDA(ida);
445 DECLARE_BITMAP(bitmap, 2048); 366 DECLARE_BITMAP(bitmap, 2048);
446 int id, err;
447 unsigned int i; 367 unsigned int i;
448 time_t s = time(NULL); 368 time_t s = time(NULL);
449 369
@@ -454,15 +374,11 @@ void ida_check_random(void)
454 int bit = i & 2047; 374 int bit = i & 2047;
455 if (test_bit(bit, bitmap)) { 375 if (test_bit(bit, bitmap)) {
456 __clear_bit(bit, bitmap); 376 __clear_bit(bit, bitmap);
457 ida_remove(&ida, bit); 377 ida_free(&ida, bit);
458 } else { 378 } else {
459 __set_bit(bit, bitmap); 379 __set_bit(bit, bitmap);
460 do { 380 IDA_BUG_ON(&ida, ida_alloc_min(&ida, bit, GFP_KERNEL)
461 ida_pre_get(&ida, GFP_KERNEL); 381 != bit);
462 err = ida_get_new_above(&ida, bit, &id);
463 } while (err == -EAGAIN);
464 assert(!err);
465 assert(id == bit);
466 } 382 }
467 } 383 }
468 ida_destroy(&ida); 384 ida_destroy(&ida);
@@ -488,71 +404,12 @@ void ida_simple_get_remove_test(void)
488 ida_destroy(&ida); 404 ida_destroy(&ida);
489} 405}
490 406
491void ida_checks(void) 407void user_ida_checks(void)
492{ 408{
493 DEFINE_IDA(ida);
494 int id;
495 unsigned long i;
496
497 radix_tree_cpu_dead(1); 409 radix_tree_cpu_dead(1);
498 ida_check_nomem();
499
500 for (i = 0; i < 10000; i++) {
501 assert(ida_pre_get(&ida, GFP_KERNEL));
502 assert(!ida_get_new(&ida, &id));
503 assert(id == i);
504 }
505
506 ida_remove(&ida, 20);
507 ida_remove(&ida, 21);
508 for (i = 0; i < 3; i++) {
509 assert(ida_pre_get(&ida, GFP_KERNEL));
510 assert(!ida_get_new(&ida, &id));
511 if (i == 2)
512 assert(id == 10000);
513 }
514
515 for (i = 0; i < 5000; i++)
516 ida_remove(&ida, i);
517
518 assert(ida_pre_get(&ida, GFP_KERNEL));
519 assert(!ida_get_new_above(&ida, 5000, &id));
520 assert(id == 10001);
521
522 ida_destroy(&ida);
523
524 assert(ida_is_empty(&ida));
525 410
526 assert(ida_pre_get(&ida, GFP_KERNEL)); 411 ida_check_nomem();
527 assert(!ida_get_new_above(&ida, 1, &id)); 412 ida_check_conv_user();
528 assert(id == 1);
529
530 ida_remove(&ida, id);
531 assert(ida_is_empty(&ida));
532 ida_destroy(&ida);
533 assert(ida_is_empty(&ida));
534
535 assert(ida_pre_get(&ida, GFP_KERNEL));
536 assert(!ida_get_new_above(&ida, 1, &id));
537 ida_destroy(&ida);
538 assert(ida_is_empty(&ida));
539
540 assert(ida_pre_get(&ida, GFP_KERNEL));
541 assert(!ida_get_new_above(&ida, 1, &id));
542 assert(id == 1);
543 assert(ida_pre_get(&ida, GFP_KERNEL));
544 assert(!ida_get_new_above(&ida, 1025, &id));
545 assert(id == 1025);
546 assert(ida_pre_get(&ida, GFP_KERNEL));
547 assert(!ida_get_new_above(&ida, 10000, &id));
548 assert(id == 10000);
549 ida_remove(&ida, 1025);
550 ida_destroy(&ida);
551 assert(ida_is_empty(&ida));
552
553 ida_check_leaf();
554 ida_check_max();
555 ida_check_conv();
556 ida_check_random(); 413 ida_check_random();
557 ida_simple_get_remove_test(); 414 ida_simple_get_remove_test();
558 415
@@ -582,12 +439,19 @@ void ida_thread_tests(void)
582 pthread_join(threads[i], NULL); 439 pthread_join(threads[i], NULL);
583} 440}
584 441
442void ida_tests(void)
443{
444 user_ida_checks();
445 ida_checks();
446 ida_exit();
447 ida_thread_tests();
448}
449
585int __weak main(void) 450int __weak main(void)
586{ 451{
587 radix_tree_init(); 452 radix_tree_init();
588 idr_checks(); 453 idr_checks();
589 ida_checks(); 454 ida_tests();
590 ida_thread_tests();
591 radix_tree_cpu_dead(1); 455 radix_tree_cpu_dead(1);
592 rcu_barrier(); 456 rcu_barrier();
593 if (nr_allocated) 457 if (nr_allocated)
diff --git a/tools/testing/radix-tree/linux/xarray.h b/tools/testing/radix-tree/linux/xarray.h
new file mode 100644
index 000000000000..df3812cda376
--- /dev/null
+++ b/tools/testing/radix-tree/linux/xarray.h
@@ -0,0 +1,2 @@
1#include "generated/map-shift.h"
2#include "../../../../include/linux/xarray.h"
diff --git a/tools/testing/radix-tree/main.c b/tools/testing/radix-tree/main.c
index 257f3f8aacaa..b741686e53d6 100644
--- a/tools/testing/radix-tree/main.c
+++ b/tools/testing/radix-tree/main.c
@@ -27,20 +27,22 @@ void __gang_check(unsigned long middle, long down, long up, int chunk, int hop)
27 item_check_present(&tree, middle + idx); 27 item_check_present(&tree, middle + idx);
28 item_check_absent(&tree, middle + up); 28 item_check_absent(&tree, middle + up);
29 29
30 item_gang_check_present(&tree, middle - down, 30 if (chunk > 0) {
31 up + down, chunk, hop); 31 item_gang_check_present(&tree, middle - down, up + down,
32 item_full_scan(&tree, middle - down, down + up, chunk); 32 chunk, hop);
33 item_full_scan(&tree, middle - down, down + up, chunk);
34 }
33 item_kill_tree(&tree); 35 item_kill_tree(&tree);
34} 36}
35 37
36void gang_check(void) 38void gang_check(void)
37{ 39{
38 __gang_check(1 << 30, 128, 128, 35, 2); 40 __gang_check(1UL << 30, 128, 128, 35, 2);
39 __gang_check(1 << 31, 128, 128, 32, 32); 41 __gang_check(1UL << 31, 128, 128, 32, 32);
40 __gang_check(1 << 31, 128, 128, 32, 100); 42 __gang_check(1UL << 31, 128, 128, 32, 100);
41 __gang_check(1 << 31, 128, 128, 17, 7); 43 __gang_check(1UL << 31, 128, 128, 17, 7);
42 __gang_check(0xffff0000, 0, 65536, 17, 7); 44 __gang_check(0xffff0000UL, 0, 65536, 17, 7);
43 __gang_check(0xfffffffe, 1, 1, 17, 7); 45 __gang_check(0xfffffffeUL, 1, 1, 17, 7);
44} 46}
45 47
46void __big_gang_check(void) 48void __big_gang_check(void)
@@ -322,7 +324,7 @@ static void single_thread_tests(bool long_run)
322 printv(2, "after dynamic_height_check: %d allocated, preempt %d\n", 324 printv(2, "after dynamic_height_check: %d allocated, preempt %d\n",
323 nr_allocated, preempt_count); 325 nr_allocated, preempt_count);
324 idr_checks(); 326 idr_checks();
325 ida_checks(); 327 ida_tests();
326 rcu_barrier(); 328 rcu_barrier();
327 printv(2, "after idr_checks: %d allocated, preempt %d\n", 329 printv(2, "after idr_checks: %d allocated, preempt %d\n",
328 nr_allocated, preempt_count); 330 nr_allocated, preempt_count);
@@ -369,7 +371,6 @@ int main(int argc, char **argv)
369 iteration_test(0, 10 + 90 * long_run); 371 iteration_test(0, 10 + 90 * long_run);
370 iteration_test(7, 10 + 90 * long_run); 372 iteration_test(7, 10 + 90 * long_run);
371 single_thread_tests(long_run); 373 single_thread_tests(long_run);
372 ida_thread_tests();
373 374
374 /* Free any remaining preallocated nodes */ 375 /* Free any remaining preallocated nodes */
375 radix_tree_cpu_dead(0); 376 radix_tree_cpu_dead(0);
diff --git a/tools/testing/radix-tree/test.h b/tools/testing/radix-tree/test.h
index 31f1d9b6f506..92d901eacf49 100644
--- a/tools/testing/radix-tree/test.h
+++ b/tools/testing/radix-tree/test.h
@@ -39,8 +39,7 @@ void multiorder_checks(void);
39void iteration_test(unsigned order, unsigned duration); 39void iteration_test(unsigned order, unsigned duration);
40void benchmark(void); 40void benchmark(void);
41void idr_checks(void); 41void idr_checks(void);
42void ida_checks(void); 42void ida_tests(void);
43void ida_thread_tests(void);
44 43
45struct item * 44struct item *
46item_tag_set(struct radix_tree_root *root, unsigned long index, int tag); 45item_tag_set(struct radix_tree_root *root, unsigned long index, int tag);