@@ -1054,6 +1054,7 @@ qeth_set_intial_options(struct qeth_card *card)
1054
1054
else
1055
1055
card -> options .layer2 = 0 ;
1056
1056
card -> options .performance_stats = 0 ;
1057
+ card -> options .rx_sg_cb = QETH_RX_SG_CB ;
1057
1058
}
1058
1059
1059
1060
/**
@@ -2258,6 +2259,89 @@ qeth_get_skb(unsigned int length, struct qeth_hdr *hdr)
2258
2259
return skb ;
2259
2260
}
2260
2261
2262
+ static inline int
2263
+ qeth_create_skb_frag (struct qdio_buffer_element * element ,
2264
+ struct sk_buff * * pskb ,
2265
+ int offset , int * pfrag , int data_len )
2266
+ {
2267
+ struct page * page = virt_to_page (element -> addr );
2268
+ if (* pfrag == 0 ) {
2269
+ /* the upper protocol layers assume that there is data in the
2270
+ * skb itself. Copy a small amount (64 bytes) to make them
2271
+ * happy. */
2272
+ * pskb = dev_alloc_skb (64 + QETH_FAKE_LL_LEN_ETH );
2273
+ if (!(* pskb ))
2274
+ return - ENOMEM ;
2275
+ skb_reserve (* pskb , QETH_FAKE_LL_LEN_ETH );
2276
+ if (data_len <= 64 ) {
2277
+ memcpy (skb_put (* pskb , data_len ), element -> addr + offset ,
2278
+ data_len );
2279
+ } else {
2280
+ get_page (page );
2281
+ memcpy (skb_put (* pskb , 64 ), element -> addr + offset , 64 );
2282
+ skb_fill_page_desc (* pskb , * pfrag , page , offset + 64 ,
2283
+ data_len - 64 );
2284
+ (* pskb )-> data_len += data_len - 64 ;
2285
+ (* pskb )-> len += data_len - 64 ;
2286
+ (* pskb )-> truesize += data_len - 64 ;
2287
+ }
2288
+ } else {
2289
+ get_page (page );
2290
+ skb_fill_page_desc (* pskb , * pfrag , page , offset , data_len );
2291
+ (* pskb )-> data_len += data_len ;
2292
+ (* pskb )-> len += data_len ;
2293
+ (* pskb )-> truesize += data_len ;
2294
+ }
2295
+ (* pfrag )++ ;
2296
+ return 0 ;
2297
+ }
2298
+
2299
+ static inline struct qeth_buffer_pool_entry *
2300
+ qeth_find_free_buffer_pool_entry (struct qeth_card * card )
2301
+ {
2302
+ struct list_head * plh ;
2303
+ struct qeth_buffer_pool_entry * entry ;
2304
+ int i , free ;
2305
+ struct page * page ;
2306
+
2307
+ if (list_empty (& card -> qdio .in_buf_pool .entry_list ))
2308
+ return NULL ;
2309
+
2310
+ list_for_each (plh , & card -> qdio .in_buf_pool .entry_list ) {
2311
+ entry = list_entry (plh , struct qeth_buffer_pool_entry , list );
2312
+ free = 1 ;
2313
+ for (i = 0 ; i < QETH_MAX_BUFFER_ELEMENTS (card ); ++ i ) {
2314
+ if (page_count (virt_to_page (entry -> elements [i ])) > 1 ) {
2315
+ free = 0 ;
2316
+ break ;
2317
+ }
2318
+ }
2319
+ if (free ) {
2320
+ list_del_init (& entry -> list );
2321
+ return entry ;
2322
+ }
2323
+ }
2324
+
2325
+ /* no free buffer in pool so take first one and swap pages */
2326
+ entry = list_entry (card -> qdio .in_buf_pool .entry_list .next ,
2327
+ struct qeth_buffer_pool_entry , list );
2328
+ for (i = 0 ; i < QETH_MAX_BUFFER_ELEMENTS (card ); ++ i ) {
2329
+ if (page_count (virt_to_page (entry -> elements [i ])) > 1 ) {
2330
+ page = alloc_page (GFP_ATOMIC |GFP_DMA );
2331
+ if (!page ) {
2332
+ return NULL ;
2333
+ } else {
2334
+ free_page ((unsigned long )entry -> elements [i ]);
2335
+ entry -> elements [i ] = page_address (page );
2336
+ if (card -> options .performance_stats )
2337
+ card -> perf_stats .sg_alloc_page_rx ++ ;
2338
+ }
2339
+ }
2340
+ }
2341
+ list_del_init (& entry -> list );
2342
+ return entry ;
2343
+ }
2344
+
2261
2345
static struct sk_buff *
2262
2346
qeth_get_next_skb (struct qeth_card * card , struct qdio_buffer * buffer ,
2263
2347
struct qdio_buffer_element * * __element , int * __offset ,
@@ -2269,6 +2353,8 @@ qeth_get_next_skb(struct qeth_card *card, struct qdio_buffer *buffer,
2269
2353
int skb_len ;
2270
2354
void * data_ptr ;
2271
2355
int data_len ;
2356
+ int use_rx_sg = 0 ;
2357
+ int frag = 0 ;
2272
2358
2273
2359
QETH_DBF_TEXT (trace ,6 ,"nextskb" );
2274
2360
/* qeth_hdr must not cross element boundaries */
@@ -2293,23 +2379,43 @@ qeth_get_next_skb(struct qeth_card *card, struct qdio_buffer *buffer,
2293
2379
2294
2380
if (!skb_len )
2295
2381
return NULL ;
2296
- if (card -> options .fake_ll ){
2297
- if (card -> dev -> type == ARPHRD_IEEE802_TR ){
2298
- if (!(skb = qeth_get_skb (skb_len + QETH_FAKE_LL_LEN_TR , * hdr )))
2299
- goto no_mem ;
2300
- skb_reserve (skb ,QETH_FAKE_LL_LEN_TR );
2382
+ if ((skb_len >= card -> options .rx_sg_cb ) &&
2383
+ (!(card -> info .type == QETH_CARD_TYPE_OSN )) &&
2384
+ (!atomic_read (& card -> force_alloc_skb ))) {
2385
+ use_rx_sg = 1 ;
2386
+ } else {
2387
+ if (card -> options .fake_ll ) {
2388
+ if (card -> dev -> type == ARPHRD_IEEE802_TR ) {
2389
+ if (!(skb = qeth_get_skb (skb_len +
2390
+ QETH_FAKE_LL_LEN_TR , * hdr )))
2391
+ goto no_mem ;
2392
+ skb_reserve (skb , QETH_FAKE_LL_LEN_TR );
2393
+ } else {
2394
+ if (!(skb = qeth_get_skb (skb_len +
2395
+ QETH_FAKE_LL_LEN_ETH , * hdr )))
2396
+ goto no_mem ;
2397
+ skb_reserve (skb , QETH_FAKE_LL_LEN_ETH );
2398
+ }
2301
2399
} else {
2302
- if (!(skb = qeth_get_skb (skb_len + QETH_FAKE_LL_LEN_ETH , * hdr )))
2400
+ skb = qeth_get_skb (skb_len , * hdr );
2401
+ if (!skb )
2303
2402
goto no_mem ;
2304
- skb_reserve (skb ,QETH_FAKE_LL_LEN_ETH );
2305
2403
}
2306
- } else if (!( skb = qeth_get_skb ( skb_len , * hdr )))
2307
- goto no_mem ;
2404
+ }
2405
+
2308
2406
data_ptr = element -> addr + offset ;
2309
2407
while (skb_len ) {
2310
2408
data_len = min (skb_len , (int )(element -> length - offset ));
2311
- if (data_len )
2312
- memcpy (skb_put (skb , data_len ), data_ptr , data_len );
2409
+ if (data_len ) {
2410
+ if (use_rx_sg ) {
2411
+ if (qeth_create_skb_frag (element , & skb , offset ,
2412
+ & frag , data_len ))
2413
+ goto no_mem ;
2414
+ } else {
2415
+ memcpy (skb_put (skb , data_len ), data_ptr ,
2416
+ data_len );
2417
+ }
2418
+ }
2313
2419
skb_len -= data_len ;
2314
2420
if (skb_len ){
2315
2421
if (qeth_is_last_sbale (element )){
@@ -2331,6 +2437,10 @@ qeth_get_next_skb(struct qeth_card *card, struct qdio_buffer *buffer,
2331
2437
}
2332
2438
* __element = element ;
2333
2439
* __offset = offset ;
2440
+ if (use_rx_sg && card -> options .performance_stats ) {
2441
+ card -> perf_stats .sg_skbs_rx ++ ;
2442
+ card -> perf_stats .sg_frags_rx += skb_shinfo (skb )-> nr_frags ;
2443
+ }
2334
2444
return skb ;
2335
2445
no_mem :
2336
2446
if (net_ratelimit ()){
@@ -2608,28 +2718,15 @@ qeth_process_inbound_buffer(struct qeth_card *card,
2608
2718
}
2609
2719
}
2610
2720
2611
- static struct qeth_buffer_pool_entry *
2612
- qeth_get_buffer_pool_entry (struct qeth_card * card )
2613
- {
2614
- struct qeth_buffer_pool_entry * entry ;
2615
-
2616
- QETH_DBF_TEXT (trace , 6 , "gtbfplen" );
2617
- if (!list_empty (& card -> qdio .in_buf_pool .entry_list )) {
2618
- entry = list_entry (card -> qdio .in_buf_pool .entry_list .next ,
2619
- struct qeth_buffer_pool_entry , list );
2620
- list_del_init (& entry -> list );
2621
- return entry ;
2622
- }
2623
- return NULL ;
2624
- }
2625
-
2626
- static void
2721
+ static int
2627
2722
qeth_init_input_buffer (struct qeth_card * card , struct qeth_qdio_buffer * buf )
2628
2723
{
2629
2724
struct qeth_buffer_pool_entry * pool_entry ;
2630
2725
int i ;
2631
-
2632
- pool_entry = qeth_get_buffer_pool_entry (card );
2726
+
2727
+ pool_entry = qeth_find_free_buffer_pool_entry (card );
2728
+ if (!pool_entry )
2729
+ return 1 ;
2633
2730
/*
2634
2731
* since the buffer is accessed only from the input_tasklet
2635
2732
* there shouldn't be a need to synchronize; also, since we use
@@ -2648,6 +2745,7 @@ qeth_init_input_buffer(struct qeth_card *card, struct qeth_qdio_buffer *buf)
2648
2745
buf -> buffer -> element [i ].flags = 0 ;
2649
2746
}
2650
2747
buf -> state = QETH_QDIO_BUF_EMPTY ;
2748
+ return 0 ;
2651
2749
}
2652
2750
2653
2751
static void
@@ -2682,6 +2780,7 @@ qeth_queue_input_buffer(struct qeth_card *card, int index)
2682
2780
int count ;
2683
2781
int i ;
2684
2782
int rc ;
2783
+ int newcount = 0 ;
2685
2784
2686
2785
QETH_DBF_TEXT (trace ,6 ,"queinbuf" );
2687
2786
count = (index < queue -> next_buf_to_init )?
@@ -2692,9 +2791,27 @@ qeth_queue_input_buffer(struct qeth_card *card, int index)
2692
2791
/* only requeue at a certain threshold to avoid SIGAs */
2693
2792
if (count >= QETH_IN_BUF_REQUEUE_THRESHOLD (card )){
2694
2793
for (i = queue -> next_buf_to_init ;
2695
- i < queue -> next_buf_to_init + count ; ++ i )
2696
- qeth_init_input_buffer (card ,
2697
- & queue -> bufs [i % QDIO_MAX_BUFFERS_PER_Q ]);
2794
+ i < queue -> next_buf_to_init + count ; ++ i ) {
2795
+ if (qeth_init_input_buffer (card ,
2796
+ & queue -> bufs [i % QDIO_MAX_BUFFERS_PER_Q ])) {
2797
+ break ;
2798
+ } else {
2799
+ newcount ++ ;
2800
+ }
2801
+ }
2802
+
2803
+ if (newcount < count ) {
2804
+ /* we are in memory shortage so we switch back to
2805
+ traditional skb allocation and drop packages */
2806
+ if (atomic_cmpxchg (& card -> force_alloc_skb , 0 , 1 ))
2807
+ printk (KERN_WARNING
2808
+ "qeth: switch to alloc skb\n" );
2809
+ count = newcount ;
2810
+ } else {
2811
+ if (atomic_cmpxchg (& card -> force_alloc_skb , 1 , 0 ))
2812
+ printk (KERN_WARNING "qeth: switch to sg\n" );
2813
+ }
2814
+
2698
2815
/*
2699
2816
* according to old code it should be avoided to requeue all
2700
2817
* 128 buffers in order to benefit from PCI avoidance.
@@ -6494,6 +6611,7 @@ qeth_hardsetup_card(struct qeth_card *card)
6494
6611
6495
6612
QETH_DBF_TEXT (setup , 2 , "hrdsetup" );
6496
6613
6614
+ atomic_set (& card -> force_alloc_skb , 0 );
6497
6615
retry :
6498
6616
if (retries < 3 ){
6499
6617
PRINT_WARN ("Retrying to do IDX activates.\n" );
0 commit comments