fix problems with NETIF_F_HIGHDMA in networking drivers
Subsystems (5)
RFC PATCH 1/1 fix problems with NETIF_F_HIGHDMA in networking drivers
Many networking drivers have issues with the use of the NETIF_F_HIGHDMA flag. This flag actually indicates whether or not the device/driver can handle skbs located in high memory (as opposed to lowmem). However, many drivers incorrectly treat this flag as indicating that 64-bit DMA is supported, which has nothing to do with its actual function. It makes no sense to make setting NETIF_F_HIGHDMA conditional on whether a 64-bit DMA mask has been set, as many drivers do, since if highmem DMA is supported at all, it should work regardless of whether 64-bit DMA is supported. Failing to set NETIF_F_HIGHDMA when it should be can hurt performance on architectures which use highmem since it results in needless data copying.
This fixes up the networking drivers which currently use NETIF_F_HIGHDMA to not do so conditionally on DMA mask settings.
For the USB kaweth and usbnet drivers, this patch also uncomments and corrects some code to set NETIF_F_HIGHDMA based on the USB host controller's DMA mask. These drivers should be able to access highmem unless the host controller is non-DMA-capable, which is indicated by the DMA mask being null.
---
Comments welcome on the approach. Not sure what the protocol is with a patch touching so many drivers - should the maintainers all be CCed?
drivers/net/8139cp.c +1 -2
@@ -1967,8 +1967,7 @@ static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) dev->features |=NETIF_F_HW_VLAN_TX |NETIF_F_HW_VLAN_RX ;#endif -if (pci_using_dac) - dev->features |=NETIF_F_HIGHDMA ; + dev->features |=NETIF_F_HIGHDMA ;#if 0 /* disabled by default until verified */ dev->features |=NETIF_F_TSO ;
drivers/net/acenic.c +1 -4
@@ -607,8 +607,7 @@ static int __devinit acenic_probe_one(struct pci_dev *pdev, } ap->name = dev->name; -if (ap->pci_using_dac) - dev->features |=NETIF_F_HIGHDMA ; + dev->features |=NETIF_F_HIGHDMA ;pci_set_drvdata (pdev, dev);
@@ -1162,9 +1161,7 @@ static int __devinit ace_init(struct net_device *dev)* Configure DMA attributes. */ if (!pci_set_dma_mask (pdev,DMA_BIT_MASK (64 ))) { - ap->pci_using_dac =1 ; }else if (!pci_set_dma_mask (pdev,DMA_BIT_MASK (32 ))) { - ap->pci_using_dac =0 ; }else { ecode = -ENODEV ; goto init_error;
drivers/net/acenic.h +0 -1
@@ -693,7 +693,6 @@ struct ace_private __attribute__ ((aligned (SMP_CACHE_BYTES)));u32 last_tx, last_std_rx, last_mini_rx;#endif -int pci_using_dac;u8 firmware_major;u8 firmware_minor;u8 firmware_fix;
drivers/net/benet/be_main.c +3 -3
@@ -2337,9 +2337,7 @@ static int __devinit be_probe(struct pci_dev *pdev,be_msix_enable (adapter); status =pci_set_dma_mask (pdev,DMA_BIT_MASK (64 )); -if (!status) { - netdev->features |=NETIF_F_HIGHDMA ; - }else { +if (status) { status =pci_set_dma_mask (pdev,DMA_BIT_MASK (32 ));if (status) {dev_err (&pdev->dev,"Could not set PCI DMA Mask\n" );
@@ -2347,6 +2345,8 @@ static int __devinit be_probe(struct pci_dev *pdev, } } + netdev->features |=NETIF_F_HIGHDMA ; + status =be_ctrl_init (adapter);if (status) goto free_netdev;
drivers/net/bnx2.c +2 -1
@@ -7948,9 +7948,10 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)else persist_dma_mask = dma_mask =DMA_BIT_MASK (64 ); + dev->features |=NETIF_F_HIGHDMA ; +/* Configure DMA attributes. */ if (pci_set_dma_mask (pdev, dma_mask) ==0 ) { - dev->features |=NETIF_F_HIGHDMA ; rc =pci_set_consistent_dma_mask (pdev, persist_dma_mask);if (rc) { dev_err(&pdev->dev,
drivers/net/bnx2x_main.c +2 -4
@@ -11871,8 +11871,7 @@ static int __devinit bnx2x_init_dev(struct pci_dev *pdev, dev->ethtool_ops = &bnx2x_ethtool_ops; dev->features |=NETIF_F_SG ; dev->features |=NETIF_F_HW_CSUM ; -if (bp->flags &USING_DAC_FLAG ) - dev->features |=NETIF_F_HIGHDMA ; + dev->features |=NETIF_F_HIGHDMA ; dev->features |= (NETIF_F_TSO |NETIF_F_TSO_ECN ); dev->features |=NETIF_F_TSO6 ;#ifdef BCM_VLAN
@@ -11881,8 +11880,7 @@ static int __devinit bnx2x_init_dev(struct pci_dev *pdev, dev->vlan_features |=NETIF_F_SG ; dev->vlan_features |=NETIF_F_HW_CSUM ; -if (bp->flags &USING_DAC_FLAG ) - dev->vlan_features |=NETIF_F_HIGHDMA ; + dev->vlan_features |=NETIF_F_HIGHDMA ; dev->vlan_features |= (NETIF_F_TSO |NETIF_F_TSO_ECN ); dev->vlan_features |=NETIF_F_TSO6 ;#endif
drivers/net/cassini.c +2 -5
@@ -4938,7 +4938,7 @@ static int __devinit cas_init_one(struct pci_dev *pdev,unsigned long casreg_len;struct net_device *dev;struct cas *cp; -int i, err, pci_using_dac; +int i, err;u16 pci_cmd;u8 orig_cacheline_size =0 , cas_cacheline_size =0 ;
@@ -5012,7 +5012,6 @@ static int __devinit cas_init_one(struct pci_dev *pdev,/* Configure DMA attributes. */ if (!pci_set_dma_mask (pdev,DMA_BIT_MASK (64 ))) { - pci_using_dac =1 ; err =pci_set_consistent_dma_mask (pdev,DMA_BIT_MASK (64 ));if (err <0 ) {
@@ -5028,7 +5027,6 @@ static int __devinit cas_init_one(struct pci_dev *pdev, "aborting\n"); goto err_out_free_res; } - pci_using_dac =0 ; } casreg_len =pci_resource_len (pdev,0 );
@@ -5133,8 +5131,7 @@ static int __devinit cas_init_one(struct pci_dev *pdev,if ((cp->cas_flags &CAS_FLAG_NO_HW_CSUM ) ==0 ) dev->features |=NETIF_F_HW_CSUM |NETIF_F_SG ; -if (pci_using_dac) - dev->features |=NETIF_F_HIGHDMA ; + dev->features |=NETIF_F_HIGHDMA ;if (register_netdev (dev)) {dev_err (&pdev->dev,"Cannot register net device, aborting\n" );
drivers/net/chelsio/cxgb2.c +3 -6
@@ -1001,7 +1001,7 @@ static int __devinit init_one(struct pci_dev *pdev, {static int version_printed; -int i, err, pci_using_dac =0 ; +int i, err;unsigned long mmio_start, mmio_len;const struct board_info *bi;struct adapter *adapter =NULL ;
@@ -1025,8 +1025,6 @@ static int __devinit init_one(struct pci_dev *pdev, }if (!pci_set_dma_mask (pdev,DMA_BIT_MASK (64 ))) { - pci_using_dac =1 ; -if (pci_set_consistent_dma_mask (pdev,DMA_BIT_MASK (64 ))) {CH_ERR ("%s: unable to obtain 64-bit DMA for " "consistent allocations\n" ,pci_name (pdev));
@@ -1108,9 +1106,8 @@ static int __devinit init_one(struct pci_dev *pdev, netdev->features |=NETIF_F_SG |NETIF_F_IP_CSUM ; netdev->features |=NETIF_F_LLTX ; - adapter->flags |=RX_CSUM_ENABLED |TCP_CSUM_CAPABLE ; -if (pci_using_dac) - netdev->features |=NETIF_F_HIGHDMA ; + adapter->flags |=RX_CSUM_ENABLED |TCP_CSUM_CAPABLE | +NETIF_F_HIGHDMA ;if (vlan_tso_capable (adapter)) {#if defined(CONFIG_VLAN_8021Q ) || defined(CONFIG_VLAN_8021Q_MODULE ) adapter->flags |=VLAN_ACCEL_CAPABLE ;
drivers/net/cxgb3/cxgb3_main.c +2 -4
@@ -3132,7 +3132,7 @@ static int __devinit init_one(struct pci_dev *pdev, {static int version_printed; -int i, err, pci_using_dac =0 ; +int i, err;resource_size_t mmio_start, mmio_len;const struct adapter_info *ai;struct adapter *adapter =NULL ;
@@ -3166,7 +3166,6 @@ static int __devinit init_one(struct pci_dev *pdev, }if (!pci_set_dma_mask (pdev,DMA_BIT_MASK (64 ))) { - pci_using_dac =1 ; err =pci_set_consistent_dma_mask (pdev,DMA_BIT_MASK (64 ));if (err) { dev_err(&pdev->dev, "unable to obtain 64-bit DMA for "
@@ -3243,8 +3242,7 @@ static int __devinit init_one(struct pci_dev *pdev, netdev->mem_end = mmio_start + mmio_len -1 ; netdev->features |=NETIF_F_SG |NETIF_F_IP_CSUM |NETIF_F_TSO ; netdev->features |=NETIF_F_GRO ; -if (pci_using_dac) - netdev->features |=NETIF_F_HIGHDMA ; + netdev->features |=NETIF_F_HIGHDMA ; netdev->features |=NETIF_F_HW_VLAN_TX |NETIF_F_HW_VLAN_RX ; netdev->netdev_ops = &cxgb_netdev_ops;
drivers/net/e1000/e1000_main.c +2 -5
@@ -809,7 +809,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev,static int cards_found =0 ;static int global_quad_port_a =0 ;/* global ksp3 port a indication */ -int i, err, pci_using_dac; +int i, err;u16 eeprom_data =0 ;u16 eeprom_apme_mask =E1000_EEPROM_APME ;int bars, need_ioport;
@@ -828,7 +828,6 @@ static int __devinit e1000_probe(struct pci_dev *pdev,if (!pci_set_dma_mask (pdev,DMA_BIT_MASK (64 )) && !pci_set_consistent_dma_mask (pdev,DMA_BIT_MASK (64 ))) { - pci_using_dac =1 ; }else { err =pci_set_dma_mask (pdev,DMA_BIT_MASK (32 ));if (err) {
@@ -839,7 +838,6 @@ static int __devinit e1000_probe(struct pci_dev *pdev, goto err_dma; } } - pci_using_dac =0 ; } err =pci_request_selected_regions (pdev, bars, e1000_driver_name);
@@ -914,8 +912,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev, (hw->mac_type != e1000_82547)) netdev->features |=NETIF_F_TSO ; -if (pci_using_dac) - netdev->features |=NETIF_F_HIGHDMA ; + netdev->features |=NETIF_F_HIGHDMA ; netdev->vlan_features |=NETIF_F_TSO ; netdev->vlan_features |=NETIF_F_HW_CSUM ;
drivers/net/e1000e/netdev.c +2 -6
@@ -4946,7 +4946,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev,resource_size_t flash_start, flash_len;static int cards_found; -int i, err, pci_using_dac; +int i, err;u16 eeprom_data =0 ;u16 eeprom_apme_mask =E1000_EEPROM_APME ;
@@ -4956,12 +4956,9 @@ static int __devinit e1000_probe(struct pci_dev *pdev,if (err)return err; - pci_using_dac =0 ; err =pci_set_dma_mask (pdev,DMA_BIT_MASK (64 ));if (!err) { err =pci_set_consistent_dma_mask (pdev,DMA_BIT_MASK (64 )); -if (!err) - pci_using_dac =1 ; }else { err =pci_set_dma_mask (pdev,DMA_BIT_MASK (32 ));if (err) {
@@ -5091,8 +5088,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev, netdev->vlan_features |=NETIF_F_HW_CSUM ; netdev->vlan_features |=NETIF_F_SG ; -if (pci_using_dac) - netdev->features |=NETIF_F_HIGHDMA ; + netdev->features |=NETIF_F_HIGHDMA ;if (e1000e_enable_mng_pass_thru (&adapter->hw)) adapter->flags |=FLAG_MNG_PT_ENABLED ;
drivers/net/enic/enic_main.c +1 -4
@@ -1887,7 +1887,6 @@ static int __devinit enic_probe(struct pci_dev *pdev, {struct net_device *netdev;struct enic *enic; -int using_dac =0 ;unsigned int i;int err;
@@ -1956,7 +1955,6 @@ static int __devinit enic_probe(struct pci_dev *pdev, "for consistent allocations, aborting.\n"); goto err_out_release_regions; } - using_dac =1 ; }/* Map vNIC resources from BAR0-5
@@ -2065,8 +2063,7 @@ static int __devinit enic_probe(struct pci_dev *pdev,NETIF_F_TSO6 |NETIF_F_TSO_ECN ;if (ENIC_SETTING (enic,LRO )) netdev->features |=NETIF_F_LRO ; -if (using_dac) - netdev->features |=NETIF_F_HIGHDMA ; + netdev->features |=NETIF_F_HIGHDMA ; enic->csum_rx_enabled =ENIC_SETTING (enic,RXCSUM );
drivers/net/forcedeth.c +2 -2
@@ -5672,6 +5672,8 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i/* copy of device id */ np->device_id = id->device; + dev->features |=NETIF_F_HIGHDMA ; +/* handle different descriptor versions */ if (id->driver_data &DEV_HAS_HIGH_DMA ) {/* packet format 3: supports 40-bit addressing */
@@ -5681,8 +5683,6 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_iif (pci_set_dma_mask (pci_dev,DMA_BIT_MASK (39 )))dev_printk (KERN_INFO , &pci_dev->dev,"64-bit DMA failed, using 32-bit addressing\n" ); -else - dev->features |=NETIF_F_HIGHDMA ;if (pci_set_consistent_dma_mask (pci_dev,DMA_BIT_MASK (39 ))) {dev_printk (KERN_INFO , &pci_dev->dev,"64-bit DMA (consistent) failed, using 32-bit ring buffers\n" );
drivers/net/igb/igb_main.c +2 -6
@@ -1409,7 +1409,7 @@ static int __devinit igb_probe(struct pci_dev *pdev,static int global_quad_port_a;/* global quad port a indication */ const struct e1000_info *ei = igb_info_tbl[ent->driver_data];unsigned long mmio_start, mmio_len; -int err, pci_using_dac; +int err;u16 eeprom_apme_mask =IGB_EEPROM_APME ;u32 part_num;
@@ -1417,12 +1417,9 @@ static int __devinit igb_probe(struct pci_dev *pdev,if (err)return err; - pci_using_dac =0 ; err =pci_set_dma_mask (pdev,DMA_BIT_MASK (64 ));if (!err) { err =pci_set_consistent_dma_mask (pdev,DMA_BIT_MASK (64 )); -if (!err) - pci_using_dac =1 ; }else { err =pci_set_dma_mask (pdev,DMA_BIT_MASK (32 ));if (err) {
@@ -1532,8 +1529,7 @@ static int __devinit igb_probe(struct pci_dev *pdev, netdev->vlan_features |=NETIF_F_IPV6_CSUM ; netdev->vlan_features |=NETIF_F_SG ; -if (pci_using_dac) - netdev->features |=NETIF_F_HIGHDMA ; + netdev->features |=NETIF_F_HIGHDMA ;if (hw->mac.type >= e1000_82576) netdev->features |=NETIF_F_SCTP_CSUM ;
drivers/net/igbvf/netdev.c +2 -7
@@ -2651,18 +2651,15 @@ static int __devinit igbvf_probe(struct pci_dev *pdev,const struct igbvf_info *ei = igbvf_info_tbl[ent->driver_data];static int cards_found; -int err, pci_using_dac; +int err; err =pci_enable_device_mem (pdev);if (err)return err; - pci_using_dac =0 ; err =pci_set_dma_mask (pdev,DMA_BIT_MASK (64 ));if (!err) { err =pci_set_consistent_dma_mask (pdev,DMA_BIT_MASK (64 )); -if (!err) - pci_using_dac =1 ; }else { err =pci_set_dma_mask (pdev,DMA_BIT_MASK (32 ));if (err) {
@@ -2746,9 +2743,7 @@ static int __devinit igbvf_probe(struct pci_dev *pdev, netdev->features |=NETIF_F_IPV6_CSUM ; netdev->features |=NETIF_F_TSO ; netdev->features |=NETIF_F_TSO6 ; - -if (pci_using_dac) - netdev->features |=NETIF_F_HIGHDMA ; + netdev->features |=NETIF_F_HIGHDMA ; netdev->vlan_features |=NETIF_F_TSO ; netdev->vlan_features |=NETIF_F_TSO6 ;
drivers/net/ioc3-eth.c +2 -7
@@ -1236,12 +1236,11 @@ static int __devinit ioc3_probe(struct pci_dev *pdev,struct ioc3 *ioc3;unsigned long ioc3_base, ioc3_size;u32 vendor, model, rev; -int err, pci_using_dac; +int err;/* Configure DMA attributes. */ err =pci_set_dma_mask (pdev,DMA_BIT_MASK (64 ));if (!err) { - pci_using_dac =1 ; err =pci_set_consistent_dma_mask (pdev,DMA_BIT_MASK (64 ));if (err <0 ) { printk(KERN_ERR "%s: Unable to obtain 64 bit DMA "
@@ -1255,7 +1254,6 @@ static int __devinit ioc3_probe(struct pci_dev *pdev, "aborting.\n", pci_name(pdev)); goto out; } - pci_using_dac =0 ; }if (pci_enable_device (pdev))
@@ -1267,9 +1265,6 @@ static int __devinit ioc3_probe(struct pci_dev *pdev, goto out_disable; } -if (pci_using_dac) - dev->features |=NETIF_F_HIGHDMA ; - err =pci_request_regions (pdev,"ioc3" );if (err) goto out_free;
@@ -1326,7 +1321,7 @@ static int __devinit ioc3_probe(struct pci_dev *pdev, dev->watchdog_timeo =5 *HZ ; dev->netdev_ops = &ioc3_netdev_ops; dev->ethtool_ops = &ioc3_ethtool_ops; - dev->features =NETIF_F_IP_CSUM ; + dev->features =NETIF_F_IP_CSUM |NETIF_F_HIGHDMA ; sw_physid1 =ioc3_mdio_read (dev, ip->mii.phy_id,MII_PHYSID1 ); sw_physid2 =ioc3_mdio_read (dev, ip->mii.phy_id,MII_PHYSID2 );
drivers/net/ixgb/ixgb_main.c +1 -6
@@ -360,7 +360,6 @@ ixgb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)struct net_device *netdev =NULL ;struct ixgb_adapter *adapter;static int cards_found =0 ; -int pci_using_dac;int i;int err;
@@ -370,7 +369,6 @@ ixgb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)if (!(err =pci_set_dma_mask (pdev,DMA_BIT_MASK (64 ))) && !(err =pci_set_consistent_dma_mask (pdev,DMA_BIT_MASK (64 )))) { - pci_using_dac =1 ; }else {if ((err =pci_set_dma_mask (pdev,DMA_BIT_MASK (32 ))) || (err =pci_set_consistent_dma_mask (pdev,DMA_BIT_MASK (32 )))) {
@@ -378,7 +376,6 @@ ixgb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) "ixgb: No usable DMA configuration, aborting\n"); goto err_dma_mask; } - pci_using_dac =0 ; } err =pci_request_regions (pdev, ixgb_driver_name);
@@ -440,9 +437,7 @@ ixgb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)NETIF_F_HW_VLAN_RX |NETIF_F_HW_VLAN_FILTER ; netdev->features |=NETIF_F_TSO ; - -if (pci_using_dac) - netdev->features |=NETIF_F_HIGHDMA ; + netdev->features |=NETIF_F_HIGHDMA ;/* make sure the EEPROM is good */
drivers/net/ixgbe/ixgbe_main.c +2 -5
@@ -5968,7 +5968,7 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,struct ixgbe_hw *hw;const struct ixgbe_info *ii = ixgbe_info_tbl[ent->driver_data];static int cards_found; -int i, err, pci_using_dac; +int i, err;#ifdef IXGBE_FCOE u16 device_caps;#endif
@@ -5980,7 +5980,6 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,if (!pci_set_dma_mask (pdev,DMA_BIT_MASK (64 )) && !pci_set_consistent_dma_mask (pdev,DMA_BIT_MASK (64 ))) { - pci_using_dac =1 ; }else { err =pci_set_dma_mask (pdev,DMA_BIT_MASK (32 ));if (err) {
@@ -5991,7 +5990,6 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, goto err_dma; } } - pci_using_dac =0 ; } err = pci_request_selected_regions(pdev, pci_select_bars(pdev,
@@ -6168,8 +6166,7 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, } }#endif /* IXGBE_FCOE */ -if (pci_using_dac) - netdev->features |=NETIF_F_HIGHDMA ; + netdev->features |=NETIF_F_HIGHDMA ;if (adapter->flags2 &IXGBE_FLAG2_RSC_ENABLED ) netdev->features |=NETIF_F_LRO ;
drivers/net/ixgbevf/ixgbevf_main.c +2 -6
@@ -3306,7 +3306,7 @@ static int __devinit ixgbevf_probe(struct pci_dev *pdev,struct ixgbe_hw *hw =NULL ;const struct ixgbevf_info *ii = ixgbevf_info_tbl[ent->driver_data];static int cards_found; -int err, pci_using_dac; +int err; err =pci_enable_device (pdev);if (err)
@@ -3314,7 +3314,6 @@ static int __devinit ixgbevf_probe(struct pci_dev *pdev,if (!pci_set_dma_mask (pdev,DMA_BIT_MASK (64 )) && !pci_set_consistent_dma_mask (pdev,DMA_BIT_MASK (64 ))) { - pci_using_dac =1 ; }else { err =pci_set_dma_mask (pdev,DMA_BIT_MASK (32 ));if (err) {
@@ -3326,7 +3325,6 @@ static int __devinit ixgbevf_probe(struct pci_dev *pdev, goto err_dma; } } - pci_using_dac =0 ; } err =pci_request_regions (pdev, ixgbevf_driver_name);
@@ -3406,9 +3404,7 @@ static int __devinit ixgbevf_probe(struct pci_dev *pdev, netdev->vlan_features |=NETIF_F_TSO6 ; netdev->vlan_features |=NETIF_F_IP_CSUM ; netdev->vlan_features |=NETIF_F_SG ; - -if (pci_using_dac) - netdev->features |=NETIF_F_HIGHDMA ; + netdev->features |=NETIF_F_HIGHDMA ;#endif /* MAX_SKB_FRAGS */
drivers/net/jme.c +5 -5
@@ -669,7 +669,7 @@ jme_set_clean_rxdesc(struct jme_adapter *jme, int i) rxdesc->desc1.bufaddrl =cpu_to_le32 ( (__u64 )rxbi->mapping &0xFFFFFFFFUL ); rxdesc->desc1.datalen =cpu_to_le16 (rxbi->len); -if (jme->dev->features &NETIF_F_HIGHDMA ) +if (jme->using_dac) rxdesc->desc1.flags =RXFLAG_64BIT ;wmb (); rxdesc->desc1.flags |=RXFLAG_OWN |RXFLAG_INT ;
@@ -1743,7 +1743,7 @@ jme_map_tx_skb(struct jme_adapter *jme, struct sk_buff *skb, int idx)struct jme_ring *txring = &(jme->txring[0 ]);struct txdesc *txdesc = txring->desc, *ctxdesc;struct jme_buffer_info *txbi = txring->bufinf, *ctxbi; -u8 hidma = jme->dev->features &NETIF_F_HIGHDMA ; +u8 hidma = jme->using_dac;int i, nr_frags =skb_shinfo (skb)->nr_frags;int mask = jme->tx_ring_mask;struct skb_frag_struct *frag;
@@ -2713,9 +2713,8 @@ jme_init_one(struct pci_dev *pdev,NETIF_F_TSO |NETIF_F_TSO6 |NETIF_F_HW_VLAN_TX | -NETIF_F_HW_VLAN_RX ; -if (using_dac) - netdev->features |=NETIF_F_HIGHDMA ; +NETIF_F_HW_VLAN_RX | +NETIF_F_HIGHDMA ;SET_NETDEV_DEV (netdev, &pdev->dev);pci_set_drvdata (pdev, netdev);
@@ -2743,6 +2742,7 @@ jme_init_one(struct pci_dev *pdev, rc = -ENOMEM ; goto err_out_free_netdev; } + jme->using_dac = using_dac;if (no_pseudohp) { apmc =jread32 (jme,JME_APMC ) & ~JME_APMC_PSEUDO_HP_EN ;
drivers/net/jme.h +1 -0
@@ -387,6 +387,7 @@ struct jme_adapter {struct pci_dev *pdev;struct net_device *dev;void __iomem *regs; +u8 using_dac;struct mii_if_info mii_if;struct jme_ring rxring[RX_RING_NR ];struct jme_ring txring[TX_RING_NR ];
drivers/net/myri10ge/myri10ge.c +1 -5
@@ -3825,7 +3825,6 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)struct device *dev = &pdev->dev;int i;int status = -ENXIO ; -int dac_enabled;unsigned hdr_offset, ss_offset;static int board_number;
@@ -3867,10 +3866,8 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent) }pci_set_master (pdev); - dac_enabled =1 ; status =pci_set_dma_mask (pdev,DMA_BIT_MASK (64 ));if (status !=0 ) { - dac_enabled =0 ;dev_err (&pdev->dev,"64-bit pci address mask was refused, " "trying 32-bit\n" );
@@ -3957,8 +3954,7 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent) netdev->base_addr = mgp->iomem_base; netdev->features = mgp->features; -if (dac_enabled) - netdev->features |=NETIF_F_HIGHDMA ; + netdev->features |=NETIF_F_HIGHDMA ; netdev->features |=NETIF_F_LRO ; netdev->vlan_features |= mgp->features;
drivers/net/netxen/netxen_nic.h +0 -1
@@ -1170,7 +1170,6 @@ struct netxen_adapter {u8 driver_mismatch;u8 msix_supported;u8 rx_csum; -u8 pci_using_dac;u8 portnum;u8 physical_port;
drivers/net/netxen/netxen_nic_main.c +2 -7
@@ -256,8 +256,6 @@ static int nx_set_dma_mask(struct netxen_adapter *adapter)struct pci_dev *pdev = adapter->pdev;uint64_t mask, cmask; - adapter->pci_using_dac =0 ; - mask =DMA_BIT_MASK (32 ); cmask =DMA_BIT_MASK (32 );
@@ -272,7 +270,6 @@ static int nx_set_dma_mask(struct netxen_adapter *adapter)if (pci_set_dma_mask (pdev, mask) ==0 &&pci_set_consistent_dma_mask (pdev, cmask) ==0 ) { - adapter->pci_using_dac =1 ;return 0 ; }
@@ -1207,10 +1204,8 @@ netxen_setup_netdev(struct netxen_adapter *adapter, netdev->vlan_features |= (NETIF_F_IPV6_CSUM |NETIF_F_TSO6 ); } -if (adapter->pci_using_dac) { - netdev->features |=NETIF_F_HIGHDMA ; - netdev->vlan_features |=NETIF_F_HIGHDMA ; - } + netdev->features |=NETIF_F_HIGHDMA ; + netdev->vlan_features |=NETIF_F_HIGHDMA ;if (adapter->capabilities &NX_FW_CAPABILITY_FVLANTX ) netdev->features |= (NETIF_F_HW_VLAN_TX );
drivers/net/niu.c +1 -2
@@ -9823,7 +9823,6 @@ static int __devinit niu_pci_init_one(struct pci_dev *pdev, dma_mask =DMA_BIT_MASK (44 ); err =pci_set_dma_mask (pdev, dma_mask);if (!err) { - dev->features |=NETIF_F_HIGHDMA ; err =pci_set_consistent_dma_mask (pdev, dma_mask);if (err) {dev_err (&pdev->dev,"Unable to obtain 44 bit DMA for consistent allocations, aborting\n" );
@@ -9838,7 +9837,7 @@ static int __devinit niu_pci_init_one(struct pci_dev *pdev, } } - dev->features |= (NETIF_F_SG |NETIF_F_HW_CSUM ); + dev->features |= (NETIF_F_SG |NETIF_F_HW_CSUM |NETIF_F_HIGHDMA ); np->regs =pci_ioremap_bar (pdev,0 );if (!np->regs) {
drivers/net/ns83820.c +1 -5
@@ -2221,11 +2221,7 @@ static int __devinit ns83820_init_one(struct pci_dev *pci_dev, ndev->features |=NETIF_F_HW_VLAN_TX |NETIF_F_HW_VLAN_RX ;#endif -if (using_dac) { -printk (KERN_INFO "%s: using 64 bit addressing.\n" , - ndev->name); - ndev->features |=NETIF_F_HIGHDMA ; - } + ndev->features |=NETIF_F_HIGHDMA ; printk(KERN_INFO "%s: ns83820 v" VERSION ": DP83820 v%u.%u: %pM io=0x%08lx irq=%d f=%s\n", ndev->name,
drivers/net/qla3xxx.c +2 -5
@@ -3922,7 +3922,7 @@ static int __devinit ql3xxx_probe(struct pci_dev *pdev,struct net_device *ndev =NULL ;struct ql3_adapter *qdev =NULL ;static int cards_found =0 ; -int uninitialized_var (pci_using_dac ), err; +int err; err =pci_enable_device (pdev);if (err) {
@@ -3941,10 +3941,8 @@ static int __devinit ql3xxx_probe(struct pci_dev *pdev,pci_set_master (pdev);if (!pci_set_dma_mask (pdev,DMA_BIT_MASK (64 ))) { - pci_using_dac =1 ; err =pci_set_consistent_dma_mask (pdev,DMA_BIT_MASK (64 )); }else if (!(err =pci_set_dma_mask (pdev,DMA_BIT_MASK (32 )))) { - pci_using_dac =0 ; err =pci_set_consistent_dma_mask (pdev,DMA_BIT_MASK (32 )); }
@@ -3977,8 +3975,7 @@ static int __devinit ql3xxx_probe(struct pci_dev *pdev, qdev->msg_enable =netif_msg_init (debug, default_msg); -if (pci_using_dac) - ndev->features |=NETIF_F_HIGHDMA ; + ndev->features |=NETIF_F_HIGHDMA ;if (qdev->device_id ==QL3032_DEVICE_ID ) ndev->features |=NETIF_F_IP_CSUM |NETIF_F_SG ;
drivers/net/qlcnic/qlcnic.h +0 -1
@@ -918,7 +918,6 @@ struct qlcnic_adapter {u8 driver_mismatch;u8 msix_supported;u8 rx_csum; -u8 pci_using_dac;u8 portnum;u8 physical_port;
drivers/net/qlcnic/qlcnic_main.c +2 -7
@@ -239,14 +239,11 @@ static int qlcnic_set_dma_mask(struct qlcnic_adapter *adapter)struct pci_dev *pdev = adapter->pdev;u64 mask, cmask; - adapter->pci_using_dac =0 ; - mask =DMA_BIT_MASK (39 ); cmask = mask;if (pci_set_dma_mask (pdev, mask) ==0 &&pci_set_consistent_dma_mask (pdev, cmask) ==0 ) { - adapter->pci_using_dac =1 ;return 0 ; }
@@ -1047,10 +1044,8 @@ qlcnic_setup_netdev(struct qlcnic_adapter *adapter, netdev->features |= (NETIF_F_IPV6_CSUM |NETIF_F_TSO6 ); netdev->vlan_features |= (NETIF_F_IPV6_CSUM |NETIF_F_TSO6 ); -if (adapter->pci_using_dac) { - netdev->features |=NETIF_F_HIGHDMA ; - netdev->vlan_features |=NETIF_F_HIGHDMA ; - } + netdev->features |=NETIF_F_HIGHDMA ; + netdev->vlan_features |=NETIF_F_HIGHDMA ;if (adapter->capabilities &QLCNIC_FW_CAPABILITY_FVLANTX ) netdev->features |= (NETIF_F_HW_VLAN_TX );
drivers/net/qlge/qlge_main.c +1 -3
@@ -4643,9 +4643,7 @@ static int __devinit qlge_probe(struct pci_dev *pdev, | NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_FILTER); ndev->features |=NETIF_F_GRO ; - -if (test_bit (QL_DMA64 , &qdev->flags)) - ndev->features |=NETIF_F_HIGHDMA ; + ndev->features |=NETIF_F_HIGHDMA ;/* * Set up net_device structure.
drivers/net/r8169.c +3 -2
@@ -3052,7 +3052,6 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) !pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) { netif_info(tp, probe, dev, "using 64-bit DMA\n"); tp->cp_cmd |= PCIDAC; - dev->features |= NETIF_F_HIGHDMA; } else { rc =pci_set_dma_mask (pdev,DMA_BIT_MASK (32 ));if (rc <0 ) {
@@ -3061,6 +3060,8 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) } } + dev->features |=NETIF_F_HIGHDMA ; +/* ioremap MMIO region */ ioaddr =ioremap (pci_resource_start (pdev, region),R8169_REGS_SIZE );if (!ioaddr) {
@@ -4325,9 +4326,9 @@ static void rtl8169_pcierr_interrupt(struct net_device *dev)/* The infamous DAC f*ckup only happens at boot time */ if ((tp->cp_cmd &PCIDAC ) && !tp->dirty_rx && !tp->cur_rx) {netif_info (tp, intr, dev,"disabling PCI DAC\n" ); +pci_set_dma_mask (pdev,DMA_BIT_MASK (32 )); tp->cp_cmd &= ~PCIDAC ;RTL_W16 (CPlusCmd, tp->cp_cmd); - dev->features &= ~NETIF_F_HIGHDMA ; }rtl8169_hw_reset (ioaddr);
drivers/net/s2io.c +1 -5
@@ -7761,7 +7761,6 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)struct s2io_nic *sp;struct net_device *dev;int i, j, ret; -int dma_flag = false;u32 mac_up, mac_down;u64 val64 =0 , tmp64 =0 ;struct XENA_dev_config __iomem *bar0 =NULL ;
@@ -7785,7 +7784,6 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)if (!pci_set_dma_mask (pdev,DMA_BIT_MASK (64 ))) {DBG_PRINT (INIT_DBG ,"%s: Using 64bit DMA\n" , __func__); - dma_flag = true;if (pci_set_consistent_dma_mask (pdev,DMA_BIT_MASK (64 ))) {DBG_PRINT (ERR_DBG , "Unable to obtain 64bit DMA "
@@ -7826,7 +7824,6 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)memset (sp,0 ,sizeof (struct s2io_nic )); sp->dev = dev; sp->pdev = pdev; - sp->high_dma_flag = dma_flag; sp->device_enabled_once = false;if (rx_ring_mode ==1 ) sp->rxd_mode =RXD_MODE_1 ;
@@ -7979,8 +7976,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) dev->features |=NETIF_F_HW_VLAN_TX |NETIF_F_HW_VLAN_RX ; dev->features |=NETIF_F_SG |NETIF_F_IP_CSUM ; -if (sp->high_dma_flag == true) - dev->features |=NETIF_F_HIGHDMA ; + dev->features |=NETIF_F_HIGHDMA ; dev->features |=NETIF_F_TSO ; dev->features |=NETIF_F_TSO6 ;if ((sp->device_type &XFRAME_II_DEVICE ) && (ufo)) {
drivers/net/s2io.h +0 -1
@@ -883,7 +883,6 @@ struct s2io_nic {struct mac_addr def_mac_addr[256 ];struct net_device_stats stats; -int high_dma_flag;int device_enabled_once;char name[60 ];
drivers/net/skge.c +5 -9
@@ -3796,8 +3796,7 @@ static const struct net_device_ops skge_netdev_ops = {/* Initialize network device */ -static struct net_device *skge_devinit (struct skge_hw *hw,int port, -int highmem) +static struct net_device *skge_devinit (struct skge_hw *hw,int port) {struct skge_port *skge;struct net_device *dev =alloc_etherdev (sizeof (*skge));
@@ -3813,8 +3812,7 @@ static struct net_device *skge_devinit(struct skge_hw *hw, int port, dev->watchdog_timeo =TX_WATCHDOG ; dev->irq = hw->pdev->irq; -if (highmem) - dev->features |=NETIF_F_HIGHDMA ; + dev->features |=NETIF_F_HIGHDMA ; skge =netdev_priv (dev);netif_napi_add (dev, &skge->napi, skge_poll,NAPI_WEIGHT );
@@ -3872,7 +3870,7 @@ static int __devinit skge_probe(struct pci_dev *pdev, {struct net_device *dev, *dev1;struct skge_hw *hw; -int err, using_dac =0 ; +int err; err =pci_enable_device (pdev);if (err) {
@@ -3889,10 +3887,8 @@ static int __devinit skge_probe(struct pci_dev *pdev,pci_set_master (pdev);if (!pci_set_dma_mask (pdev,DMA_BIT_MASK (64 ))) { - using_dac =1 ; err =pci_set_consistent_dma_mask (pdev,DMA_BIT_MASK (64 )); }else if (!(err =pci_set_dma_mask (pdev,DMA_BIT_MASK (32 )))) { - using_dac =0 ; err =pci_set_consistent_dma_mask (pdev,DMA_BIT_MASK (32 )); }
@@ -3942,7 +3938,7 @@ static int __devinit skge_probe(struct pci_dev *pdev, (unsigned long long )pci_resource_start (pdev,0 ), pdev->irq, skge_board_name(hw), hw->chip_rev); - dev =skge_devinit (hw,0 , using_dac); + dev =skge_devinit (hw,0 );if (!dev) goto err_out_led_off;
@@ -3965,7 +3961,7 @@ static int __devinit skge_probe(struct pci_dev *pdev,skge_show_addr (dev);if (hw->ports >1 ) { - dev1 =skge_devinit (hw,1 , using_dac); + dev1 =skge_devinit (hw,1 );if (dev1 &®ister_netdev (dev1) ==0 )skge_show_addr (dev1);else {
drivers/net/sky2.c +6 -8
@@ -4444,7 +4444,7 @@ static const struct net_device_ops sky2_netdev_ops[2] = {/* Initialize network device */ static __devinit struct net_device *sky2_init_netdev (struct sky2_hw *hw,unsigned port, -int highmem,int wol) +int wol) {struct sky2_port *sky2;struct net_device *dev =alloc_etherdev (sizeof (*sky2));
@@ -4487,9 +4487,8 @@ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw, sky2->port = port; - dev->features |=NETIF_F_TSO |NETIF_F_IP_CSUM |NETIF_F_SG ; -if (highmem) - dev->features |=NETIF_F_HIGHDMA ; + dev->features |=NETIF_F_TSO |NETIF_F_IP_CSUM |NETIF_F_SG | +NETIF_F_HIGHDMA ;#ifdef SKY2_VLAN_TAG_USED /* The workaround for FE+ status conflicts with VLAN tag detection. */
@@ -4598,7 +4597,7 @@ static int __devinit sky2_probe(struct pci_dev *pdev, {struct net_device *dev;struct sky2_hw *hw; -int err, using_dac =0 , wol_default; +int err, wol_default;u32 reg;char buf1[16 ];
@@ -4634,7 +4633,6 @@ static int __devinit sky2_probe(struct pci_dev *pdev,if (sizeof (dma_addr_t) >sizeof (u32) && !(err =pci_set_dma_mask (pdev,DMA_BIT_MASK (64 )))) { - using_dac =1 ; err =pci_set_consistent_dma_mask (pdev,DMA_BIT_MASK (64 ));if (err <0 ) { dev_err(&pdev->dev, "unable to obtain 64 bit DMA "
@@ -4696,7 +4694,7 @@ static int __devinit sky2_probe(struct pci_dev *pdev,sky2_reset (hw); - dev =sky2_init_netdev (hw,0 , using_dac, wol_default); + dev =sky2_init_netdev (hw,0 , wol_default);if (!dev) { err = -ENOMEM ; goto err_out_free_pci;
@@ -4736,7 +4734,7 @@ static int __devinit sky2_probe(struct pci_dev *pdev,struct net_device *dev1; err = -ENOMEM ; - dev1 =sky2_init_netdev (hw,1 , using_dac, wol_default); + dev1 =sky2_init_netdev (hw,1 , wol_default);if (dev1 && (err =register_netdev (dev1)) ==0 )sky2_show_addr (dev1);else {
drivers/net/starfire.c +1 -2
@@ -732,9 +732,8 @@ static int __devinit starfire_init_one(struct pci_dev *pdev,#ifdef VLAN_SUPPORT dev->features |=NETIF_F_HW_VLAN_RX |NETIF_F_HW_VLAN_FILTER ;#endif /* VLAN_RX_KILL_VID */ -#ifdef ADDR_64BITS + dev->features |=NETIF_F_HIGHDMA ; -#endif /* ADDR_64BITS */ /* Serial EEPROM reads are hidden by the hardware. */ for (i =0 ; i <6 ; i++)
drivers/net/sungem.c +6 -10
@@ -3014,7 +3014,7 @@ static int __devinit gem_init_one(struct pci_dev *pdev,unsigned long gemreg_base, gemreg_len;struct net_device *dev;struct gem *gp; -int err, pci_using_dac; +int err;if (gem_version_printed++ ==0 )printk (KERN_INFO "%s" , version);
@@ -3042,18 +3042,15 @@ static int __devinit gem_init_one(struct pci_dev *pdev,* * For now we assume the various PPC GEMs are 32-bit only as well. */ -if (pdev->vendor ==PCI_VENDOR_ID_SUN && - pdev->device ==PCI_DEVICE_ID_SUN_GEM && - !pci_set_dma_mask (pdev,DMA_BIT_MASK (64 ))) { - pci_using_dac =1 ; - }else { +if (!(pdev->vendor ==PCI_VENDOR_ID_SUN && + pdev->device ==PCI_DEVICE_ID_SUN_GEM && + !pci_set_dma_mask (pdev,DMA_BIT_MASK (64 )))) { err =pci_set_dma_mask (pdev,DMA_BIT_MASK (32 ));if (err) { printk(KERN_ERR PFX "No usable DMA configuration, " "aborting.\n"); goto err_disable_device; } - pci_using_dac =0 ; } gemreg_base =pci_resource_start (pdev,0 );
@@ -3196,9 +3193,8 @@ static int __devinit gem_init_one(struct pci_dev *pdev, gp->phy_mii.def ? gp->phy_mii.def->name : "no");/* GEM can do it all... */ - dev->features |=NETIF_F_SG |NETIF_F_HW_CSUM |NETIF_F_LLTX ; -if (pci_using_dac) - dev->features |=NETIF_F_HIGHDMA ; + dev->features |=NETIF_F_SG |NETIF_F_HW_CSUM |NETIF_F_LLTX | +NETIF_F_HIGHDMA ;return 0 ;
drivers/net/tehuti.c +2 -7
@@ -1921,7 +1921,7 @@ bdx_probe(struct pci_dev *pdev, const struct pci_device_id *ent) {struct net_device *ndev;struct bdx_priv *priv; -int err, pci_using_dac, port; +int err, port;unsigned long pciaddr;u32 regionSize;struct pci_nic *nic;
@@ -1939,14 +1939,12 @@ bdx_probe(struct pci_dev *pdev, const struct pci_device_id *ent)if (!(err =pci_set_dma_mask (pdev,DMA_BIT_MASK (64 ))) && !(err =pci_set_consistent_dma_mask (pdev,DMA_BIT_MASK (64 )))) { - pci_using_dac =1 ; }else {if ((err =pci_set_dma_mask (pdev,DMA_BIT_MASK (32 ))) || (err =pci_set_consistent_dma_mask (pdev,DMA_BIT_MASK (32 )))) {pr_err ("No usable DMA configuration, aborting\n" ); goto err_dma; } - pci_using_dac =0 ; } err =pci_request_regions (pdev,BDX_DRV_NAME );
@@ -2026,13 +2024,10 @@ bdx_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ndev->irq = pdev->irq; ndev->features =NETIF_F_IP_CSUM |NETIF_F_SG |NETIF_F_TSO |NETIF_F_HW_VLAN_TX |NETIF_F_HW_VLAN_RX | -NETIF_F_HW_VLAN_FILTER +NETIF_F_HW_VLAN_FILTER |NETIF_F_HIGHDMA /*| NETIF_F_FRAGLIST */ ; -if (pci_using_dac) - ndev->features |=NETIF_F_HIGHDMA ; -/************** priv ****************/ priv = nic->priv[port] =netdev_priv (ndev);
drivers/net/tg3.c +2 -1
@@ -14571,11 +14571,12 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, }else persist_dma_mask = dma_mask =DMA_BIT_MASK (64 ); + dev->features |=NETIF_F_HIGHDMA ; +/* Configure DMA attributes. */ if (dma_mask >DMA_BIT_MASK (32 )) { err =pci_set_dma_mask (pdev, dma_mask);if (!err) { - dev->features |=NETIF_F_HIGHDMA ; err =pci_set_consistent_dma_mask (pdev, persist_dma_mask);if (err <0 ) {
drivers/net/usb/kaweth.c +6 -4
@@ -1181,11 +1181,13 @@ err_fw:INIT_DELAYED_WORK (&kaweth->lowmem_work, kaweth_resubmit_tl);usb_set_intfdata (intf, kaweth); -#if 0 -// dma_supported() is deeply broken on almost all architectures -if (dma_supported (&intf->dev,0xffffffffffffffffULL )) +/* Some USB host controllers can't do DMA; they have to use PIO. +* They indicate this by setting their dma_mask to NULL. For +* such controllers we need to make sure the networking layer doesn't +* send us skbs in high memory. +*/ +if (dev->bus->controller->dma_mask) kaweth->net->features |=NETIF_F_HIGHDMA ; -#endif SET_NETDEV_DEV (netdev, &intf->dev);if (register_netdev (netdev) !=0 ) {
drivers/net/usb/usbnet.c +7 -5
@@ -1317,12 +1317,14 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)* bind() should set rx_urb_size in that case. */ dev->hard_mtu = net->mtu + net->hard_header_len; -#if 0 -// dma_supported() is deeply broken on almost all architectures -// possible with some EHCI controllers -if (dma_supported (&udev->dev,DMA_BIT_MASK (64 ))) + +/* Some USB host controllers can't do DMA; they have to use PIO. +* They indicate this by setting their dma_mask to NULL. For +* such controllers we need to make sure the networking layer doesn't +* send us skbs in high memory. +*/ +if (xdev->bus->controller->dma_mask) net->features |=NETIF_F_HIGHDMA ; -#endif net->netdev_ops = &usbnet_netdev_ops; net->watchdog_timeo =TX_TIMEOUT_JIFFIES ;
drivers/net/vmxnet3/vmxnet3_drv.c +7 -14
@@ -1973,7 +1973,7 @@ vmxnet3_set_mac_addr(struct net_device *netdev, void *p)/* ==================== initialization and cleanup routines ============ */ static int -vmxnet3_alloc_pci_resources (struct vmxnet3_adapter *adapter,bool *dma64) +vmxnet3_alloc_pci_resources (struct vmxnet3_adapter *adapter) {int err;unsigned long mmio_start, mmio_len;
@@ -1993,7 +1993,6 @@ vmxnet3_alloc_pci_resources(struct vmxnet3_adapter *adapter, bool *dma64) err = -EIO ; goto err_set_mask; } - *dma64 = true; }else {if (pci_set_dma_mask (pdev,DMA_BIT_MASK (32 )) !=0 ) { printk(KERN_ERR "pci_set_dma_mask failed for adapter "
@@ -2001,7 +2000,6 @@ vmxnet3_alloc_pci_resources(struct vmxnet3_adapter *adapter, bool *dma64) err = -EIO ; goto err_set_mask; } - *dma64 = false; } err = pci_request_selected_regions(pdev, (1 << 2) - 1,
@@ -2245,7 +2243,7 @@ out:static void -vmxnet3_declare_features (struct vmxnet3_adapter *adapter,bool dma64) +vmxnet3_declare_features (struct vmxnet3_adapter *adapter) {struct net_device *netdev = adapter->netdev;
@@ -2256,19 +2254,15 @@ vmxnet3_declare_features(struct vmxnet3_adapter *adapter, bool dma64)NETIF_F_HW_VLAN_FILTER |NETIF_F_TSO |NETIF_F_TSO6 | -NETIF_F_LRO ; +NETIF_F_LRO | +NETIF_F_HIGHDMA ; -printk (KERN_INFO "features: sg csum vlan jf tso tsoIPv6 lro" ); +printk (KERN_INFO "features: sg csum vlan jf tso tsoIPv6 lro highDMA" ); adapter->rxcsum = true; adapter->jumbo_frame = true; adapter->lro = true; -if (dma64) { - netdev->features |=NETIF_F_HIGHDMA ; -printk (" highDMA" ); - } - netdev->vlan_features = netdev->features;printk ("\n" ); }
@@ -2398,7 +2392,6 @@ vmxnet3_probe_device(struct pci_dev *pdev,#endif };int err; -bool dma64 = false;/* stupid gcc */ u32 ver;struct net_device *netdev;struct vmxnet3_adapter *adapter;
@@ -2448,7 +2441,7 @@ vmxnet3_probe_device(struct pci_dev *pdev, goto err_alloc_pm; } - err =vmxnet3_alloc_pci_resources (adapter, &dma64); + err =vmxnet3_alloc_pci_resources (adapter);if (err <0 ) goto err_alloc_pci;
@@ -2472,7 +2465,7 @@ vmxnet3_probe_device(struct pci_dev *pdev, goto err_ver; } -vmxnet3_declare_features (adapter, dma64); +vmxnet3_declare_features (adapter); adapter->dev_number =atomic_read (&devices_found);vmxnet3_alloc_intr_resources (adapter);
drivers/net/vxge/vxge-main.c +3 -10
@@ -3226,7 +3226,7 @@ static const struct net_device_ops vxge_netdev_ops = {int __devinit vxge_device_register (struct __vxge_hw_device *hldev,struct vxge_config *config, -int high_dma,int no_of_vpath, +int no_of_vpath,struct vxgedev **vdev_out) {struct net_device *ndev;
@@ -3294,11 +3294,7 @@ int __devinit vxge_device_register(struct __vxge_hw_device *hldev,vxge_debug_init (vxge_hw_device_trace_level_get (hldev),"%s : checksuming enabled" , __func__); -if (high_dma) { - ndev->features |=NETIF_F_HIGHDMA ; -vxge_debug_init (vxge_hw_device_trace_level_get (hldev), -"%s : using High DMA" , __func__); - } + ndev->features |=NETIF_F_HIGHDMA ; ndev->features |=NETIF_F_TSO |NETIF_F_TSO6 ;
@@ -4013,7 +4009,6 @@ vxge_probe(struct pci_dev *pdev, const struct pci_device_id *pre)struct __vxge_hw_device *hldev;enum vxge_hw_status status;int ret; -int high_dma =0 ;u64 vpath_mask =0 ;struct vxgedev *vdev;struct vxge_config ll_config;
@@ -4091,8 +4086,6 @@ vxge_probe(struct pci_dev *pdev, const struct pci_device_id *pre)vxge_debug_ll_config (VXGE_TRACE ,"%s : using 64bit DMA" , __func__); - high_dma =1 ; -if (pci_set_consistent_dma_mask (pdev,DMA_BIT_MASK (64 ))) { vxge_debug_init(VXGE_ERR,
@@ -4232,7 +4225,7 @@ vxge_probe(struct pci_dev *pdev, const struct pci_device_id *pre) ll_config.tx_pause_enable =VXGE_PAUSE_CTRL_ENABLE ; ll_config.rx_pause_enable =VXGE_PAUSE_CTRL_ENABLE ; -if (vxge_device_register (hldev, &ll_config, high_dma, no_of_vpath, +if (vxge_device_register (hldev, &ll_config, no_of_vpath, &vdev)) { ret = -EINVAL ; goto _exit4;
drivers/net/vxge/vxge-main.h +1 -1
@@ -402,7 +402,7 @@ struct vxge_tx_priv {int __devinit vxge_device_register (struct __vxge_hw_device *devh,struct vxge_config *config, -int high_dma,int no_of_vpath, +int no_of_vpath,struct vxgedev **vdev);void vxge_device_unregister (struct __vxge_hw_device *devh);
David Miller
maintainerFrom: Robert Hancock <[email protected]>
Date: Mon, 22 Feb 2010 20:45:45 -0600
Quoted 14 lines
Many networking drivers have issues with the use of the
NETIF_F_HIGHDMAflag. This flag actually indicates whether or not the device/driver can handle skbs located in high memory (as opposed to lowmem). However, many drivers incorrectly treat this flag as indicating that 64-bit DMA is supported, which has nothing to do with its actual function. It makes no sense to make settingNETIF_F_HIGHDMAconditional on whether a 64-bit DMA mask has been set, as many drivers do, since if highmem DMA is supported at all, it should work regardless of whether 64-bit DMA is supported. Failing to setNETIF_F_HIGHDMAwhen it should be can hurt performance on architectures which use highmem since it results in needless data copying.This fixes up the networking drivers which currently use
NETIF_F_HIGHDMAto not do so conditionally on DMA mask settings.
Quoted 6 lines
For the USB kaweth and usbnet drivers, this patch also uncomments and corrects some code to set
NETIF_F_HIGHDMAbased on the USB host controller's DMA mask. These drivers should be able to access highmem unless the host controller is non-DMA-capable, which is indicated by the DMA mask being null.Signed-off-by Robert Hancock <[email protected]>
Well, if the device isn't using 64-bit DMA addressing and the platform uses direct (no-iommu) mapping of physical to DMA addresses , won't your change break things? The device will get a >4GB DMA address or the DMA mapping layer will signal an error.
That's really part of the what the issue is I think.
So, this trigger the check in check_addr() in arch/x86/kernel/pci-nommu.c when such packets try to get mapped by the driver, right?
That will make the DMA mapping call fail, and the packet will be dropped permanently. And hey, on top of it, many of these drivers you remove the setting from don't even check the mapping call return values for errors.
So even bigger breakage. One example is drivers/net/8139cp.c, it just does dma_map_single() and uses the result.
It really depends upon that NETIF_F_HIGHDMA setting for correct operation.
And even if something like swiotlb is available, now we're going to do bounce buffering which is largely equivalent to what a lack of NETIF_F_HIGHDMA will do. Except that once NETIF_F_HIGHDMA copies the packet to lowmem it will only do that once, whereas if the packet goes to multiple devices swiotlb might copy the packet to a bounce buffer multiple times.
We definitely can't apply your patch as-is.
Quoted 46 lines · David Miller
From: Robert Hancock <[email protected]>
Date: Mon, 22 Feb 2010 20:45:45 -0600Quoted 14 lines
Many networking drivers have issues with the use of the
NETIF_F_HIGHDMAflag. This flag actually indicates whether or not the device/driver can handle skbs located in high memory (as opposed to lowmem). However, many drivers incorrectly treat this flag as indicating that 64-bit DMA is supported, which has nothing to do with its actual function. It makes no sense to make settingNETIF_F_HIGHDMAconditional on whether a 64-bit DMA mask has been set, as many drivers do, since if highmem DMA is supported at all, it should work regardless of whether 64-bit DMA is supported. Failing to setNETIF_F_HIGHDMAwhen it should be can hurt performance on architectures which use highmem since it results in needless data copying.This fixes up the networking drivers which currently use
NETIF_F_HIGHDMAto not do so conditionally on DMA mask settings.Quoted 6 lines
For the USB kaweth and usbnet drivers, this patch also uncomments and corrects some code to set
NETIF_F_HIGHDMAbased on the USB host controller's DMA mask. These drivers should be able to access highmem unless the host controller is non-DMA-capable, which is indicated by the DMA mask being null.Signed-off-by Robert Hancock <[email protected]>Well, if the device isn't using 64-bit DMA addressing and the platform uses direct (no-iommu) mapping of physical to DMA addresses , won't your change break things? The device will get a >4GB DMA address or the DMA mapping layer will signal an error.
That's really part of the what the issue is I think.
So, this trigger the check in
check_addr()inarch/x86/kernel/pci-nommu.cwhen such packets try to get mapped by the driver, right?That will make the DMA mapping call fail, and the packet will be dropped permanently. And hey, on top of it, many of these drivers you remove the setting from don't even check the mapping call return values for errors.
So even bigger breakage. One example is
drivers/net/8139cp.c, it just doesdma_map_single()and uses the result.It really depends upon that
NETIF_F_HIGHDMAsetting for correct operation.
Quoted 8 lines
And even if something like swiotlb is available, now we're going to do bounce buffering which is largely equivalent to what a lack of
NETIF_F_HIGHDMAwill do. Except that onceNETIF_F_HIGHDMAcopies the packet to lowmem it will only do that once, whereas if the packet goes to multiple devices swiotlb might copy the packet to a bounce buffer multiple times.We definitely can't apply your patch as-is.
Hmm.. Yeah, there is a bit of a mess there. I'm thinking of the particular example of i386 where you have 32-bit DMA devices with more than 4GB of RAM. If you then allow the device to access highmem then the DMA mapping API can get presented with addresses above 4GB and AFAIK I don't think it can cope with that situation on that platform.
Problem is that the NETIF_F_HIGHDMA check is generally too restrictive in that situation, and it's really conflating two things into one (the genuine can't-access-highmem part, and the "oh by the way, if highmem can be >4GB then we can't access that") . If you have 3GB of RAM on i386 with one of these drivers, you'll have packets being bounced through lowmem without any real reason. I'll have a look into things a bit further..
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Quoted 62 lines · Robert Hancock
Quoted 46 lines · David Miller
From: Robert Hancock <[email protected]>
Date: Mon, 22 Feb 2010 20:45:45 -0600Quoted 14 lines
Many networking drivers have issues with the use of the
NETIF_F_HIGHDMAflag. This flag actually indicates whether or not the device/driver can handle skbs located in high memory (as opposed to lowmem). However, many drivers incorrectly treat this flag as indicating that 64-bit DMA is supported, which has nothing to do with its actual function. It makes no sense to make settingNETIF_F_HIGHDMAconditional on whether a 64-bit DMA mask has been set, as many drivers do, since if highmem DMA is supported at all, it should work regardless of whether 64-bit DMA is supported. Failing to setNETIF_F_HIGHDMAwhen it should be can hurt performance on architectures which use highmem since it results in needless data copying.This fixes up the networking drivers which currently use
NETIF_F_HIGHDMAto not do so conditionally on DMA mask settings.Quoted 6 lines
For the USB kaweth and usbnet drivers, this patch also uncomments and corrects some code to set
NETIF_F_HIGHDMAbased on the USB host controller's DMA mask. These drivers should be able to access highmem unless the host controller is non-DMA-capable, which is indicated by the DMA mask being null.Signed-off-by Robert Hancock <[email protected]>Well, if the device isn't using 64-bit DMA addressing and the platform uses direct (no-iommu) mapping of physical to DMA addresses , won't your change break things? The device will get a >4GB DMA address or the DMA mapping layer will signal an error.
That's really part of the what the issue is I think.
So, this trigger the check in
check_addr()inarch/x86/kernel/pci-nommu.cwhen such packets try to get mapped by the driver, right?That will make the DMA mapping call fail, and the packet will be dropped permanently. And hey, on top of it, many of these drivers you remove the setting from don't even check the mapping call return values for errors.
So even bigger breakage. One example is
drivers/net/8139cp.c, it just doesdma_map_single()and uses the result.It really depends upon that
NETIF_F_HIGHDMAsetting for correct operation.Quoted 8 lines
And even if something like swiotlb is available, now we're going to do bounce buffering which is largely equivalent to what a lack of
NETIF_F_HIGHDMAwill do. Except that onceNETIF_F_HIGHDMAcopies the packet to lowmem it will only do that once, whereas if the packet goes to multiple devices swiotlb might copy the packet to a bounce buffer multiple times.We definitely can't apply your patch as-is.
Hmm.. Yeah, there is a bit of a mess there. I'm thinking of the particular example of i386 where you have 32-bit DMA devices with more than 4GB of RAM. If you then allow the device to access highmem then the DMA mapping API can get presented with addresses above 4GB and AFAIK I don't think it can cope with that situation on that platform.
Quoted 7 lines
Problem is that the
NETIF_F_HIGHDMAcheck is generally too restrictive in that situation, and it's really conflating two things into one (the genuine can't-access-highmem part, and the "oh by the way, if highmem can be >4GB then we can't access that") . If you have 3GB of RAM on i386 with one of these drivers, you'll have packets being bounced through lowmem without any real reason. I'll have a look into things a bit further..
Maybe it would be useful to start with splitting NETIF_F_HIGHDMA on two independent flags, i.e.:
#define NETIF_F_DMA_HIGH (1 << 27) #define NETIF_F_DMA_64BIT (1 << 28)
and keeping NETIF_F_HIGHDMA as
#define NETIF_F_HIGHDMA (NETIF_F_DMA_HIGH | NET_F_DMA_64BIT)
for now..?
[ Next step would involve fixing illegal_highdma() check in net/core/dev.c
to distinguish between those new flags which in turn should allow sorting out code in the device drivers on *per-driver* basis. ]
--
Bartlomiej Zolnierkiewicz
Quoted 79 lines · Bartlomiej Zolnierkiewicz
Quoted 62 lines · Robert Hancock
Quoted 46 lines · David Miller
From: Robert Hancock <[email protected]>
Date: Mon, 22 Feb 2010 20:45:45 -0600Quoted 14 lines
Many networking drivers have issues with the use of the
NETIF_F_HIGHDMAflag. This flag actually indicates whether or not the device/driver can handle skbs located in high memory (as opposed to lowmem). However, many drivers incorrectly treat this flag as indicating that 64-bit DMA is supported, which has nothing to do with its actual function. It makes no sense to make settingNETIF_F_HIGHDMAconditional on whether a 64-bit DMA mask has been set, as many drivers do, since if highmem DMA is supported at all, it should work regardless of whether 64-bit DMA is supported. Failing to setNETIF_F_HIGHDMAwhen it should be can hurt performance on architectures which use highmem since it results in needless data copying.This fixes up the networking drivers which currently use
NETIF_F_HIGHDMAto not do so conditionally on DMA mask settings.Quoted 6 lines
For the USB kaweth and usbnet drivers, this patch also uncomments and corrects some code to set
NETIF_F_HIGHDMAbased on the USB host controller's DMA mask. These drivers should be able to access highmem unless the host controller is non-DMA-capable, which is indicated by the DMA mask being null.Signed-off-by Robert Hancock <[email protected]>Well, if the device isn't using 64-bit DMA addressing and the platform uses direct (no-iommu) mapping of physical to DMA addresses , won't your change break things? The device will get a >4GB DMA address or the DMA mapping layer will signal an error.
That's really part of the what the issue is I think.
So, this trigger the check in
check_addr()inarch/x86/kernel/pci-nommu.cwhen such packets try to get mapped by the driver, right?That will make the DMA mapping call fail, and the packet will be dropped permanently. And hey, on top of it, many of these drivers you remove the setting from don't even check the mapping call return values for errors.
So even bigger breakage. One example is
drivers/net/8139cp.c, it just doesdma_map_single()and uses the result.It really depends upon that
NETIF_F_HIGHDMAsetting for correct operation.Quoted 8 lines
And even if something like swiotlb is available, now we're going to do bounce buffering which is largely equivalent to what a lack of
NETIF_F_HIGHDMAwill do. Except that onceNETIF_F_HIGHDMAcopies the packet to lowmem it will only do that once, whereas if the packet goes to multiple devices swiotlb might copy the packet to a bounce buffer multiple times.We definitely can't apply your patch as-is.
Hmm.. Yeah, there is a bit of a mess there. I'm thinking of the particular example of i386 where you have 32-bit DMA devices with more than 4GB of RAM. If you then allow the device to access highmem then the DMA mapping API can get presented with addresses above 4GB and AFAIK I don't think it can cope with that situation on that platform.
Quoted 7 lines
Problem is that the
NETIF_F_HIGHDMAcheck is generally too restrictive in that situation, and it's really conflating two things into one (the genuine can't-access-highmem part, and the "oh by the way, if highmem can be >4GB then we can't access that") . If you have 3GB of RAM on i386 with one of these drivers, you'll have packets being bounced through lowmem without any real reason. I'll have a look into things a bit further..Maybe it would be useful to start with splitting
NETIF_F_HIGHDMAon two independent flags, i.e.:#define
NETIF_F_DMA_HIGH(1 << 27)
#defineNETIF_F_DMA_64BIT(1 << 28)and keeping
NETIF_F_HIGHDMAas
Quoted 7 lines
#define
NETIF_F_HIGHDMA(NETIF_F_DMA_HIGH|NET_F_DMA_64BIT)for now..?
[ Next step would involve fixing
illegal_highdma()check innet/core/dev.cto distinguish between those new flags which in turn should allow sorting out code in the device drivers on *per-driver* basis. ]
That seems like a reasonable approach to me. Only question is how to implement the check for DMA_64BIT. Can we just check page_to_phys on each of the pages in the skb to see if it's > 0xffffffff ? Are there any architectures where it's more complicated than that?
Also, presumably these flags still wouldn't have any effect on non-highmem architectures, same as NETIF_F_HIGHDMA now, since the best we can do is copy the data to lowmem, which could still be >4GB in this case. Therefore, the IOMMU (either HW or SWIOTLB, one of which had better exist) just has to deal with it. (I suppose you could copy to a buffer allocated with GFP_DMA32, but that likely wouldn't be a win if you had a hardware IOMMU.)
David Miller
maintainerFrom: Robert Hancock <[email protected]>
Date: Fri, 26 Feb 2010 21:08:04 -0600
Quoted 4 lines
That seems like a reasonable approach to me. Only question is how to implement the check for
DMA_64BIT. Can we just checkpage_to_physon each of the pages in the skb to see if it's >0xffffffff? Are there any architectures where it's more complicated than that?
On almost every platform it's "more complicated than that".
This is the whole issue. What matters is the final DMA address and since we have IOMMUs and the like, it is absolutely not tenable to solve this by checking physical address attributes.
Quoted 9 lines · David Miller
From: Robert Hancock <[email protected]>
Date: Fri, 26 Feb 2010 21:08:04 -0600Quoted 4 lines
That seems like a reasonable approach to me. Only question is how to implement the check for
DMA_64BIT. Can we just checkpage_to_physon each of the pages in the skb to see if it's >0xffffffff? Are there any architectures where it's more complicated than that?On almost every platform it's "more complicated than that".
Mildly speaking, I see the real problem now and it is much higher in the software stack than networking..
Quoted 3 lines
This is the whole issue. What matters is the final DMA address and since we have IOMMUs and the like, it is absolutely not tenable to solve this by checking physical address attributes.
What's more we may not have IOMMU in place which creates really interesting scenarios for HIGHMEM=y and results in all kind of wonderful band-aids in particular device drivers.
Having IOMMU (even if it is only a software one, i.e. this would mean swiotlb for x86-32/highmem) always in place would simplify things greatly..
--
Bartlomiej Zolnierkiewicz
David Miller
maintainerFrom: Bartlomiej Zolnierkiewicz <[email protected]>
Date: Sat, 27 Feb 2010 12:59:31 +0100
Quoted 3 lines
Having IOMMU (even if it is only a software one, i.e. this would mean swiotlb for x86-32/highmem) always in place would simplify things greatly..
I agree, things would be a lot simpler.
Quoted 8 lines · David Miller
From: Bartlomiej Zolnierkiewicz <[email protected]>
Date: Sat, 27 Feb 2010 12:59:31 +0100Quoted 3 lines
Having IOMMU (even if it is only a software one, i.e. this would mean swiotlb for x86-32/highmem) always in place would simplify things greatly..
I agree, things would be a lot simpler.
Yeah, the situation kind of sucks on the platforms that don't have any IOMMU support, since it means that the DMA API can't handle anything over 4GB properly and you need all these hacks in the block layer, networking layer, etc. It would be nice if some kind of IOMMU support could be relied upon always.
Quoted 8 lines · On Sat, 27 Feb 2010 12:15:19 -0600 Robert Hancock <[email protected]> wrote:
Quoted 7 lines · David Miller
From: Bartlomiej Zolnierkiewicz <[email protected]>
Date: Sat, 27 Feb 2010 12:59:31 +0100Quoted 3 lines
Having IOMMU (even if it is only a software one, i.e. this would mean swiotlb for x86-32/highmem) always in place would simplify things greatly..
Quoted 7 lines
Quoted 1 line
I agree, things would be a lot simpler.
Yeah, the situation kind of sucks on the platforms that don't have any IOMMU support, since it means that the DMA API can't handle anything over 4GB properly and you need all these hacks in the block layer, networking layer, etc. It would be nice if some kind of IOMMU support could be relied upon always.
When I proposed such approach (always use swiotlb) before, IIRC, the objections were:
- better to make allocation respect dma_mask. (I don't think that this approach is possible since we don't know which device handles data later when we allocate memory).
- swiotlb is not good for small systems since it allocates too much memory (we can fix this though).
There might be more.
David Miller
maintainerFrom: FUJITA Tomonori <[email protected]>
Date: Sun, 28 Feb 2010 03:38:19 +0900
Quoted 6 lines
When I proposed such approach (always use swiotlb) before, IIRC, the objections were:
- better to make allocation respect
dma_mask. (I don't think that this approach is possible since we don't know which device handles data later when we allocate memory).
And such objects might end up being processed by multiple devices with different DMA restrictions.
Quoted 2 lines
- swiotlb is not good for small systems since it allocates too much memory (we can fix this though).
Indeed.
Was: Re: [RFC PATCH] fix problems with NETIF_F_HIGHDMA in networking, Now: SWIOTLB dynamic allocation
Quoted 10 lines · David Miller
From: FUJITA Tomonori <[email protected]>
Date: Sun, 28 Feb 2010 03:38:19 +0900Quoted 6 lines
When I proposed such approach (always use swiotlb) before, IIRC, the objections were:
- better to make allocation respect
dma_mask. (I don't think that this approach is possible since we don't know which device handles data later when we allocate memory).
Quoted 7 lines
And such objects might end up being processed by multiple devices with different DMA restrictions.
Quoted 2 lines
- swiotlb is not good for small systems since it allocates too much memory (we can fix this though).
Indeed.
What would be a good mechanism for this? Enumerating all of the PCI devices to find out which ones are 32-bit and then allocate some chunk of memory based on the amount of them? say, 1MB per card?
Or maybe a simpler one - figure out how many pages we have an allocate based on some sliding rule (say, 8MB for under 512MB, 16MB between 512MB and 2GB, and 32MB for 2GB to 4GB, and after that the full 64MB?)
Re: Was: Re: [RFC PATCH] fix problems with NETIF_F_HIGHDMA in networking, Now: SWIOTLB dynamic allocation
Quoted 19 lines · Konrad Rzeszutek Wilk
Quoted 10 lines · David Miller
From: FUJITA Tomonori <[email protected]>
Date: Sun, 28 Feb 2010 03:38:19 +0900Quoted 6 lines
When I proposed such approach (always use swiotlb) before, IIRC, the objections were:
- better to make allocation respect
dma_mask. (I don't think that this approach is possible since we don't know which device handles data later when we allocate memory).Quoted 7 lines
And such objects might end up being processed by multiple devices with different DMA restrictions.
Quoted 2 lines
- swiotlb is not good for small systems since it allocates too much memory (we can fix this though).
Indeed.
Quoted 7 lines
What would be a good mechanism for this? Enumerating all of the PCI devices to find out which ones are 32-bit and then allocate some chunk of memory based on the amount of them? say, 1MB per card?
Or maybe a simpler one - figure out how many pages we have an allocate based on some sliding rule (say, 8MB for under 512MB, 16MB between 512MB and 2GB, and 32MB for 2GB to 4GB, and after that the full 64MB?)
Why do we need to allocate SWIOTLB if your highest memory address is under 4GB? You can just disable it in that case, like x86_64 does.
Re: Was: Re: [RFC PATCH] fix problems with NETIF_F_HIGHDMA in networking, Now: SWIOTLB dynamic allocation
Quoted 25 lines · On Mon, 1 Mar 2010 15:12:41 -0600 Robert Hancock <[email protected]> wrote:
Quoted 23 lines · Konrad Rzeszutek Wilk
Quoted 10 lines · David Miller
From: FUJITA Tomonori <[email protected]>
Date: Sun, 28 Feb 2010 03:38:19 +0900Quoted 6 lines
When I proposed such approach (always use swiotlb) before, IIRC, the objections were:
- better to make allocation respect
dma_mask. (I don't think that this approach is possible since we don't know which device handles data later when we allocate memory).Quoted 7 lines
And such objects might end up being processed by multiple devices with different DMA restrictions.
Quoted 2 lines
- swiotlb is not good for small systems since it allocates too much memory (we can fix this though).
Indeed.
What would be a good mechanism for this? Enumerating all of the PCI devices to find out which ones are 32-bit and then allocate some chunk of memory based on the amount of them? say, 1MB per card?
Quoted 6 lines
Quoted 3 lines
Or maybe a simpler one - figure out how many pages we have an allocate based on some sliding rule (say, 8MB for under 512MB, 16MB between 512MB and 2GB, and 32MB for 2GB to 4GB, and after that the full 64MB?)
Why do we need to allocate SWIOTLB if your highest memory address is under 4GB? You can just disable it in that case, like
x86_64does.
Unfortunately, we need to do because the goal is removing the block layer bounce (and other bounce mechanisms in sub systems).
For example, even if highest memory address is under 4GB, you must provide bounce buffer for ISA devices (and some devices for strange DMA restrictions such as under 1GB).
Re: Was: Re: [RFC PATCH] fix problems with NETIF_F_HIGHDMA in networking, Now: SWIOTLB dynamic allocation
In reply to Konrad Rzeszutek WilkQuoted 19 lines · On Mon, 1 Mar 2010 11:34:37 -0500 Konrad Rzeszutek Wilk…
Quoted 10 lines · David Miller
From: FUJITA Tomonori <[email protected]>
Date: Sun, 28 Feb 2010 03:38:19 +0900Quoted 6 lines
When I proposed such approach (always use swiotlb) before, IIRC, the objections were:
- better to make allocation respect
dma_mask. (I don't think that this approach is possible since we don't know which device handles data later when we allocate memory).Quoted 7 lines
And such objects might end up being processed by multiple devices with different DMA restrictions.
Quoted 2 lines
- swiotlb is not good for small systems since it allocates too much memory (we can fix this though).
Indeed.
Quoted 7 lines
What would be a good mechanism for this? Enumerating all of the PCI devices to find out which ones are 32-bit and then allocate some chunk of memory based on the amount of them? say, 1MB per card?
Or maybe a simpler one - figure out how many pages we have an allocate based on some sliding rule (say, 8MB for under 512MB, 16MB between 512MB and 2GB, and 32MB for 2GB to 4GB, and after that the full 64MB?)
Hmm, have you read the above objection from embedded system people ? :)
We can't pre-allocate such lots of memory (several MB). And we don't need to.
We have to pre-allocate some for the block layer (we have to guarantee that we can handle one request at least), however we don't need to pre-allocate for the rest (including the network stack).
This guarantee is a bit difficult since the dma_map_* doesn't know who is at the upper layer; the dma_map_* cannot know if it needs to allocate from the pre-allocated pool or not. I thought about adding 'dma attribute flag' to struct device (to be exact, struct device_dma_parameters).
Quoted 8 lines · David Miller
From: Robert Hancock <[email protected]>
Date: Fri, 26 Feb 2010 21:08:04 -0600Quoted 4 lines
That seems like a reasonable approach to me. Only question is how to implement the check for
DMA_64BIT. Can we just checkpage_to_physon each of the pages in the skb to see if it's >0xffffffff? Are there any architectures where it's more complicated than that?
Quoted 5 lines
On almost every platform it's "more complicated than that".
This is the whole issue. What matters is the final DMA address and since we have IOMMUs and the like, it is absolutely not tenable to solve this by checking physical address attributes.
Yeah, physical address isn't quite right. There is a precedent for such a check in the block layer though - look at blk_queue_bounce_limit in block/blk-settings.c:
void blk_queue_bounce_limit(struct request_queue *q, u64 dma_mask)
{
unsigned long b_pfn = dma_mask >> PAGE_SHIFT;
int dma = 0;
q->bounce_gfp = GFP_NOIO;
#if BITS_PER_LONG == 64
/*
* Assume anything <= 4GB can be handled by IOMMU. Actually
* some IOMMUs can handle everything, but I don't know of a
* way to test this here.
*/
if (b_pfn < (min_t(u64, 0xffffffffUL, BLK_BOUNCE_HIGH) >> PAGE_SHIFT))
dma = 1;
q->limits.bounce_pfn = max_low_pfn;
#else
if (b_pfn < blk_max_low_pfn)
dma = 1;
q->limits.bounce_pfn = b_pfn;
#endif
if (dma) {
init_emergency_isa_pool();
q->bounce_gfp = GFP_NOIO | GFP_DMA;
q->limits.bounce_pfn = b_pfn;
}
}and then in mm/bounce.c:
static void __blk_queue_bounce(struct request_queue *q, struct bio **bio_orig,
mempool_t *pool)
{
struct page *page;
struct bio *bio = NULL;
int i, rw = bio_data_dir(*bio_orig);
struct bio_vec *to, *from;
bio_for_each_segment(from, *bio_orig, i) {
page = from->bv_page;
/*
* is destination page below bounce pfn?
*/
if (page_to_pfn(page) <= queue_bounce_pfn(q))
continue;Following that logic then, it appears that page_to_pfn(page) > (0xffffffff >> PAGE_SHIFT) should tell us what we want to know for the DMA_64BIT flag.. or am I missing something?
Quoted 9 lines · On Sat, 27 Feb 2010 11:59:47 -0600 Robert Hancock…
Quoted 8 lines · David Miller
From: Robert Hancock <[email protected]>
Date: Fri, 26 Feb 2010 21:08:04 -0600Quoted 4 lines
That seems like a reasonable approach to me. Only question is how to implement the check for
DMA_64BIT. Can we just checkpage_to_physon each of the pages in the skb to see if it's >0xffffffff? Are there any architectures where it's more complicated than that?
Quoted 7 lines
Quoted 5 lines
On almost every platform it's "more complicated than that".
This is the whole issue. What matters is the final DMA address and since we have IOMMUs and the like, it is absolutely not tenable to solve this by checking physical address attributes.
Yeah, physical address isn't quite right. There is a precedent for
Probably, you need to check PCI_DMA_BUS_IS_PHYS.
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html