@@ -805,6 +805,133 @@ int bpf_jit_add_poke_descriptor(struct bpf_prog *prog,
805
805
return slot ;
806
806
}
807
807
808
+ /*
809
+ * BPF program pack allocator.
810
+ *
811
+ * Most BPF programs are pretty small. Allocating a hole page for each
812
+ * program is sometime a waste. Many small bpf program also adds pressure
813
+ * to instruction TLB. To solve this issue, we introduce a BPF program pack
814
+ * allocator. The prog_pack allocator uses HPAGE_PMD_SIZE page (2MB on x86)
815
+ * to host BPF programs.
816
+ */
817
+ #define BPF_PROG_PACK_SIZE HPAGE_PMD_SIZE
818
+ #define BPF_PROG_CHUNK_SHIFT 6
819
+ #define BPF_PROG_CHUNK_SIZE (1 << BPF_PROG_CHUNK_SHIFT)
820
+ #define BPF_PROG_CHUNK_MASK (~(BPF_PROG_CHUNK_SIZE - 1))
821
+ #define BPF_PROG_CHUNK_COUNT (BPF_PROG_PACK_SIZE / BPF_PROG_CHUNK_SIZE)
822
+
823
+ struct bpf_prog_pack {
824
+ struct list_head list ;
825
+ void * ptr ;
826
+ unsigned long bitmap [BITS_TO_LONGS (BPF_PROG_CHUNK_COUNT )];
827
+ };
828
+
829
+ #define BPF_PROG_MAX_PACK_PROG_SIZE HPAGE_PMD_SIZE
830
+ #define BPF_PROG_SIZE_TO_NBITS (size ) (round_up(size, BPF_PROG_CHUNK_SIZE) / BPF_PROG_CHUNK_SIZE)
831
+
832
+ static DEFINE_MUTEX (pack_mutex );
833
+ static LIST_HEAD (pack_list );
834
+
835
+ static struct bpf_prog_pack * alloc_new_pack (void )
836
+ {
837
+ struct bpf_prog_pack * pack ;
838
+
839
+ pack = kzalloc (sizeof (* pack ), GFP_KERNEL );
840
+ if (!pack )
841
+ return NULL ;
842
+ pack -> ptr = module_alloc (BPF_PROG_PACK_SIZE );
843
+ if (!pack -> ptr ) {
844
+ kfree (pack );
845
+ return NULL ;
846
+ }
847
+ bitmap_zero (pack -> bitmap , BPF_PROG_PACK_SIZE / BPF_PROG_CHUNK_SIZE );
848
+ list_add_tail (& pack -> list , & pack_list );
849
+
850
+ set_vm_flush_reset_perms (pack -> ptr );
851
+ set_memory_ro ((unsigned long )pack -> ptr , BPF_PROG_PACK_SIZE / PAGE_SIZE );
852
+ set_memory_x ((unsigned long )pack -> ptr , BPF_PROG_PACK_SIZE / PAGE_SIZE );
853
+ return pack ;
854
+ }
855
+
856
+ static void * bpf_prog_pack_alloc (u32 size )
857
+ {
858
+ unsigned int nbits = BPF_PROG_SIZE_TO_NBITS (size );
859
+ struct bpf_prog_pack * pack ;
860
+ unsigned long pos ;
861
+ void * ptr = NULL ;
862
+
863
+ if (size > BPF_PROG_MAX_PACK_PROG_SIZE ) {
864
+ size = round_up (size , PAGE_SIZE );
865
+ ptr = module_alloc (size );
866
+ if (ptr ) {
867
+ set_vm_flush_reset_perms (ptr );
868
+ set_memory_ro ((unsigned long )ptr , size / PAGE_SIZE );
869
+ set_memory_x ((unsigned long )ptr , size / PAGE_SIZE );
870
+ }
871
+ return ptr ;
872
+ }
873
+ mutex_lock (& pack_mutex );
874
+ list_for_each_entry (pack , & pack_list , list ) {
875
+ pos = bitmap_find_next_zero_area (pack -> bitmap , BPF_PROG_CHUNK_COUNT , 0 ,
876
+ nbits , 0 );
877
+ if (pos < BPF_PROG_CHUNK_COUNT )
878
+ goto found_free_area ;
879
+ }
880
+
881
+ pack = alloc_new_pack ();
882
+ if (!pack )
883
+ goto out ;
884
+
885
+ pos = 0 ;
886
+
887
+ found_free_area :
888
+ bitmap_set (pack -> bitmap , pos , nbits );
889
+ ptr = (void * )(pack -> ptr ) + (pos << BPF_PROG_CHUNK_SHIFT );
890
+
891
+ out :
892
+ mutex_unlock (& pack_mutex );
893
+ return ptr ;
894
+ }
895
+
896
+ static void bpf_prog_pack_free (struct bpf_binary_header * hdr )
897
+ {
898
+ struct bpf_prog_pack * pack = NULL , * tmp ;
899
+ unsigned int nbits ;
900
+ unsigned long pos ;
901
+ void * pack_ptr ;
902
+
903
+ if (hdr -> size > BPF_PROG_MAX_PACK_PROG_SIZE ) {
904
+ module_memfree (hdr );
905
+ return ;
906
+ }
907
+
908
+ pack_ptr = (void * )((unsigned long )hdr & ~(BPF_PROG_PACK_SIZE - 1 ));
909
+ mutex_lock (& pack_mutex );
910
+
911
+ list_for_each_entry (tmp , & pack_list , list ) {
912
+ if (tmp -> ptr == pack_ptr ) {
913
+ pack = tmp ;
914
+ break ;
915
+ }
916
+ }
917
+
918
+ if (WARN_ONCE (!pack , "bpf_prog_pack bug\n" ))
919
+ goto out ;
920
+
921
+ nbits = BPF_PROG_SIZE_TO_NBITS (hdr -> size );
922
+ pos = ((unsigned long )hdr - (unsigned long )pack_ptr ) >> BPF_PROG_CHUNK_SHIFT ;
923
+
924
+ bitmap_clear (pack -> bitmap , pos , nbits );
925
+ if (bitmap_find_next_zero_area (pack -> bitmap , BPF_PROG_CHUNK_COUNT , 0 ,
926
+ BPF_PROG_CHUNK_COUNT , 0 ) == 0 ) {
927
+ list_del (& pack -> list );
928
+ module_memfree (pack -> ptr );
929
+ kfree (pack );
930
+ }
931
+ out :
932
+ mutex_unlock (& pack_mutex );
933
+ }
934
+
808
935
static atomic_long_t bpf_jit_current ;
809
936
810
937
/* Can be overridden by an arch's JIT compiler if it has a custom,
0 commit comments