ibmveth: enable driver for CMO

Enable ibmveth for Cooperative Memory Overcommitment (CMO). For this driver
it means calculating a desired amount of IO memory based on the current MTU
and updating this value with the bus when MTU changes occur. Because DMA
mappings can fail, we have added a bounce buffer for temporary cases where
the driver can not map IO memory for the buffer pool.

The following changes are made to enable the driver for CMO:
* DMA mapping errors will not result in error messages if entitlement has
been exceeded and resources were not available.
* DMA mapping errors are handled gracefully, ibmveth_replenish_buffer_pool()
is corrected to check the return from dma_map_single and fail gracefully.
* The driver will have a get_desired_dma function defined to function
in a CMO environment.
* When the MTU is changed, the driver will update the device IO entitlement

Signed-off-by: Robert Jennings <rcj@linux.vnet.ibm.com>
Signed-off-by: Brian King <brking@linux.vnet.ibm.com>
Signed-off-by: Santiago Leon <santil@us.ibm.com>
Acked-by: Paul Mackerras <paulus@samba.org>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>

authored by

Robert Jennings and committed by
Benjamin Herrenschmidt
1096d63d ea866e65

+140 -34
+135 -34
drivers/net/ibmveth.c
··· 33 */ 34 35 #include <linux/module.h> 36 #include <linux/types.h> 37 #include <linux/errno.h> 38 #include <linux/ioport.h> ··· 53 #include <asm/hvcall.h> 54 #include <asm/atomic.h> 55 #include <asm/vio.h> 56 #include <asm/uaccess.h> 57 #include <linux/seq_file.h> 58 59 #include "ibmveth.h" ··· 97 static void ibmveth_proc_unregister_adapter(struct ibmveth_adapter *adapter); 98 static irqreturn_t ibmveth_interrupt(int irq, void *dev_instance); 99 static void ibmveth_rxq_harvest_buffer(struct ibmveth_adapter *adapter); 100 static struct kobj_type ktype_veth_pool; 101 102 #ifdef CONFIG_PROC_FS 103 #define IBMVETH_PROC_DIR "ibmveth" ··· 231 u32 i; 232 u32 count = pool->size - atomic_read(&pool->available); 233 u32 buffers_added = 0; 234 235 mb(); 236 237 for(i = 0; i < count; ++i) { 238 - struct sk_buff *skb; 239 - unsigned int free_index, index; 240 - u64 correlator; 241 union ibmveth_buf_desc desc; 242 - unsigned long lpar_rc; 243 - dma_addr_t dma_addr; 244 245 skb = alloc_skb(pool->buff_size, GFP_ATOMIC); 246 ··· 260 dma_addr = dma_map_single(&adapter->vdev->dev, skb->data, 261 pool->buff_size, DMA_FROM_DEVICE); 262 263 pool->free_map[free_index] = IBM_VETH_INVALID_MAP; 264 pool->dma_addr[index] = dma_addr; 265 pool->skbuff[index] = skb; ··· 275 276 lpar_rc = h_add_logical_lan_buffer(adapter->vdev->unit_address, desc.desc); 277 278 - if(lpar_rc != H_SUCCESS) { 279 - pool->free_map[free_index] = index; 280 - pool->skbuff[index] = NULL; 281 - if (pool->consumer_index == 0) 282 - pool->consumer_index = pool->size - 1; 283 - else 284 - pool->consumer_index--; 285 - dma_unmap_single(&adapter->vdev->dev, 286 - pool->dma_addr[index], pool->buff_size, 287 - DMA_FROM_DEVICE); 288 - dev_kfree_skb_any(skb); 289 - adapter->replenish_add_buff_failure++; 290 - break; 291 - } else { 292 buffers_added++; 293 adapter->replenish_add_buff_success++; 294 } 295 } 296 297 mb(); 298 atomic_add(buffers_added, &(pool->available)); ··· 312 313 adapter->replenish_task_cycles++; 314 315 - for(i = 0; i < IbmVethNumBufferPools; i++) 316 if(adapter->rx_buff_pool[i].active) 317 ibmveth_replenish_buffer_pool(adapter, 318 &adapter->rx_buff_pool[i]); ··· 487 if (adapter->rx_buff_pool[i].active) 488 ibmveth_free_buffer_pool(adapter, 489 &adapter->rx_buff_pool[i]); 490 } 491 492 static int ibmveth_register_logical_lan(struct ibmveth_adapter *adapter, ··· 632 ibmveth_cleanup(adapter); 633 napi_disable(&adapter->napi); 634 return rc; 635 } 636 637 ibmveth_debug_printk("initial replenish cycle\n"); ··· 898 unsigned int tx_packets = 0; 899 unsigned int tx_send_failed = 0; 900 unsigned int tx_map_failed = 0; 901 902 desc.fields.flags_len = IBMVETH_BUF_VALID | skb->len; 903 - desc.fields.address = dma_map_single(&adapter->vdev->dev, skb->data, 904 - skb->len, DMA_TO_DEVICE); 905 906 if (skb->ip_summed == CHECKSUM_PARTIAL && 907 ip_hdr(skb)->protocol != IPPROTO_TCP && skb_checksum_help(skb)) { ··· 922 buf[1] = 0; 923 } 924 925 - if (dma_mapping_error(desc.fields.address)) { 926 - ibmveth_error_printk("tx: unable to map xmit buffer\n"); 927 tx_map_failed++; 928 - tx_dropped++; 929 - goto out; 930 - } 931 932 /* send the frame. Arbitrarily set retrycount to 1024 */ 933 correlator = 0; ··· 955 netdev->trans_start = jiffies; 956 } 957 958 - dma_unmap_single(&adapter->vdev->dev, desc.fields.address, 959 - skb->len, DMA_TO_DEVICE); 960 961 out: spin_lock_irqsave(&adapter->stats_lock, flags); 962 netdev->stats.tx_dropped += tx_dropped; ··· 1105 static int ibmveth_change_mtu(struct net_device *dev, int new_mtu) 1106 { 1107 struct ibmveth_adapter *adapter = dev->priv; 1108 int new_mtu_oh = new_mtu + IBMVETH_BUFF_OH; 1109 - int i, rc; 1110 1111 if (new_mtu < IBMVETH_MAX_MTU) 1112 return -EINVAL; ··· 1138 ibmveth_close(adapter->netdev); 1139 adapter->pool_config = 0; 1140 dev->mtu = new_mtu; 1141 - if ((rc = ibmveth_open(adapter->netdev))) 1142 - return rc; 1143 - } else 1144 - dev->mtu = new_mtu; 1145 return 0; 1146 } 1147 } ··· 1160 ibmveth_interrupt(dev->irq, dev); 1161 } 1162 #endif 1163 1164 static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_id *id) 1165 { ··· 1345 ibmveth_proc_unregister_adapter(adapter); 1346 1347 free_netdev(netdev); 1348 return 0; 1349 } 1350 ··· 1591 .id_table = ibmveth_device_table, 1592 .probe = ibmveth_probe, 1593 .remove = ibmveth_remove, 1594 .driver = { 1595 .name = ibmveth_driver_name, 1596 .owner = THIS_MODULE,
··· 33 */ 34 35 #include <linux/module.h> 36 + #include <linux/moduleparam.h> 37 #include <linux/types.h> 38 #include <linux/errno.h> 39 #include <linux/ioport.h> ··· 52 #include <asm/hvcall.h> 53 #include <asm/atomic.h> 54 #include <asm/vio.h> 55 + #include <asm/iommu.h> 56 #include <asm/uaccess.h> 57 + #include <asm/firmware.h> 58 #include <linux/seq_file.h> 59 60 #include "ibmveth.h" ··· 94 static void ibmveth_proc_unregister_adapter(struct ibmveth_adapter *adapter); 95 static irqreturn_t ibmveth_interrupt(int irq, void *dev_instance); 96 static void ibmveth_rxq_harvest_buffer(struct ibmveth_adapter *adapter); 97 + static unsigned long ibmveth_get_desired_dma(struct vio_dev *vdev); 98 static struct kobj_type ktype_veth_pool; 99 + 100 101 #ifdef CONFIG_PROC_FS 102 #define IBMVETH_PROC_DIR "ibmveth" ··· 226 u32 i; 227 u32 count = pool->size - atomic_read(&pool->available); 228 u32 buffers_added = 0; 229 + struct sk_buff *skb; 230 + unsigned int free_index, index; 231 + u64 correlator; 232 + unsigned long lpar_rc; 233 + dma_addr_t dma_addr; 234 235 mb(); 236 237 for(i = 0; i < count; ++i) { 238 union ibmveth_buf_desc desc; 239 240 skb = alloc_skb(pool->buff_size, GFP_ATOMIC); 241 ··· 255 dma_addr = dma_map_single(&adapter->vdev->dev, skb->data, 256 pool->buff_size, DMA_FROM_DEVICE); 257 258 + if (dma_mapping_error(dma_addr)) 259 + goto failure; 260 + 261 pool->free_map[free_index] = IBM_VETH_INVALID_MAP; 262 pool->dma_addr[index] = dma_addr; 263 pool->skbuff[index] = skb; ··· 267 268 lpar_rc = h_add_logical_lan_buffer(adapter->vdev->unit_address, desc.desc); 269 270 + if (lpar_rc != H_SUCCESS) 271 + goto failure; 272 + else { 273 buffers_added++; 274 adapter->replenish_add_buff_success++; 275 } 276 } 277 + 278 + mb(); 279 + atomic_add(buffers_added, &(pool->available)); 280 + return; 281 + 282 + failure: 283 + pool->free_map[free_index] = index; 284 + pool->skbuff[index] = NULL; 285 + if (pool->consumer_index == 0) 286 + pool->consumer_index = pool->size - 1; 287 + else 288 + pool->consumer_index--; 289 + if (!dma_mapping_error(dma_addr)) 290 + dma_unmap_single(&adapter->vdev->dev, 291 + pool->dma_addr[index], pool->buff_size, 292 + DMA_FROM_DEVICE); 293 + dev_kfree_skb_any(skb); 294 + adapter->replenish_add_buff_failure++; 295 296 mb(); 297 atomic_add(buffers_added, &(pool->available)); ··· 297 298 adapter->replenish_task_cycles++; 299 300 + for (i = (IbmVethNumBufferPools - 1); i >= 0; i--) 301 if(adapter->rx_buff_pool[i].active) 302 ibmveth_replenish_buffer_pool(adapter, 303 &adapter->rx_buff_pool[i]); ··· 472 if (adapter->rx_buff_pool[i].active) 473 ibmveth_free_buffer_pool(adapter, 474 &adapter->rx_buff_pool[i]); 475 + 476 + if (adapter->bounce_buffer != NULL) { 477 + if (!dma_mapping_error(adapter->bounce_buffer_dma)) { 478 + dma_unmap_single(&adapter->vdev->dev, 479 + adapter->bounce_buffer_dma, 480 + adapter->netdev->mtu + IBMVETH_BUFF_OH, 481 + DMA_BIDIRECTIONAL); 482 + adapter->bounce_buffer_dma = DMA_ERROR_CODE; 483 + } 484 + kfree(adapter->bounce_buffer); 485 + adapter->bounce_buffer = NULL; 486 + } 487 } 488 489 static int ibmveth_register_logical_lan(struct ibmveth_adapter *adapter, ··· 605 ibmveth_cleanup(adapter); 606 napi_disable(&adapter->napi); 607 return rc; 608 + } 609 + 610 + adapter->bounce_buffer = 611 + kmalloc(netdev->mtu + IBMVETH_BUFF_OH, GFP_KERNEL); 612 + if (!adapter->bounce_buffer) { 613 + ibmveth_error_printk("unable to allocate bounce buffer\n"); 614 + ibmveth_cleanup(adapter); 615 + napi_disable(&adapter->napi); 616 + return -ENOMEM; 617 + } 618 + adapter->bounce_buffer_dma = 619 + dma_map_single(&adapter->vdev->dev, adapter->bounce_buffer, 620 + netdev->mtu + IBMVETH_BUFF_OH, DMA_BIDIRECTIONAL); 621 + if (dma_mapping_error(adapter->bounce_buffer_dma)) { 622 + ibmveth_error_printk("unable to map bounce buffer\n"); 623 + ibmveth_cleanup(adapter); 624 + napi_disable(&adapter->napi); 625 + return -ENOMEM; 626 } 627 628 ibmveth_debug_printk("initial replenish cycle\n"); ··· 853 unsigned int tx_packets = 0; 854 unsigned int tx_send_failed = 0; 855 unsigned int tx_map_failed = 0; 856 + int used_bounce = 0; 857 + unsigned long data_dma_addr; 858 859 desc.fields.flags_len = IBMVETH_BUF_VALID | skb->len; 860 + data_dma_addr = dma_map_single(&adapter->vdev->dev, skb->data, 861 + skb->len, DMA_TO_DEVICE); 862 863 if (skb->ip_summed == CHECKSUM_PARTIAL && 864 ip_hdr(skb)->protocol != IPPROTO_TCP && skb_checksum_help(skb)) { ··· 875 buf[1] = 0; 876 } 877 878 + if (dma_mapping_error(data_dma_addr)) { 879 + if (!firmware_has_feature(FW_FEATURE_CMO)) 880 + ibmveth_error_printk("tx: unable to map xmit buffer\n"); 881 + skb_copy_from_linear_data(skb, adapter->bounce_buffer, 882 + skb->len); 883 + desc.fields.address = adapter->bounce_buffer_dma; 884 tx_map_failed++; 885 + used_bounce = 1; 886 + } else 887 + desc.fields.address = data_dma_addr; 888 889 /* send the frame. Arbitrarily set retrycount to 1024 */ 890 correlator = 0; ··· 904 netdev->trans_start = jiffies; 905 } 906 907 + if (!used_bounce) 908 + dma_unmap_single(&adapter->vdev->dev, data_dma_addr, 909 + skb->len, DMA_TO_DEVICE); 910 911 out: spin_lock_irqsave(&adapter->stats_lock, flags); 912 netdev->stats.tx_dropped += tx_dropped; ··· 1053 static int ibmveth_change_mtu(struct net_device *dev, int new_mtu) 1054 { 1055 struct ibmveth_adapter *adapter = dev->priv; 1056 + struct vio_dev *viodev = adapter->vdev; 1057 int new_mtu_oh = new_mtu + IBMVETH_BUFF_OH; 1058 + int i; 1059 1060 if (new_mtu < IBMVETH_MAX_MTU) 1061 return -EINVAL; ··· 1085 ibmveth_close(adapter->netdev); 1086 adapter->pool_config = 0; 1087 dev->mtu = new_mtu; 1088 + vio_cmo_set_dev_desired(viodev, 1089 + ibmveth_get_desired_dma 1090 + (viodev)); 1091 + return ibmveth_open(adapter->netdev); 1092 + } 1093 + dev->mtu = new_mtu; 1094 + vio_cmo_set_dev_desired(viodev, 1095 + ibmveth_get_desired_dma 1096 + (viodev)); 1097 return 0; 1098 } 1099 } ··· 1102 ibmveth_interrupt(dev->irq, dev); 1103 } 1104 #endif 1105 + 1106 + /** 1107 + * ibmveth_get_desired_dma - Calculate IO memory desired by the driver 1108 + * 1109 + * @vdev: struct vio_dev for the device whose desired IO mem is to be returned 1110 + * 1111 + * Return value: 1112 + * Number of bytes of IO data the driver will need to perform well. 1113 + */ 1114 + static unsigned long ibmveth_get_desired_dma(struct vio_dev *vdev) 1115 + { 1116 + struct net_device *netdev = dev_get_drvdata(&vdev->dev); 1117 + struct ibmveth_adapter *adapter; 1118 + unsigned long ret; 1119 + int i; 1120 + int rxqentries = 1; 1121 + 1122 + /* netdev inits at probe time along with the structures we need below*/ 1123 + if (netdev == NULL) 1124 + return IOMMU_PAGE_ALIGN(IBMVETH_IO_ENTITLEMENT_DEFAULT); 1125 + 1126 + adapter = netdev_priv(netdev); 1127 + 1128 + ret = IBMVETH_BUFF_LIST_SIZE + IBMVETH_FILT_LIST_SIZE; 1129 + ret += IOMMU_PAGE_ALIGN(netdev->mtu); 1130 + 1131 + for (i = 0; i < IbmVethNumBufferPools; i++) { 1132 + /* add the size of the active receive buffers */ 1133 + if (adapter->rx_buff_pool[i].active) 1134 + ret += 1135 + adapter->rx_buff_pool[i].size * 1136 + IOMMU_PAGE_ALIGN(adapter->rx_buff_pool[i]. 1137 + buff_size); 1138 + rxqentries += adapter->rx_buff_pool[i].size; 1139 + } 1140 + /* add the size of the receive queue entries */ 1141 + ret += IOMMU_PAGE_ALIGN(rxqentries * sizeof(struct ibmveth_rx_q_entry)); 1142 + 1143 + return ret; 1144 + } 1145 1146 static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_id *id) 1147 { ··· 1247 ibmveth_proc_unregister_adapter(adapter); 1248 1249 free_netdev(netdev); 1250 + dev_set_drvdata(&dev->dev, NULL); 1251 + 1252 return 0; 1253 } 1254 ··· 1491 .id_table = ibmveth_device_table, 1492 .probe = ibmveth_probe, 1493 .remove = ibmveth_remove, 1494 + .get_desired_dma = ibmveth_get_desired_dma, 1495 .driver = { 1496 .name = ibmveth_driver_name, 1497 .owner = THIS_MODULE,
+5
drivers/net/ibmveth.h
··· 93 plpar_hcall_norets(H_CHANGE_LOGICAL_LAN_MAC, ua, mac) 94 95 #define IbmVethNumBufferPools 5 96 #define IBMVETH_BUFF_OH 22 /* Overhead: 14 ethernet header + 8 opaque handle */ 97 #define IBMVETH_MAX_MTU 68 98 #define IBMVETH_MAX_POOL_COUNT 4096 99 #define IBMVETH_MAX_BUF_SIZE (1024 * 128) 100 101 static int pool_size[] = { 512, 1024 * 2, 1024 * 16, 1024 * 32, 1024 * 64 }; ··· 146 struct ibmveth_rx_q rx_queue; 147 int pool_config; 148 int rx_csum; 149 150 /* adapter specific stats */ 151 u64 replenish_task_cycles;
··· 93 plpar_hcall_norets(H_CHANGE_LOGICAL_LAN_MAC, ua, mac) 94 95 #define IbmVethNumBufferPools 5 96 + #define IBMVETH_IO_ENTITLEMENT_DEFAULT 4243456 /* MTU of 1500 needs 4.2Mb */ 97 #define IBMVETH_BUFF_OH 22 /* Overhead: 14 ethernet header + 8 opaque handle */ 98 #define IBMVETH_MAX_MTU 68 99 #define IBMVETH_MAX_POOL_COUNT 4096 100 + #define IBMVETH_BUFF_LIST_SIZE 4096 101 + #define IBMVETH_FILT_LIST_SIZE 4096 102 #define IBMVETH_MAX_BUF_SIZE (1024 * 128) 103 104 static int pool_size[] = { 512, 1024 * 2, 1024 * 16, 1024 * 32, 1024 * 64 }; ··· 143 struct ibmveth_rx_q rx_queue; 144 int pool_config; 145 int rx_csum; 146 + void *bounce_buffer; 147 + dma_addr_t bounce_buffer_dma; 148 149 /* adapter specific stats */ 150 u64 replenish_task_cycles;