162306a36Sopenharmony_ci.. SPDX-License-Identifier: GPL-2.0+ 262306a36Sopenharmony_ci 362306a36Sopenharmony_ci============= 462306a36Sopenharmony_ciID Allocation 562306a36Sopenharmony_ci============= 662306a36Sopenharmony_ci 762306a36Sopenharmony_ci:Author: Matthew Wilcox 862306a36Sopenharmony_ci 962306a36Sopenharmony_ciOverview 1062306a36Sopenharmony_ci======== 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_ciA common problem to solve is allocating identifiers (IDs); generally 1362306a36Sopenharmony_cismall numbers which identify a thing. Examples include file descriptors, 1462306a36Sopenharmony_ciprocess IDs, packet identifiers in networking protocols, SCSI tags 1562306a36Sopenharmony_ciand device instance numbers. The IDR and the IDA provide a reasonable 1662306a36Sopenharmony_cisolution to the problem to avoid everybody inventing their own. The IDR 1762306a36Sopenharmony_ciprovides the ability to map an ID to a pointer, while the IDA provides 1862306a36Sopenharmony_cionly ID allocation, and as a result is much more memory-efficient. 1962306a36Sopenharmony_ci 2062306a36Sopenharmony_ciThe IDR interface is deprecated; please use the :doc:`XArray <xarray>` 2162306a36Sopenharmony_ciinstead. 2262306a36Sopenharmony_ci 2362306a36Sopenharmony_ciIDR usage 2462306a36Sopenharmony_ci========= 2562306a36Sopenharmony_ci 2662306a36Sopenharmony_ciStart by initialising an IDR, either with DEFINE_IDR() 2762306a36Sopenharmony_cifor statically allocated IDRs or idr_init() for dynamically 2862306a36Sopenharmony_ciallocated IDRs. 2962306a36Sopenharmony_ci 3062306a36Sopenharmony_ciYou can call idr_alloc() to allocate an unused ID. Look up 3162306a36Sopenharmony_cithe pointer you associated with the ID by calling idr_find() 3262306a36Sopenharmony_ciand free the ID by calling idr_remove(). 3362306a36Sopenharmony_ci 3462306a36Sopenharmony_ciIf you need to change the pointer associated with an ID, you can call 3562306a36Sopenharmony_ciidr_replace(). One common reason to do this is to reserve an 3662306a36Sopenharmony_ciID by passing a ``NULL`` pointer to the allocation function; initialise the 3762306a36Sopenharmony_ciobject with the reserved ID and finally insert the initialised object 3862306a36Sopenharmony_ciinto the IDR. 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_ciSome users need to allocate IDs larger than ``INT_MAX``. So far all of 4162306a36Sopenharmony_cithese users have been content with a ``UINT_MAX`` limit, and they use 4262306a36Sopenharmony_ciidr_alloc_u32(). If you need IDs that will not fit in a u32, 4362306a36Sopenharmony_ciwe will work with you to address your needs. 4462306a36Sopenharmony_ci 4562306a36Sopenharmony_ciIf you need to allocate IDs sequentially, you can use 4662306a36Sopenharmony_ciidr_alloc_cyclic(). The IDR becomes less efficient when dealing 4762306a36Sopenharmony_ciwith larger IDs, so using this function comes at a slight cost. 4862306a36Sopenharmony_ci 4962306a36Sopenharmony_ciTo perform an action on all pointers used by the IDR, you can 5062306a36Sopenharmony_cieither use the callback-based idr_for_each() or the 5162306a36Sopenharmony_ciiterator-style idr_for_each_entry(). You may need to use 5262306a36Sopenharmony_ciidr_for_each_entry_continue() to continue an iteration. You can 5362306a36Sopenharmony_cialso use idr_get_next() if the iterator doesn't fit your needs. 5462306a36Sopenharmony_ci 5562306a36Sopenharmony_ciWhen you have finished using an IDR, you can call idr_destroy() 5662306a36Sopenharmony_cito release the memory used by the IDR. This will not free the objects 5762306a36Sopenharmony_cipointed to from the IDR; if you want to do that, use one of the iterators 5862306a36Sopenharmony_cito do it. 5962306a36Sopenharmony_ci 6062306a36Sopenharmony_ciYou can use idr_is_empty() to find out whether there are any 6162306a36Sopenharmony_ciIDs currently allocated. 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_ciIf you need to take a lock while allocating a new ID from the IDR, 6462306a36Sopenharmony_ciyou may need to pass a restrictive set of GFP flags, which can lead 6562306a36Sopenharmony_cito the IDR being unable to allocate memory. To work around this, 6662306a36Sopenharmony_ciyou can call idr_preload() before taking the lock, and then 6762306a36Sopenharmony_ciidr_preload_end() after the allocation. 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_ci.. kernel-doc:: include/linux/idr.h 7062306a36Sopenharmony_ci :doc: idr sync 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_ciIDA usage 7362306a36Sopenharmony_ci========= 7462306a36Sopenharmony_ci 7562306a36Sopenharmony_ci.. kernel-doc:: lib/idr.c 7662306a36Sopenharmony_ci :doc: IDA description 7762306a36Sopenharmony_ci 7862306a36Sopenharmony_ciFunctions and structures 7962306a36Sopenharmony_ci======================== 8062306a36Sopenharmony_ci 8162306a36Sopenharmony_ci.. kernel-doc:: include/linux/idr.h 8262306a36Sopenharmony_ci :functions: 8362306a36Sopenharmony_ci.. kernel-doc:: lib/idr.c 8462306a36Sopenharmony_ci :functions: 85