@@ -643,83 +643,82 @@ static void build_ksm_umr(struct mlx5e_icosq *sq, struct mlx5e_umr_wqe *umr_wqe,
643643 umr_wqe -> uctrl .mkey_mask = cpu_to_be64 (MLX5_MKEY_MASK_FREE );
644644}
645645
646+ static struct mlx5e_frag_page * mlx5e_shampo_hd_to_frag_page (struct mlx5e_rq * rq , int header_index )
647+ {
648+ BUILD_BUG_ON (MLX5E_SHAMPO_LOG_MAX_HEADER_ENTRY_SIZE > PAGE_SHIFT );
649+
650+ return & rq -> mpwqe .shampo -> pages [header_index >> MLX5E_SHAMPO_LOG_WQ_HEADER_PER_PAGE ];
651+ }
652+
653+ static u64 mlx5e_shampo_hd_offset (int header_index )
654+ {
655+ return (header_index & (MLX5E_SHAMPO_WQ_HEADER_PER_PAGE - 1 )) <<
656+ MLX5E_SHAMPO_LOG_MAX_HEADER_ENTRY_SIZE ;
657+ }
658+
659+ static void mlx5e_free_rx_shampo_hd_entry (struct mlx5e_rq * rq , u16 header_index );
660+
646661static int mlx5e_build_shampo_hd_umr (struct mlx5e_rq * rq ,
647662 struct mlx5e_icosq * sq ,
648663 u16 ksm_entries , u16 index )
649664{
650665 struct mlx5e_shampo_hd * shampo = rq -> mpwqe .shampo ;
651- u16 entries , pi , header_offset , err , wqe_bbs , new_entries ;
666+ u16 pi , header_offset , err , wqe_bbs ;
652667 u32 lkey = rq -> mdev -> mlx5e_res .hw_objs .mkey ;
653- u16 page_index = shampo -> curr_page_index ;
654- struct mlx5e_frag_page * frag_page ;
655- u64 addr = shampo -> last_addr ;
656- struct mlx5e_dma_info * dma_info ;
657668 struct mlx5e_umr_wqe * umr_wqe ;
658- int headroom , i ;
669+ int headroom , i = 0 ;
659670
660671 headroom = rq -> buff .headroom ;
661- new_entries = ksm_entries - (shampo -> pi & (MLX5_UMR_KSM_NUM_ENTRIES_ALIGNMENT - 1 ));
662- entries = ALIGN (ksm_entries , MLX5_UMR_KSM_NUM_ENTRIES_ALIGNMENT );
663- wqe_bbs = MLX5E_KSM_UMR_WQEBBS (entries );
672+ wqe_bbs = MLX5E_KSM_UMR_WQEBBS (ksm_entries );
664673 pi = mlx5e_icosq_get_next_pi (sq , wqe_bbs );
665674 umr_wqe = mlx5_wq_cyc_get_wqe (& sq -> wq , pi );
666- build_ksm_umr (sq , umr_wqe , shampo -> key , index , entries );
675+ build_ksm_umr (sq , umr_wqe , shampo -> key , index , ksm_entries );
667676
668- frag_page = & shampo -> pages [page_index ];
677+ WARN_ON_ONCE (ksm_entries & (MLX5E_SHAMPO_WQ_HEADER_PER_PAGE - 1 ));
678+ while (i < ksm_entries ) {
679+ struct mlx5e_frag_page * frag_page = mlx5e_shampo_hd_to_frag_page (rq , index );
680+ u64 addr ;
669681
670- for (i = 0 ; i < entries ; i ++ , index ++ ) {
671- dma_info = & shampo -> info [index ];
672- if (i >= ksm_entries || (index < shampo -> pi && shampo -> pi - index <
673- MLX5_UMR_KSM_NUM_ENTRIES_ALIGNMENT ))
674- goto update_ksm ;
675- header_offset = (index & (MLX5E_SHAMPO_WQ_HEADER_PER_PAGE - 1 )) <<
676- MLX5E_SHAMPO_LOG_MAX_HEADER_ENTRY_SIZE ;
677- if (!(header_offset & (PAGE_SIZE - 1 ))) {
678- page_index = (page_index + 1 ) & (shampo -> hd_per_wq - 1 );
679- frag_page = & shampo -> pages [page_index ];
682+ err = mlx5e_page_alloc_fragmented (rq , frag_page );
683+ if (unlikely (err ))
684+ goto err_unmap ;
680685
681- err = mlx5e_page_alloc_fragmented (rq , frag_page );
682- if (unlikely (err ))
683- goto err_unmap ;
684686
685- addr = page_pool_get_dma_addr (frag_page -> page );
687+ addr = page_pool_get_dma_addr (frag_page -> page );
686688
687- dma_info -> addr = addr ;
688- dma_info -> frag_page = frag_page ;
689- } else {
690- dma_info -> addr = addr + header_offset ;
691- dma_info -> frag_page = frag_page ;
692- }
689+ for (int j = 0 ; j < MLX5E_SHAMPO_WQ_HEADER_PER_PAGE ; j ++ ) {
690+ header_offset = mlx5e_shampo_hd_offset (index ++ );
693691
694- update_ksm :
695- umr_wqe -> inline_ksms [ i ] = ( struct mlx5_ksm ) {
696- . key = cpu_to_be32 ( lkey ),
697- . va = cpu_to_be64 ( dma_info -> addr + headroom ),
698- };
692+ umr_wqe -> inline_ksms [ i ++ ] = ( struct mlx5_ksm ) {
693+ . key = cpu_to_be32 ( lkey ),
694+ . va = cpu_to_be64 ( addr + header_offset + headroom ),
695+ };
696+ }
699697 }
700698
701699 sq -> db .wqe_info [pi ] = (struct mlx5e_icosq_wqe_info ) {
702700 .wqe_type = MLX5E_ICOSQ_WQE_SHAMPO_HD_UMR ,
703701 .num_wqebbs = wqe_bbs ,
704- .shampo .len = new_entries ,
702+ .shampo .len = ksm_entries ,
705703 };
706704
707- shampo -> pi = (shampo -> pi + new_entries ) & (shampo -> hd_per_wq - 1 );
708- shampo -> curr_page_index = page_index ;
709- shampo -> last_addr = addr ;
705+ shampo -> pi = (shampo -> pi + ksm_entries ) & (shampo -> hd_per_wq - 1 );
710706 sq -> pc += wqe_bbs ;
711707 sq -> doorbell_cseg = & umr_wqe -> ctrl ;
712708
713709 return 0 ;
714710
715711err_unmap :
716- while (-- i >= 0 ) {
717- dma_info = & shampo -> info [-- index ];
718- if (!(i & (MLX5E_SHAMPO_WQ_HEADER_PER_PAGE - 1 ))) {
719- dma_info -> addr = ALIGN_DOWN (dma_info -> addr , PAGE_SIZE );
720- mlx5e_page_release_fragmented (rq , dma_info -> frag_page );
712+ while (-- i ) {
713+ -- index ;
714+ header_offset = mlx5e_shampo_hd_offset (index );
715+ if (!header_offset ) {
716+ struct mlx5e_frag_page * frag_page = mlx5e_shampo_hd_to_frag_page (rq , index );
717+
718+ mlx5e_page_release_fragmented (rq , frag_page );
721719 }
722720 }
721+
723722 rq -> stats -> buff_alloc_err ++ ;
724723 return err ;
725724}
@@ -731,16 +730,17 @@ static int mlx5e_alloc_rx_hd_mpwqe(struct mlx5e_rq *rq)
731730 struct mlx5e_icosq * sq = rq -> icosq ;
732731 int i , err , max_ksm_entries , len ;
733732
734- max_ksm_entries = MLX5E_MAX_KSM_PER_WQE (rq -> mdev );
733+ max_ksm_entries = ALIGN_DOWN (MLX5E_MAX_KSM_PER_WQE (rq -> mdev ),
734+ MLX5E_SHAMPO_WQ_HEADER_PER_PAGE );
735735 ksm_entries = bitmap_find_window (shampo -> bitmap ,
736736 shampo -> hd_per_wqe ,
737737 shampo -> hd_per_wq , shampo -> pi );
738738 ksm_entries = ALIGN_DOWN (ksm_entries , MLX5E_SHAMPO_WQ_HEADER_PER_PAGE );
739739 if (!ksm_entries )
740740 return 0 ;
741741
742- ksm_entries += ( shampo -> pi & ( MLX5_UMR_KSM_NUM_ENTRIES_ALIGNMENT - 1 ));
743- index = ALIGN_DOWN ( shampo -> pi , MLX5_UMR_KSM_NUM_ENTRIES_ALIGNMENT ) ;
742+ /* pi is aligned to MLX5E_SHAMPO_WQ_HEADER_PER_PAGE */
743+ index = shampo -> pi ;
744744 entries_before = shampo -> hd_per_wq - index ;
745745
746746 if (unlikely (entries_before < ksm_entries ))
@@ -851,13 +851,11 @@ static void
851851mlx5e_free_rx_shampo_hd_entry (struct mlx5e_rq * rq , u16 header_index )
852852{
853853 struct mlx5e_shampo_hd * shampo = rq -> mpwqe .shampo ;
854- u64 addr = shampo -> info [header_index ].addr ;
855854
856855 if (((header_index + 1 ) & (MLX5E_SHAMPO_WQ_HEADER_PER_PAGE - 1 )) == 0 ) {
857- struct mlx5e_dma_info * dma_info = & shampo -> info [ header_index ] ;
856+ struct mlx5e_frag_page * frag_page = mlx5e_shampo_hd_to_frag_page ( rq , header_index ) ;
858857
859- dma_info -> addr = ALIGN_DOWN (addr , PAGE_SIZE );
860- mlx5e_page_release_fragmented (rq , dma_info -> frag_page );
858+ mlx5e_page_release_fragmented (rq , frag_page );
861859 }
862860 clear_bit (header_index , shampo -> bitmap );
863861}
@@ -1211,10 +1209,10 @@ static void mlx5e_lro_update_hdr(struct sk_buff *skb, struct mlx5_cqe64 *cqe,
12111209
12121210static void * mlx5e_shampo_get_packet_hd (struct mlx5e_rq * rq , u16 header_index )
12131211{
1214- struct mlx5e_dma_info * last_head = & rq -> mpwqe . shampo -> info [ header_index ] ;
1215- u16 head_offset = ( last_head -> addr & ( PAGE_SIZE - 1 ) ) + rq -> buff .headroom ;
1212+ struct mlx5e_frag_page * frag_page = mlx5e_shampo_hd_to_frag_page ( rq , header_index ) ;
1213+ u16 head_offset = mlx5e_shampo_hd_offset ( header_index ) + rq -> buff .headroom ;
12161214
1217- return page_address (last_head -> frag_page -> page ) + head_offset ;
1215+ return page_address (frag_page -> page ) + head_offset ;
12181216}
12191217
12201218static void mlx5e_shampo_update_ipv4_udp_hdr (struct mlx5e_rq * rq , struct iphdr * ipv4 )
@@ -2185,29 +2183,30 @@ static struct sk_buff *
21852183mlx5e_skb_from_cqe_shampo (struct mlx5e_rq * rq , struct mlx5e_mpw_info * wi ,
21862184 struct mlx5_cqe64 * cqe , u16 header_index )
21872185{
2188- struct mlx5e_dma_info * head = & rq -> mpwqe .shampo -> info [header_index ];
2189- u16 head_offset = head -> addr & (PAGE_SIZE - 1 );
2186+ struct mlx5e_frag_page * frag_page = mlx5e_shampo_hd_to_frag_page (rq , header_index );
2187+ dma_addr_t page_dma_addr = page_pool_get_dma_addr (frag_page -> page );
2188+ u16 head_offset = mlx5e_shampo_hd_offset (header_index );
2189+ dma_addr_t dma_addr = page_dma_addr + head_offset ;
21902190 u16 head_size = cqe -> shampo .header_size ;
21912191 u16 rx_headroom = rq -> buff .headroom ;
21922192 struct sk_buff * skb = NULL ;
21932193 void * hdr , * data ;
21942194 u32 frag_size ;
21952195
2196- hdr = page_address (head -> frag_page -> page ) + head_offset ;
2196+ hdr = page_address (frag_page -> page ) + head_offset ;
21972197 data = hdr + rx_headroom ;
21982198 frag_size = MLX5_SKB_FRAG_SZ (rx_headroom + head_size );
21992199
22002200 if (likely (frag_size <= BIT (MLX5E_SHAMPO_LOG_MAX_HEADER_ENTRY_SIZE ))) {
22012201 /* build SKB around header */
2202- dma_sync_single_range_for_cpu (rq -> pdev , head -> addr , 0 , frag_size , rq -> buff .map_dir );
2202+ dma_sync_single_range_for_cpu (rq -> pdev , dma_addr , 0 , frag_size , rq -> buff .map_dir );
22032203 net_prefetchw (hdr );
22042204 net_prefetch (data );
22052205 skb = mlx5e_build_linear_skb (rq , hdr , frag_size , rx_headroom , head_size , 0 );
2206-
22072206 if (unlikely (!skb ))
22082207 return NULL ;
22092208
2210- head -> frag_page -> frags ++ ;
2209+ frag_page -> frags ++ ;
22112210 } else {
22122211 /* allocate SKB and copy header for large header */
22132212 rq -> stats -> gro_large_hds ++ ;
@@ -2219,7 +2218,7 @@ mlx5e_skb_from_cqe_shampo(struct mlx5e_rq *rq, struct mlx5e_mpw_info *wi,
22192218 }
22202219
22212220 net_prefetchw (skb -> data );
2222- mlx5e_copy_skb_header (rq , skb , head -> frag_page -> page , head -> addr ,
2221+ mlx5e_copy_skb_header (rq , skb , frag_page -> page , dma_addr ,
22232222 head_offset + rx_headroom ,
22242223 rx_headroom , head_size );
22252224 /* skb linear part was allocated with headlen and aligned to long */
0 commit comments