@@ -151,11 +151,6 @@ static struct pcpu_chunk *pcpu_first_chunk;
151151static struct pcpu_chunk * pcpu_reserved_chunk ;
152152static int pcpu_reserved_chunk_limit ;
153153
154- /*
155- * Free path accesses and alters only the index data structures and can be
156- * safely called from atomic context. When memory needs to be returned to
157- * the system, free path schedules reclaim_work.
158- */
159154static DEFINE_SPINLOCK (pcpu_lock ); /* all internal data structures */
160155static DEFINE_MUTEX (pcpu_alloc_mutex ); /* chunk create/destroy, [de]pop */
161156
@@ -727,20 +722,21 @@ static struct pcpu_chunk *pcpu_chunk_addr_search(void *addr)
727722 * @size: size of area to allocate in bytes
728723 * @align: alignment of area (max PAGE_SIZE)
729724 * @reserved: allocate from the reserved chunk if available
725+ * @gfp: allocation flags
730726 *
731- * Allocate percpu area of @size bytes aligned at @align.
732- *
733- * CONTEXT:
734- * Does GFP_KERNEL allocation.
727+ * Allocate percpu area of @size bytes aligned at @align. If @gfp doesn't
728+ * contain %GFP_KERNEL, the allocation is atomic.
735729 *
736730 * RETURNS:
737731 * Percpu pointer to the allocated area on success, NULL on failure.
738732 */
739- static void __percpu * pcpu_alloc (size_t size , size_t align , bool reserved )
733+ static void __percpu * pcpu_alloc (size_t size , size_t align , bool reserved ,
734+ gfp_t gfp )
740735{
741736 static int warn_limit = 10 ;
742737 struct pcpu_chunk * chunk ;
743738 const char * err ;
739+ bool is_atomic = !(gfp & GFP_KERNEL );
744740 int slot , off , new_alloc , cpu , ret ;
745741 unsigned long flags ;
746742 void __percpu * ptr ;
@@ -773,14 +769,15 @@ static void __percpu *pcpu_alloc(size_t size, size_t align, bool reserved)
773769
774770 while ((new_alloc = pcpu_need_to_extend (chunk ))) {
775771 spin_unlock_irqrestore (& pcpu_lock , flags );
776- if (pcpu_extend_area_map (chunk , new_alloc ) < 0 ) {
772+ if (is_atomic ||
773+ pcpu_extend_area_map (chunk , new_alloc ) < 0 ) {
777774 err = "failed to extend area map of reserved chunk" ;
778775 goto fail ;
779776 }
780777 spin_lock_irqsave (& pcpu_lock , flags );
781778 }
782779
783- off = pcpu_alloc_area (chunk , size , align , false );
780+ off = pcpu_alloc_area (chunk , size , align , is_atomic );
784781 if (off >= 0 )
785782 goto area_found ;
786783
@@ -797,6 +794,8 @@ static void __percpu *pcpu_alloc(size_t size, size_t align, bool reserved)
797794
798795 new_alloc = pcpu_need_to_extend (chunk );
799796 if (new_alloc ) {
797+ if (is_atomic )
798+ continue ;
800799 spin_unlock_irqrestore (& pcpu_lock , flags );
801800 if (pcpu_extend_area_map (chunk ,
802801 new_alloc ) < 0 ) {
@@ -811,7 +810,7 @@ static void __percpu *pcpu_alloc(size_t size, size_t align, bool reserved)
811810 goto restart ;
812811 }
813812
814- off = pcpu_alloc_area (chunk , size , align , false );
813+ off = pcpu_alloc_area (chunk , size , align , is_atomic );
815814 if (off >= 0 )
816815 goto area_found ;
817816 }
@@ -824,6 +823,9 @@ static void __percpu *pcpu_alloc(size_t size, size_t align, bool reserved)
824823 * tasks to create chunks simultaneously. Serialize and create iff
825824 * there's still no empty chunk after grabbing the mutex.
826825 */
826+ if (is_atomic )
827+ goto fail ;
828+
827829 mutex_lock (& pcpu_alloc_mutex );
828830
829831 if (list_empty (& pcpu_slot [pcpu_nr_slots - 1 ])) {
@@ -846,7 +848,7 @@ static void __percpu *pcpu_alloc(size_t size, size_t align, bool reserved)
846848 spin_unlock_irqrestore (& pcpu_lock , flags );
847849
848850 /* populate if not all pages are already there */
849- if (true ) {
851+ if (! is_atomic ) {
850852 int page_start , page_end , rs , re ;
851853
852854 mutex_lock (& pcpu_alloc_mutex );
@@ -884,9 +886,9 @@ static void __percpu *pcpu_alloc(size_t size, size_t align, bool reserved)
884886fail_unlock :
885887 spin_unlock_irqrestore (& pcpu_lock , flags );
886888fail :
887- if (warn_limit ) {
888- pr_warning ("PERCPU: allocation failed, size=%zu align=%zu, "
889- "%s\n" , size , align , err );
889+ if (! is_atomic && warn_limit ) {
890+ pr_warning ("PERCPU: allocation failed, size=%zu align=%zu atomic=%d, %s\n" ,
891+ size , align , is_atomic , err );
890892 dump_stack ();
891893 if (!-- warn_limit )
892894 pr_info ("PERCPU: limit reached, disable warning\n" );
@@ -895,22 +897,34 @@ static void __percpu *pcpu_alloc(size_t size, size_t align, bool reserved)
895897}
896898
897899/**
898- * __alloc_percpu - allocate dynamic percpu area
900+ * __alloc_percpu_gfp - allocate dynamic percpu area
899901 * @size: size of area to allocate in bytes
900902 * @align: alignment of area (max PAGE_SIZE)
903+ * @gfp: allocation flags
901904 *
902- * Allocate zero-filled percpu area of @size bytes aligned at @align.
903- * Might sleep. Might trigger writeouts.
904- *
905- * CONTEXT:
906- * Does GFP_KERNEL allocation.
905+ * Allocate zero-filled percpu area of @size bytes aligned at @align. If
906+ * @gfp doesn't contain %GFP_KERNEL, the allocation doesn't block and can
907+ * be called from any context but is a lot more likely to fail.
907908 *
908909 * RETURNS:
909910 * Percpu pointer to the allocated area on success, NULL on failure.
910911 */
912+ void __percpu * __alloc_percpu_gfp (size_t size , size_t align , gfp_t gfp )
913+ {
914+ return pcpu_alloc (size , align , false, gfp );
915+ }
916+ EXPORT_SYMBOL_GPL (__alloc_percpu_gfp );
917+
918+ /**
919+ * __alloc_percpu - allocate dynamic percpu area
920+ * @size: size of area to allocate in bytes
921+ * @align: alignment of area (max PAGE_SIZE)
922+ *
923+ * Equivalent to __alloc_percpu_gfp(size, align, %GFP_KERNEL).
924+ */
911925void __percpu * __alloc_percpu (size_t size , size_t align )
912926{
913- return pcpu_alloc (size , align , false);
927+ return pcpu_alloc (size , align , false, GFP_KERNEL );
914928}
915929EXPORT_SYMBOL_GPL (__alloc_percpu );
916930
@@ -932,7 +946,7 @@ EXPORT_SYMBOL_GPL(__alloc_percpu);
932946 */
933947void __percpu * __alloc_reserved_percpu (size_t size , size_t align )
934948{
935- return pcpu_alloc (size , align , true);
949+ return pcpu_alloc (size , align , true, GFP_KERNEL );
936950}
937951
938952/**
0 commit comments