- Adding checks to check the return value of pci mapping function Signed-off-by: Veena Parat <[EMAIL PROTECTED]> --- diff -Nurp 2.0.23.1/drivers/net/s2io.c 2.0.23.1P1/drivers/net/s2io.c --- 2.0.23.1/drivers/net/s2io.c 2007-07-03 08:54:02.000000000 -0700 +++ 2.0.23.1P1/drivers/net/s2io.c 2007-07-03 11:39:24.000000000 -0700 @@ -282,6 +282,7 @@ static char ethtool_driver_stats_keys[][ ("lro_flush_due_to_max_pkts"), ("lro_avg_aggr_pkts"), ("mem_alloc_fail_cnt"), + {"pci_map_fail_cnt"}, ("watchdog_timer_cnt"), ("mem_allocated"), ("mem_freed"), @@ -2236,10 +2237,19 @@ static int fill_rxd_3buf(struct s2io_nic (nic->pdev, skb->data, l3l4hdr_size + 4, PCI_DMA_FROMDEVICE); + if ((((struct RxD3*)rxdp)->Buffer1_ptr == 0) || + (((struct RxD3*)rxdp)->Buffer1_ptr == DMA_ERROR_CODE)) { + nic->mac_control.stats_info->sw_stat.pci_map_fail_cnt++; + return -ENOMEM; + } + /* skb_shinfo(skb)->frag_list will have L4 data payload */ skb_shinfo(skb)->frag_list = dev_alloc_skb(dev->mtu + ALIGN_SIZE); if (skb_shinfo(skb)->frag_list == NULL) { nic->mac_control.stats_info->sw_stat.mem_alloc_fail_cnt++; + pci_unmap_single + (nic->pdev, (dma_addr_t)skb->data, l3l4hdr_size + 4, + PCI_DMA_FROMDEVICE); DBG_PRINT(INFO_DBG, "%s: dev_alloc_skb failed\n ", dev->name); return -ENOMEM ; } @@ -2256,6 +2266,11 @@ static int fill_rxd_3buf(struct s2io_nic ((struct RxD3*)rxdp)->Buffer2_ptr = pci_map_single(nic->pdev, frag_list->data, dev->mtu, PCI_DMA_FROMDEVICE); + if ((((struct RxD3*)rxdp)->Buffer2_ptr == 0) || + (((struct RxD3*)rxdp)->Buffer2_ptr == DMA_ERROR_CODE)) { + nic->mac_control.stats_info->sw_stat.pci_map_fail_cnt++; + return -ENOMEM; + } rxdp->Control_2 |= SET_BUFFER1_SIZE_3(l3l4hdr_size + 4); rxdp->Control_2 |= SET_BUFFER2_SIZE_3(dev->mtu); @@ -2388,6 +2403,16 @@ static int fill_rx_buffers(struct s2io_n ((struct RxD1*)rxdp)->Buffer0_ptr = pci_map_single (nic->pdev, skb->data, size - NET_IP_ALIGN, PCI_DMA_FROMDEVICE); + if ((((struct RxD1*)rxdp)->Buffer0_ptr == 0) || + (((struct RxD1*)rxdp)->Buffer0_ptr == + DMA_ERROR_CODE)) { + nic->mac_control.stats_info->sw_stat. + pci_map_fail_cnt++; + nic->mac_control.stats_info->sw_stat.mem_freed + += skb->truesize; + dev_kfree_skb_irq(skb); + return -ENOMEM; + } rxdp->Control_2 = SET_BUFFER0_SIZE_1(size - NET_IP_ALIGN); @@ -2419,14 +2444,19 @@ static int fill_rx_buffers(struct s2io_n skb->data = (void *) (unsigned long)tmp; skb_reset_tail_pointer(skb); - if (!(((struct RxD3*)rxdp)->Buffer0_ptr)) - ((struct RxD3*)rxdp)->Buffer0_ptr = - pci_map_single(nic->pdev, ba->ba_0, BUF0_LEN, - PCI_DMA_FROMDEVICE); - else - pci_dma_sync_single_for_device(nic->pdev, - (dma_addr_t) ((struct RxD3*)rxdp)->Buffer0_ptr, - BUF0_LEN, PCI_DMA_FROMDEVICE); + ((struct RxD3*)rxdp)->Buffer0_ptr = + pci_map_single(nic->pdev, ba->ba_0, BUF0_LEN, + PCI_DMA_FROMDEVICE); + if ((((struct RxD3*)rxdp)->Buffer0_ptr == 0) || + (((struct RxD3*)rxdp)->Buffer0_ptr == + DMA_ERROR_CODE)) { + nic->mac_control.stats_info->sw_stat. + pci_map_fail_cnt++; + nic->mac_control.stats_info->sw_stat.mem_freed + += skb->truesize; + dev_kfree_skb_irq(skb); + return -ENOMEM; + } rxdp->Control_2 = SET_BUFFER0_SIZE_3(BUF0_LEN); if (nic->rxd_mode == RXD_MODE_3B) { /* Two buffer mode */ @@ -2436,15 +2466,37 @@ static int fill_rx_buffers(struct s2io_n * L4 payload */ ((struct RxD3*)rxdp)->Buffer2_ptr = pci_map_single - (nic->pdev, skb->data, dev->mtu + 4, - PCI_DMA_FROMDEVICE); + (nic->pdev, skb->data, dev->mtu + 4, + PCI_DMA_FROMDEVICE); + if ((((struct RxD3*)rxdp)->Buffer2_ptr == 0) || + (((struct RxD3*)rxdp)->Buffer2_ptr == + DMA_ERROR_CODE)) { + nic->mac_control.stats_info->sw_stat. + pci_map_fail_cnt++; + nic->mac_control.stats_info->sw_stat. + mem_freed += skb->truesize; + dev_kfree_skb_irq(skb); + return -ENOMEM; + } - /* Buffer-1 will be dummy buffer. Not used */ - if (!(((struct RxD3*)rxdp)->Buffer1_ptr)) { - ((struct RxD3*)rxdp)->Buffer1_ptr = + ((struct RxD3*)rxdp)->Buffer1_ptr = pci_map_single(nic->pdev, ba->ba_1, BUF1_LEN, PCI_DMA_FROMDEVICE); + if ((((struct RxD3*)rxdp)->Buffer1_ptr == 0) || + (((struct RxD3*)rxdp)->Buffer1_ptr == + DMA_ERROR_CODE)) { + nic->mac_control.stats_info->sw_stat. + pci_map_fail_cnt++; + nic->mac_control.stats_info->sw_stat. + mem_freed += skb->truesize; + pci_unmap_single + (nic->pdev, + (dma_addr_t)skb->data, + dev->mtu + 4, + PCI_DMA_FROMDEVICE); + dev_kfree_skb_irq(skb); + return -ENOMEM; } rxdp->Control_2 |= SET_BUFFER1_SIZE_3(1); rxdp->Control_2 |= SET_BUFFER2_SIZE_3 @@ -2644,7 +2696,8 @@ static int s2io_poll(struct net_device * for (i = 0; i < config->rx_ring_num; i++) { if (fill_rx_buffers(nic, i) == -ENOMEM) { - DBG_PRINT(INFO_DBG, "%s:Out of memory", dev->name); + DBG_PRINT(INFO_DBG, "%s - %s:Out of memory", + __FUNCTION__, dev->name); DBG_PRINT(INFO_DBG, " in Rx Poll!!\n"); break; } @@ -2661,7 +2714,8 @@ no_rx: for (i = 0; i < config->rx_ring_num; i++) { if (fill_rx_buffers(nic, i) == -ENOMEM) { - DBG_PRINT(INFO_DBG, "%s:Out of memory", dev->name); + DBG_PRINT(INFO_DBG, "%s - %s:Out of memory", + __FUNCTION__, dev->name); DBG_PRINT(INFO_DBG, " in Rx Poll!!\n"); break; } @@ -2711,7 +2765,8 @@ static void s2io_netpoll(struct net_devi for (i = 0; i < config->rx_ring_num; i++) { if (fill_rx_buffers(nic, i) == -ENOMEM) { - DBG_PRINT(INFO_DBG, "%s:Out of memory", dev->name); + DBG_PRINT(INFO_DBG, "%s - %s:Out of memory", + __FUNCTION__, dev->name); DBG_PRINT(INFO_DBG, " in Rx Netpoll!!\n"); break; } @@ -2792,24 +2847,27 @@ static void rx_intr_handler(struct ring_ HEADER_SNAP_SIZE, PCI_DMA_FROMDEVICE); } else if (nic->rxd_mode == RXD_MODE_3B) { - pci_dma_sync_single_for_cpu(nic->pdev, (dma_addr_t) + pci_unmap_single(nic->pdev, (dma_addr_t) ((struct RxD3*)rxdp)->Buffer0_ptr, BUF0_LEN, PCI_DMA_FROMDEVICE); pci_unmap_single(nic->pdev, (dma_addr_t) + ((struct RxD3*)rxdp)->Buffer1_ptr, + BUF1_LEN, PCI_DMA_FROMDEVICE); + pci_unmap_single(nic->pdev, (dma_addr_t) ((struct RxD3*)rxdp)->Buffer2_ptr, dev->mtu + 4, PCI_DMA_FROMDEVICE); } else { - pci_dma_sync_single_for_cpu(nic->pdev, (dma_addr_t) - ((struct RxD3*)rxdp)->Buffer0_ptr, BUF0_LEN, - PCI_DMA_FROMDEVICE); pci_unmap_single(nic->pdev, (dma_addr_t) - ((struct RxD3*)rxdp)->Buffer1_ptr, - l3l4hdr_size + 4, - PCI_DMA_FROMDEVICE); + ((struct RxD3*)rxdp)->Buffer0_ptr, BUF0_LEN, + PCI_DMA_FROMDEVICE); pci_unmap_single(nic->pdev, (dma_addr_t) - ((struct RxD3*)rxdp)->Buffer2_ptr, - dev->mtu, PCI_DMA_FROMDEVICE); + ((struct RxD3*)rxdp)->Buffer1_ptr, + l3l4hdr_size + 4, + PCI_DMA_FROMDEVICE); + pci_unmap_single(nic->pdev, (dma_addr_t) + ((struct RxD3*)rxdp)->Buffer2_ptr, + dev->mtu, PCI_DMA_FROMDEVICE); } prefetch(skb->data); rx_osm_handler(ring_data, rxdp); @@ -4072,11 +4130,33 @@ static int s2io_xmit(struct sk_buff *skb txdp->Buffer_Pointer = pci_map_single(sp->pdev, sp->ufo_in_band_v, sizeof(u64), PCI_DMA_TODEVICE); + if ((txdp->Buffer_Pointer == 0) || + (txdp->Buffer_Pointer == DMA_ERROR_CODE)) { + sp->mac_control.stats_info->sw_stat.pci_map_fail_cnt++; + netif_stop_queue(dev); + sp->mac_control.stats_info->sw_stat.mem_freed += + skb->truesize; + dev_kfree_skb(skb); + spin_unlock_irqrestore(&sp->tx_lock, flags); + return 0; + } txdp++; } txdp->Buffer_Pointer = pci_map_single (sp->pdev, skb->data, frg_len, PCI_DMA_TODEVICE); + + if ((txdp->Buffer_Pointer == 0) || + (txdp->Buffer_Pointer == DMA_ERROR_CODE)) { + sp->mac_control.stats_info->sw_stat.pci_map_fail_cnt++; + netif_stop_queue(dev); + sp->mac_control.stats_info->sw_stat.mem_freed += + skb->truesize; + dev_kfree_skb(skb); + spin_unlock_irqrestore(&sp->tx_lock, flags); + return 0; + } + txdp->Host_Control = (unsigned long) skb; txdp->Control_1 |= TXD_BUFFER0_SIZE(frg_len); if (offload_type == SKB_GSO_UDP) @@ -4165,11 +4245,13 @@ static int s2io_chk_rx_buffers(struct s2 clear_bit(0, (&sp->tasklet_status)); } else if (level == LOW) tasklet_schedule(&sp->task); - - } else if (fill_rx_buffers(sp, rng_n) == -ENOMEM) { - DBG_PRINT(INFO_DBG, "%s:Out of memory", sp->dev->name); + } else { + if (fill_rx_buffers(sp, rng_n) == -ENOMEM) { + DBG_PRINT(INFO_DBG, "%s - %s:Out of memory", + __FUNCTION__, sp->dev->name); DBG_PRINT(INFO_DBG, " in Rx Intr!!\n"); } + } return 0; } @@ -5906,6 +5988,7 @@ static void s2io_get_ethtool_stats(struc else tmp_stats[i++] = 0; tmp_stats[i++] = stat_info->sw_stat.mem_alloc_fail_cnt; + tmp_stats[i++] = stat_info->sw_stat.pci_map_fail_cnt; tmp_stats[i++] = stat_info->sw_stat.watchdog_timer_cnt; tmp_stats[i++] = stat_info->sw_stat.mem_allocated; tmp_stats[i++] = stat_info->sw_stat.mem_freed; @@ -6148,8 +6231,8 @@ static void s2io_tasklet(unsigned long d for (i = 0; i < config->rx_ring_num; i++) { ret = fill_rx_buffers(sp, i); if (ret == -ENOMEM) { - DBG_PRINT(INFO_DBG, "%s: Out of ", - dev->name); + DBG_PRINT(INFO_DBG, "%s- %s: Out of ", + __FUNCTION__, dev->name); DBG_PRINT(INFO_DBG, "memory in tasklet\n"); break; } else if (ret == -EFILL) { @@ -6281,6 +6364,16 @@ static int set_rxd_buffer_pointer(struct pci_map_single( sp->pdev, (*skb)->data, size - NET_IP_ALIGN, PCI_DMA_FROMDEVICE); + if ((((struct RxD1*)rxdp)->Buffer0_ptr == 0) || + (((struct RxD1*)rxdp)->Buffer0_ptr == + DMA_ERROR_CODE)) { + sp->mac_control.stats_info->sw_stat. + pci_map_fail_cnt++; + sp->mac_control.stats_info->sw_stat.mem_freed += + (*skb)->truesize; + dev_kfree_skb(*skb); + return -ENOMEM; + } rxdp->Host_Control = (unsigned long) (*skb); } } else if ((sp->rxd_mode == RXD_MODE_3B) && (rxdp->Host_Control == 0)) { @@ -6305,15 +6398,51 @@ static int set_rxd_buffer_pointer(struct pci_map_single(sp->pdev, (*skb)->data, dev->mtu + 4, PCI_DMA_FROMDEVICE); + if ((((struct RxD3*)rxdp)->Buffer2_ptr == 0) || + (((struct RxD3*)rxdp)->Buffer2_ptr == + DMA_ERROR_CODE)) { + sp->mac_control.stats_info->sw_stat. + pci_map_fail_cnt++; + sp->mac_control.stats_info->sw_stat.mem_freed += + (*skb)->truesize; + dev_kfree_skb(*skb); + return -ENOMEM; + } ((struct RxD3*)rxdp)->Buffer0_ptr = *temp0 = pci_map_single( sp->pdev, ba->ba_0, BUF0_LEN, PCI_DMA_FROMDEVICE); + if ((((struct RxD3*)rxdp)->Buffer0_ptr == 0) || + (((struct RxD3*)rxdp)->Buffer0_ptr == + DMA_ERROR_CODE)) { + sp->mac_control.stats_info->sw_stat. + pci_map_fail_cnt++; + sp->mac_control.stats_info->sw_stat.mem_freed += + (*skb)->truesize; + pci_unmap_single (sp->pdev, + (dma_addr_t)(*skb)->data, + dev->mtu + 4, PCI_DMA_FROMDEVICE); + dev_kfree_skb(*skb); + return -ENOMEM; + } rxdp->Host_Control = (unsigned long) (*skb); /* Buffer-1 will be dummy buffer not used */ ((struct RxD3*)rxdp)->Buffer1_ptr = *temp1 = pci_map_single(sp->pdev, ba->ba_1, BUF1_LEN, PCI_DMA_FROMDEVICE); + if ((((struct RxD3*)rxdp)->Buffer0_ptr == 0) || + (((struct RxD3*)rxdp)->Buffer0_ptr == + DMA_ERROR_CODE)) { + sp->mac_control.stats_info->sw_stat. + pci_map_fail_cnt++; + sp->mac_control.stats_info->sw_stat.mem_freed += + (*skb)->truesize; + pci_unmap_single (sp->pdev, + (dma_addr_t)(*skb)->data, + dev->mtu + 4, PCI_DMA_FROMDEVICE); + dev_kfree_skb(*skb); + return -ENOMEM; + } } } else if ((rxdp->Host_Control == 0)) { /* Three buffer mode */ @@ -6336,11 +6465,31 @@ static int set_rxd_buffer_pointer(struct ((struct RxD3*)rxdp)->Buffer0_ptr = *temp0 = pci_map_single(sp->pdev, ba->ba_0, BUF0_LEN, PCI_DMA_FROMDEVICE); + if ((((struct RxD3*)rxdp)->Buffer0_ptr == 0) || + (((struct RxD3*)rxdp)->Buffer0_ptr == + DMA_ERROR_CODE)) { + sp->mac_control.stats_info->sw_stat. + pci_map_fail_cnt++; + sp->mac_control.stats_info->sw_stat.mem_freed += + (*skb)->truesize; + dev_kfree_skb(*skb); + return -ENOMEM; + } /* Buffer-1 receives L3/L4 headers */ ((struct RxD3*)rxdp)->Buffer1_ptr = *temp1 = pci_map_single( sp->pdev, (*skb)->data, l3l4hdr_size + 4, PCI_DMA_FROMDEVICE); + if ((((struct RxD3*)rxdp)->Buffer1_ptr == 0) || + (((struct RxD3*)rxdp)->Buffer1_ptr == + DMA_ERROR_CODE)) { + sp->mac_control.stats_info->sw_stat. + pci_map_fail_cnt++; + sp->mac_control.stats_info->sw_stat.mem_freed += + (*skb)->truesize; + dev_kfree_skb(*skb); + return -ENOMEM; + } /* * skb_shinfo(skb)->frag_list will have L4 * data payload @@ -6352,10 +6501,17 @@ static int set_rxd_buffer_pointer(struct failed\n ", dev->name); sp->mac_control.stats_info->sw_stat. \ mem_alloc_fail_cnt++; + sp->mac_control.stats_info->sw_stat.mem_freed + += (*skb)->truesize; + pci_unmap_single (sp->pdev, + (dma_addr_t)(*skb)->data, + l3l4hdr_size + 4, PCI_DMA_FROMDEVICE); + dev_kfree_skb(*skb); return -ENOMEM ; } frag_list = skb_shinfo(*skb)->frag_list; frag_list->next = NULL; + (*skb)->truesize += frag_list->truesize; sp->mac_control.stats_info->sw_stat.mem_allocated += frag_list->truesize; /* @@ -6364,6 +6520,19 @@ static int set_rxd_buffer_pointer(struct ((struct RxD3*)rxdp)->Buffer2_ptr = *temp2 = pci_map_single( sp->pdev, frag_list->data, dev->mtu, PCI_DMA_FROMDEVICE); + if ((((struct RxD3*)rxdp)->Buffer2_ptr == 0) || + (((struct RxD3*)rxdp)->Buffer2_ptr == + DMA_ERROR_CODE)) { + sp->mac_control.stats_info->sw_stat. + pci_map_fail_cnt++; + sp->mac_control.stats_info->sw_stat.mem_freed += + (*skb)->truesize; + pci_unmap_single (sp->pdev, + (dma_addr_t)(*skb)->data, + l3l4hdr_size + 4, PCI_DMA_FROMDEVICE); + dev_kfree_skb(*skb); + return -ENOMEM; + } } } return 0; @@ -6658,8 +6827,8 @@ static int s2io_card_up(struct s2io_nic for (i = 0; i < config->rx_ring_num; i++) { if ((ret = fill_rx_buffers(sp, i))) { - DBG_PRINT(ERR_DBG, "%s: Out of memory in Open\n", - dev->name); + DBG_PRINT(ERR_DBG, "%s - %s: Out of memory in Open\n", + __FUNCTION__, dev->name); s2io_reset(sp); free_rx_buffers(sp); return -ENOMEM; diff -Nurp 2.0.23.1/drivers/net/s2io.h 2.0.23.1P1/drivers/net/s2io.h --- 2.0.23.1/drivers/net/s2io.h 2007-07-03 08:54:02.000000000 -0700 +++ 2.0.23.1P1/drivers/net/s2io.h 2007-07-03 11:39:27.000000000 -0700 @@ -74,6 +74,10 @@ static int debug_level = ERR_DBG; /* DEBUG message print. */ #define DBG_PRINT(dbg_level, args...) if(!(debug_level<dbg_level)) printk(args) +#ifndef DMA_ERROR_CODE +#define DMA_ERROR_CODE (~(dma_addr_t)0x0) +#endif + /* Protocol assist features of the NIC */ #define L3_CKSUM_OK 0xFFFF #define L4_CKSUM_OK 0xFFFF @@ -97,6 +101,7 @@ struct swStat { unsigned long long num_aggregations; /* Other statistics */ unsigned long long mem_alloc_fail_cnt; + unsigned long long pci_map_fail_cnt; unsigned long long watchdog_timer_cnt; unsigned long long mem_allocated; unsigned long long mem_freed; @@ -851,6 +856,7 @@ struct s2io_nic { int task_flag; unsigned long long start_time; + unsigned long long max_mem; #define CARD_DOWN 1 #define CARD_UP 2 atomic_t card_state;
- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html