Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

powerpc/pseries: vio bus support for CMO

This is a large patch but the normal code path is not affected. For
non-pSeries platforms the code is ifdef'ed out and for non-CMO enabled
pSeries systems this does not affect the normal code path. Devices that
do not perform DMA operations do not need modification with this patch.
The function get_desired_dma was renamed from get_io_entitlement for
clarity.

Overview

Cooperative Memory Overcommitment (CMO) allows for a set of OS partitions
to be run with less RAM than the aggregate needs of the group of
partitions. The firmware will balance memory between the partitions
and page in/out memory as needed. Based on the number and type of IO
adpaters preset each partition is allocated an amount of memory for
DMA operations and this allocation will be guaranteed to the partition;
this is referred to as the partition's 'entitlement'.

Partitions running in a CMO environment can only have virtual IO devices
present. The VIO bus layer will manage the IO entitlement for the system.
Accounting, at a system and per-device level, is tracked in the VIO bus
code and exposed via sysfs. A set of dma_ops functions are added to
the bus to allow for this accounting.

Bus initialization

At initialization, the bus will calculate the minimum needs of the system
based on providing each device present with a standard minimum entitlement
along with a spare allocation for the bus to handle hotplug events.
If the minimum needs can not be met the system boot will be halted.

Device changes

The significant changes for devices while running under CMO are that the
devices must specify how much dedicated IO entitlement they desire and
must also handle DMA mapping errors that can occur due to constrained
IO memory. The virtual IO drivers are modified to silence errors when
DMA mappings fail for CMO and handle these failures gracefully.

Each devices will be guaranteed a minimum entitlement that can always
be mapped. Devices will specify how much entitlement they desire and
the VIO bus will attempt to provide for this. Devices can change their
desired entitlement level at any point in time to address particular needs
(via vio_cmo_set_dev_desired()), not just at device probe time.

VIO bus changes

The system will have a particular entitlement level available from which
it can provide memory to the devices. The bus defines two pools of memory
within this entitlement, the reserved and excess pools. Each device is
provided with it's own entitlement no less than a system defined minimum
entitlement and no greater than what the device has specified as it's
desired entitlement. The entitlement provided to devices comes from the
reserve pool. The reserve pool can also contain a spare allocation as
large as the system defined minimum entitlement which is used for device
hotplug events. Any entitlement not needed to fulfill the needs of a
reserve pool is placed in the excess pool. Each device is guaranteed
that it can map up to it's entitled level; additional mapping are possible
as long as there is unmapped memory in the excess pool.

Bus probe

As the system starts, each device is given an entitlement equal only
to the system defined minimum entitlement. The reserve pool is equal
to the sum of these entitlements, plus a spare allocation. The VIO bus
also tracks the aggregate desired entitlement of all the devices. If the
system desired entitlement is greater than the size of the reserve pool,
when devices unmap IO memory it will be reserved and a balance operation
will be scheduled for some time in the future.

Entitlement balancing

The balance function tries to fairly distribute entitlement between the
devices in the system with the goal of providing each device with it's
desired amount of entitlement. Devices using more than what would be
ideal will have their entitled set-point adjusted; this will effectively
set a goal for lower IO memory usage as future mappings can fail and
deallocations will trigger a balance operation to distribute the newly
unmapped memory. A fair distribution of entitlement can take several
balance operations to achieve. Entitlement changes and device DLPAR
events will alter the state of CMO and will trigger balance operations.

Hotplug events

The VIO bus allows for changes in system entitlement at run-time via
'vio_cmo_entitlement_update()'. When devices are added the hotplug
device event will be preceded by a system entitlement increase and this
is reversed when devices are removed.

The following changes are made that the VIO bus layer for CMO:
* add IO memory accounting per device structure.
* add IO memory entitlement query function to driver structure.
* during vio bus probe, if CMO is enabled, check that driver has
memory entitlement query function defined. Fail if function not defined.
* fail to register driver if io entitlement function not defined.
* create set of dma_ops at vio level for CMO that will track allocations
and return DMA failures once entitlement is reached. Entitlement will
limited by overall system entitlement. Devices will have a reserved
quantity of memory that is guaranteed, the rest can be used as available.
* expose entitlement, current allocation, desired allocation, and the
allocation error counter for devices to the user through sysfs
* provide mechanism for changing a device's desired entitlement at run time
for devices as an exported function and sysfs tunable
* track any DMA failures for entitled IO memory for each vio device.
* check entitlement against available system entitlement on device add
* track entitlement metrics (high water mark, current usage)
* provide function to reset high water mark
* provide minimum and desired entitlement numbers at a bus level
* provide drivers with a minimum guaranteed entitlement
* balance available entitlement between devices to satisfy their needs
* handle system entitlement changes and device hotplug

Signed-off-by: Robert Jennings <rcj@linux.vnet.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
a90ab95a 6490c490

+1052 -8
+1027 -6
arch/powerpc/kernel/vio.c
··· 1 1 /* 2 2 * IBM PowerPC Virtual I/O Infrastructure Support. 3 3 * 4 - * Copyright (c) 2003-2005 IBM Corp. 4 + * Copyright (c) 2003,2008 IBM Corp. 5 5 * Dave Engebretsen engebret@us.ibm.com 6 6 * Santiago Leon santil@us.ibm.com 7 7 * Hollis Blanchard <hollisb@us.ibm.com> 8 8 * Stephen Rothwell 9 + * Robert Jennings <rcjenn@us.ibm.com> 9 10 * 10 11 * This program is free software; you can redistribute it and/or 11 12 * modify it under the terms of the GNU General Public License ··· 46 45 .dev.bus_id = "vio", 47 46 .dev.bus = &vio_bus_type, 48 47 }; 48 + 49 + #ifdef CONFIG_PPC_SMLPAR 50 + /** 51 + * vio_cmo_pool - A pool of IO memory for CMO use 52 + * 53 + * @size: The size of the pool in bytes 54 + * @free: The amount of free memory in the pool 55 + */ 56 + struct vio_cmo_pool { 57 + size_t size; 58 + size_t free; 59 + }; 60 + 61 + /* How many ms to delay queued balance work */ 62 + #define VIO_CMO_BALANCE_DELAY 100 63 + 64 + /* Portion out IO memory to CMO devices by this chunk size */ 65 + #define VIO_CMO_BALANCE_CHUNK 131072 66 + 67 + /** 68 + * vio_cmo_dev_entry - A device that is CMO-enabled and requires entitlement 69 + * 70 + * @vio_dev: struct vio_dev pointer 71 + * @list: pointer to other devices on bus that are being tracked 72 + */ 73 + struct vio_cmo_dev_entry { 74 + struct vio_dev *viodev; 75 + struct list_head list; 76 + }; 77 + 78 + /** 79 + * vio_cmo - VIO bus accounting structure for CMO entitlement 80 + * 81 + * @lock: spinlock for entire structure 82 + * @balance_q: work queue for balancing system entitlement 83 + * @device_list: list of CMO-enabled devices requiring entitlement 84 + * @entitled: total system entitlement in bytes 85 + * @reserve: pool of memory from which devices reserve entitlement, incl. spare 86 + * @excess: pool of excess entitlement not needed for device reserves or spare 87 + * @spare: IO memory for device hotplug functionality 88 + * @min: minimum necessary for system operation 89 + * @desired: desired memory for system operation 90 + * @curr: bytes currently allocated 91 + * @high: high water mark for IO data usage 92 + */ 93 + struct vio_cmo { 94 + spinlock_t lock; 95 + struct delayed_work balance_q; 96 + struct list_head device_list; 97 + size_t entitled; 98 + struct vio_cmo_pool reserve; 99 + struct vio_cmo_pool excess; 100 + size_t spare; 101 + size_t min; 102 + size_t desired; 103 + size_t curr; 104 + size_t high; 105 + } vio_cmo; 106 + 107 + /** 108 + * vio_cmo_OF_devices - Count the number of OF devices that have DMA windows 109 + */ 110 + static int vio_cmo_num_OF_devs(void) 111 + { 112 + struct device_node *node_vroot; 113 + int count = 0; 114 + 115 + /* 116 + * Count the number of vdevice entries with an 117 + * ibm,my-dma-window OF property 118 + */ 119 + node_vroot = of_find_node_by_name(NULL, "vdevice"); 120 + if (node_vroot) { 121 + struct device_node *of_node; 122 + struct property *prop; 123 + 124 + for_each_child_of_node(node_vroot, of_node) { 125 + prop = of_find_property(of_node, "ibm,my-dma-window", 126 + NULL); 127 + if (prop) 128 + count++; 129 + } 130 + } 131 + of_node_put(node_vroot); 132 + return count; 133 + } 134 + 135 + /** 136 + * vio_cmo_alloc - allocate IO memory for CMO-enable devices 137 + * 138 + * @viodev: VIO device requesting IO memory 139 + * @size: size of allocation requested 140 + * 141 + * Allocations come from memory reserved for the devices and any excess 142 + * IO memory available to all devices. The spare pool used to service 143 + * hotplug must be equal to %VIO_CMO_MIN_ENT for the excess pool to be 144 + * made available. 145 + * 146 + * Return codes: 147 + * 0 for successful allocation and -ENOMEM for a failure 148 + */ 149 + static inline int vio_cmo_alloc(struct vio_dev *viodev, size_t size) 150 + { 151 + unsigned long flags; 152 + size_t reserve_free = 0; 153 + size_t excess_free = 0; 154 + int ret = -ENOMEM; 155 + 156 + spin_lock_irqsave(&vio_cmo.lock, flags); 157 + 158 + /* Determine the amount of free entitlement available in reserve */ 159 + if (viodev->cmo.entitled > viodev->cmo.allocated) 160 + reserve_free = viodev->cmo.entitled - viodev->cmo.allocated; 161 + 162 + /* If spare is not fulfilled, the excess pool can not be used. */ 163 + if (vio_cmo.spare >= VIO_CMO_MIN_ENT) 164 + excess_free = vio_cmo.excess.free; 165 + 166 + /* The request can be satisfied */ 167 + if ((reserve_free + excess_free) >= size) { 168 + vio_cmo.curr += size; 169 + if (vio_cmo.curr > vio_cmo.high) 170 + vio_cmo.high = vio_cmo.curr; 171 + viodev->cmo.allocated += size; 172 + size -= min(reserve_free, size); 173 + vio_cmo.excess.free -= size; 174 + ret = 0; 175 + } 176 + 177 + spin_unlock_irqrestore(&vio_cmo.lock, flags); 178 + return ret; 179 + } 180 + 181 + /** 182 + * vio_cmo_dealloc - deallocate IO memory from CMO-enable devices 183 + * @viodev: VIO device freeing IO memory 184 + * @size: size of deallocation 185 + * 186 + * IO memory is freed by the device back to the correct memory pools. 187 + * The spare pool is replenished first from either memory pool, then 188 + * the reserve pool is used to reduce device entitlement, the excess 189 + * pool is used to increase the reserve pool toward the desired entitlement 190 + * target, and then the remaining memory is returned to the pools. 191 + * 192 + */ 193 + static inline void vio_cmo_dealloc(struct vio_dev *viodev, size_t size) 194 + { 195 + unsigned long flags; 196 + size_t spare_needed = 0; 197 + size_t excess_freed = 0; 198 + size_t reserve_freed = size; 199 + size_t tmp; 200 + int balance = 0; 201 + 202 + spin_lock_irqsave(&vio_cmo.lock, flags); 203 + vio_cmo.curr -= size; 204 + 205 + /* Amount of memory freed from the excess pool */ 206 + if (viodev->cmo.allocated > viodev->cmo.entitled) { 207 + excess_freed = min(reserve_freed, (viodev->cmo.allocated - 208 + viodev->cmo.entitled)); 209 + reserve_freed -= excess_freed; 210 + } 211 + 212 + /* Remove allocation from device */ 213 + viodev->cmo.allocated -= (reserve_freed + excess_freed); 214 + 215 + /* Spare is a subset of the reserve pool, replenish it first. */ 216 + spare_needed = VIO_CMO_MIN_ENT - vio_cmo.spare; 217 + 218 + /* 219 + * Replenish the spare in the reserve pool from the excess pool. 220 + * This moves entitlement into the reserve pool. 221 + */ 222 + if (spare_needed && excess_freed) { 223 + tmp = min(excess_freed, spare_needed); 224 + vio_cmo.excess.size -= tmp; 225 + vio_cmo.reserve.size += tmp; 226 + vio_cmo.spare += tmp; 227 + excess_freed -= tmp; 228 + spare_needed -= tmp; 229 + balance = 1; 230 + } 231 + 232 + /* 233 + * Replenish the spare in the reserve pool from the reserve pool. 234 + * This removes entitlement from the device down to VIO_CMO_MIN_ENT, 235 + * if needed, and gives it to the spare pool. The amount of used 236 + * memory in this pool does not change. 237 + */ 238 + if (spare_needed && reserve_freed) { 239 + tmp = min(spare_needed, min(reserve_freed, 240 + (viodev->cmo.entitled - 241 + VIO_CMO_MIN_ENT))); 242 + 243 + vio_cmo.spare += tmp; 244 + viodev->cmo.entitled -= tmp; 245 + reserve_freed -= tmp; 246 + spare_needed -= tmp; 247 + balance = 1; 248 + } 249 + 250 + /* 251 + * Increase the reserve pool until the desired allocation is met. 252 + * Move an allocation freed from the excess pool into the reserve 253 + * pool and schedule a balance operation. 254 + */ 255 + if (excess_freed && (vio_cmo.desired > vio_cmo.reserve.size)) { 256 + tmp = min(excess_freed, (vio_cmo.desired - vio_cmo.reserve.size)); 257 + 258 + vio_cmo.excess.size -= tmp; 259 + vio_cmo.reserve.size += tmp; 260 + excess_freed -= tmp; 261 + balance = 1; 262 + } 263 + 264 + /* Return memory from the excess pool to that pool */ 265 + if (excess_freed) 266 + vio_cmo.excess.free += excess_freed; 267 + 268 + if (balance) 269 + schedule_delayed_work(&vio_cmo.balance_q, VIO_CMO_BALANCE_DELAY); 270 + spin_unlock_irqrestore(&vio_cmo.lock, flags); 271 + } 272 + 273 + /** 274 + * vio_cmo_entitlement_update - Manage system entitlement changes 275 + * 276 + * @new_entitlement: new system entitlement to attempt to accommodate 277 + * 278 + * Increases in entitlement will be used to fulfill the spare entitlement 279 + * and the rest is given to the excess pool. Decreases, if they are 280 + * possible, come from the excess pool and from unused device entitlement 281 + * 282 + * Returns: 0 on success, -ENOMEM when change can not be made 283 + */ 284 + int vio_cmo_entitlement_update(size_t new_entitlement) 285 + { 286 + struct vio_dev *viodev; 287 + struct vio_cmo_dev_entry *dev_ent; 288 + unsigned long flags; 289 + size_t avail, delta, tmp; 290 + 291 + spin_lock_irqsave(&vio_cmo.lock, flags); 292 + 293 + /* Entitlement increases */ 294 + if (new_entitlement > vio_cmo.entitled) { 295 + delta = new_entitlement - vio_cmo.entitled; 296 + 297 + /* Fulfill spare allocation */ 298 + if (vio_cmo.spare < VIO_CMO_MIN_ENT) { 299 + tmp = min(delta, (VIO_CMO_MIN_ENT - vio_cmo.spare)); 300 + vio_cmo.spare += tmp; 301 + vio_cmo.reserve.size += tmp; 302 + delta -= tmp; 303 + } 304 + 305 + /* Remaining new allocation goes to the excess pool */ 306 + vio_cmo.entitled += delta; 307 + vio_cmo.excess.size += delta; 308 + vio_cmo.excess.free += delta; 309 + 310 + goto out; 311 + } 312 + 313 + /* Entitlement decreases */ 314 + delta = vio_cmo.entitled - new_entitlement; 315 + avail = vio_cmo.excess.free; 316 + 317 + /* 318 + * Need to check how much unused entitlement each device can 319 + * sacrifice to fulfill entitlement change. 320 + */ 321 + list_for_each_entry(dev_ent, &vio_cmo.device_list, list) { 322 + if (avail >= delta) 323 + break; 324 + 325 + viodev = dev_ent->viodev; 326 + if ((viodev->cmo.entitled > viodev->cmo.allocated) && 327 + (viodev->cmo.entitled > VIO_CMO_MIN_ENT)) 328 + avail += viodev->cmo.entitled - 329 + max_t(size_t, viodev->cmo.allocated, 330 + VIO_CMO_MIN_ENT); 331 + } 332 + 333 + if (delta <= avail) { 334 + vio_cmo.entitled -= delta; 335 + 336 + /* Take entitlement from the excess pool first */ 337 + tmp = min(vio_cmo.excess.free, delta); 338 + vio_cmo.excess.size -= tmp; 339 + vio_cmo.excess.free -= tmp; 340 + delta -= tmp; 341 + 342 + /* 343 + * Remove all but VIO_CMO_MIN_ENT bytes from devices 344 + * until entitlement change is served 345 + */ 346 + list_for_each_entry(dev_ent, &vio_cmo.device_list, list) { 347 + if (!delta) 348 + break; 349 + 350 + viodev = dev_ent->viodev; 351 + tmp = 0; 352 + if ((viodev->cmo.entitled > viodev->cmo.allocated) && 353 + (viodev->cmo.entitled > VIO_CMO_MIN_ENT)) 354 + tmp = viodev->cmo.entitled - 355 + max_t(size_t, viodev->cmo.allocated, 356 + VIO_CMO_MIN_ENT); 357 + viodev->cmo.entitled -= min(tmp, delta); 358 + delta -= min(tmp, delta); 359 + } 360 + } else { 361 + spin_unlock_irqrestore(&vio_cmo.lock, flags); 362 + return -ENOMEM; 363 + } 364 + 365 + out: 366 + schedule_delayed_work(&vio_cmo.balance_q, 0); 367 + spin_unlock_irqrestore(&vio_cmo.lock, flags); 368 + return 0; 369 + } 370 + 371 + /** 372 + * vio_cmo_balance - Balance entitlement among devices 373 + * 374 + * @work: work queue structure for this operation 375 + * 376 + * Any system entitlement above the minimum needed for devices, or 377 + * already allocated to devices, can be distributed to the devices. 378 + * The list of devices is iterated through to recalculate the desired 379 + * entitlement level and to determine how much entitlement above the 380 + * minimum entitlement is allocated to devices. 381 + * 382 + * Small chunks of the available entitlement are given to devices until 383 + * their requirements are fulfilled or there is no entitlement left to give. 384 + * Upon completion sizes of the reserve and excess pools are calculated. 385 + * 386 + * The system minimum entitlement level is also recalculated here. 387 + * Entitlement will be reserved for devices even after vio_bus_remove to 388 + * accommodate reloading the driver. The OF tree is walked to count the 389 + * number of devices present and this will remove entitlement for devices 390 + * that have actually left the system after having vio_bus_remove called. 391 + */ 392 + static void vio_cmo_balance(struct work_struct *work) 393 + { 394 + struct vio_cmo *cmo; 395 + struct vio_dev *viodev; 396 + struct vio_cmo_dev_entry *dev_ent; 397 + unsigned long flags; 398 + size_t avail = 0, level, chunk, need; 399 + int devcount = 0, fulfilled; 400 + 401 + cmo = container_of(work, struct vio_cmo, balance_q.work); 402 + 403 + spin_lock_irqsave(&vio_cmo.lock, flags); 404 + 405 + /* Calculate minimum entitlement and fulfill spare */ 406 + cmo->min = vio_cmo_num_OF_devs() * VIO_CMO_MIN_ENT; 407 + BUG_ON(cmo->min > cmo->entitled); 408 + cmo->spare = min_t(size_t, VIO_CMO_MIN_ENT, (cmo->entitled - cmo->min)); 409 + cmo->min += cmo->spare; 410 + cmo->desired = cmo->min; 411 + 412 + /* 413 + * Determine how much entitlement is available and reset device 414 + * entitlements 415 + */ 416 + avail = cmo->entitled - cmo->spare; 417 + list_for_each_entry(dev_ent, &vio_cmo.device_list, list) { 418 + viodev = dev_ent->viodev; 419 + devcount++; 420 + viodev->cmo.entitled = VIO_CMO_MIN_ENT; 421 + cmo->desired += (viodev->cmo.desired - VIO_CMO_MIN_ENT); 422 + avail -= max_t(size_t, viodev->cmo.allocated, VIO_CMO_MIN_ENT); 423 + } 424 + 425 + /* 426 + * Having provided each device with the minimum entitlement, loop 427 + * over the devices portioning out the remaining entitlement 428 + * until there is nothing left. 429 + */ 430 + level = VIO_CMO_MIN_ENT; 431 + while (avail) { 432 + fulfilled = 0; 433 + list_for_each_entry(dev_ent, &vio_cmo.device_list, list) { 434 + viodev = dev_ent->viodev; 435 + 436 + if (viodev->cmo.desired <= level) { 437 + fulfilled++; 438 + continue; 439 + } 440 + 441 + /* 442 + * Give the device up to VIO_CMO_BALANCE_CHUNK 443 + * bytes of entitlement, but do not exceed the 444 + * desired level of entitlement for the device. 445 + */ 446 + chunk = min_t(size_t, avail, VIO_CMO_BALANCE_CHUNK); 447 + chunk = min(chunk, (viodev->cmo.desired - 448 + viodev->cmo.entitled)); 449 + viodev->cmo.entitled += chunk; 450 + 451 + /* 452 + * If the memory for this entitlement increase was 453 + * already allocated to the device it does not come 454 + * from the available pool being portioned out. 455 + */ 456 + need = max(viodev->cmo.allocated, viodev->cmo.entitled)- 457 + max(viodev->cmo.allocated, level); 458 + avail -= need; 459 + 460 + } 461 + if (fulfilled == devcount) 462 + break; 463 + level += VIO_CMO_BALANCE_CHUNK; 464 + } 465 + 466 + /* Calculate new reserve and excess pool sizes */ 467 + cmo->reserve.size = cmo->min; 468 + cmo->excess.free = 0; 469 + cmo->excess.size = 0; 470 + need = 0; 471 + list_for_each_entry(dev_ent, &vio_cmo.device_list, list) { 472 + viodev = dev_ent->viodev; 473 + /* Calculated reserve size above the minimum entitlement */ 474 + if (viodev->cmo.entitled) 475 + cmo->reserve.size += (viodev->cmo.entitled - 476 + VIO_CMO_MIN_ENT); 477 + /* Calculated used excess entitlement */ 478 + if (viodev->cmo.allocated > viodev->cmo.entitled) 479 + need += viodev->cmo.allocated - viodev->cmo.entitled; 480 + } 481 + cmo->excess.size = cmo->entitled - cmo->reserve.size; 482 + cmo->excess.free = cmo->excess.size - need; 483 + 484 + cancel_delayed_work(container_of(work, struct delayed_work, work)); 485 + spin_unlock_irqrestore(&vio_cmo.lock, flags); 486 + } 487 + 488 + static void *vio_dma_iommu_alloc_coherent(struct device *dev, size_t size, 489 + dma_addr_t *dma_handle, gfp_t flag) 490 + { 491 + struct vio_dev *viodev = to_vio_dev(dev); 492 + void *ret; 493 + 494 + if (vio_cmo_alloc(viodev, roundup(size, IOMMU_PAGE_SIZE))) { 495 + atomic_inc(&viodev->cmo.allocs_failed); 496 + return NULL; 497 + } 498 + 499 + ret = dma_iommu_ops.alloc_coherent(dev, size, dma_handle, flag); 500 + if (unlikely(ret == NULL)) { 501 + vio_cmo_dealloc(viodev, roundup(size, IOMMU_PAGE_SIZE)); 502 + atomic_inc(&viodev->cmo.allocs_failed); 503 + } 504 + 505 + return ret; 506 + } 507 + 508 + static void vio_dma_iommu_free_coherent(struct device *dev, size_t size, 509 + void *vaddr, dma_addr_t dma_handle) 510 + { 511 + struct vio_dev *viodev = to_vio_dev(dev); 512 + 513 + dma_iommu_ops.free_coherent(dev, size, vaddr, dma_handle); 514 + 515 + vio_cmo_dealloc(viodev, roundup(size, IOMMU_PAGE_SIZE)); 516 + } 517 + 518 + static dma_addr_t vio_dma_iommu_map_single(struct device *dev, void *vaddr, 519 + size_t size, 520 + enum dma_data_direction direction, 521 + struct dma_attrs *attrs) 522 + { 523 + struct vio_dev *viodev = to_vio_dev(dev); 524 + dma_addr_t ret = DMA_ERROR_CODE; 525 + 526 + if (vio_cmo_alloc(viodev, roundup(size, IOMMU_PAGE_SIZE))) { 527 + atomic_inc(&viodev->cmo.allocs_failed); 528 + return ret; 529 + } 530 + 531 + ret = dma_iommu_ops.map_single(dev, vaddr, size, direction, attrs); 532 + if (unlikely(dma_mapping_error(ret))) { 533 + vio_cmo_dealloc(viodev, roundup(size, IOMMU_PAGE_SIZE)); 534 + atomic_inc(&viodev->cmo.allocs_failed); 535 + } 536 + 537 + return ret; 538 + } 539 + 540 + static void vio_dma_iommu_unmap_single(struct device *dev, 541 + dma_addr_t dma_handle, size_t size, 542 + enum dma_data_direction direction, 543 + struct dma_attrs *attrs) 544 + { 545 + struct vio_dev *viodev = to_vio_dev(dev); 546 + 547 + dma_iommu_ops.unmap_single(dev, dma_handle, size, direction, attrs); 548 + 549 + vio_cmo_dealloc(viodev, roundup(size, IOMMU_PAGE_SIZE)); 550 + } 551 + 552 + static int vio_dma_iommu_map_sg(struct device *dev, struct scatterlist *sglist, 553 + int nelems, enum dma_data_direction direction, 554 + struct dma_attrs *attrs) 555 + { 556 + struct vio_dev *viodev = to_vio_dev(dev); 557 + struct scatterlist *sgl; 558 + int ret, count = 0; 559 + size_t alloc_size = 0; 560 + 561 + for (sgl = sglist; count < nelems; count++, sgl++) 562 + alloc_size += roundup(sgl->length, IOMMU_PAGE_SIZE); 563 + 564 + if (vio_cmo_alloc(viodev, alloc_size)) { 565 + atomic_inc(&viodev->cmo.allocs_failed); 566 + return 0; 567 + } 568 + 569 + ret = dma_iommu_ops.map_sg(dev, sglist, nelems, direction, attrs); 570 + 571 + if (unlikely(!ret)) { 572 + vio_cmo_dealloc(viodev, alloc_size); 573 + atomic_inc(&viodev->cmo.allocs_failed); 574 + } 575 + 576 + for (sgl = sglist, count = 0; count < ret; count++, sgl++) 577 + alloc_size -= roundup(sgl->dma_length, IOMMU_PAGE_SIZE); 578 + if (alloc_size) 579 + vio_cmo_dealloc(viodev, alloc_size); 580 + 581 + return ret; 582 + } 583 + 584 + static void vio_dma_iommu_unmap_sg(struct device *dev, 585 + struct scatterlist *sglist, int nelems, 586 + enum dma_data_direction direction, 587 + struct dma_attrs *attrs) 588 + { 589 + struct vio_dev *viodev = to_vio_dev(dev); 590 + struct scatterlist *sgl; 591 + size_t alloc_size = 0; 592 + int count = 0; 593 + 594 + for (sgl = sglist; count < nelems; count++, sgl++) 595 + alloc_size += roundup(sgl->dma_length, IOMMU_PAGE_SIZE); 596 + 597 + dma_iommu_ops.unmap_sg(dev, sglist, nelems, direction, attrs); 598 + 599 + vio_cmo_dealloc(viodev, alloc_size); 600 + } 601 + 602 + struct dma_mapping_ops vio_dma_mapping_ops = { 603 + .alloc_coherent = vio_dma_iommu_alloc_coherent, 604 + .free_coherent = vio_dma_iommu_free_coherent, 605 + .map_single = vio_dma_iommu_map_single, 606 + .unmap_single = vio_dma_iommu_unmap_single, 607 + .map_sg = vio_dma_iommu_map_sg, 608 + .unmap_sg = vio_dma_iommu_unmap_sg, 609 + }; 610 + 611 + /** 612 + * vio_cmo_set_dev_desired - Set desired entitlement for a device 613 + * 614 + * @viodev: struct vio_dev for device to alter 615 + * @new_desired: new desired entitlement level in bytes 616 + * 617 + * For use by devices to request a change to their entitlement at runtime or 618 + * through sysfs. The desired entitlement level is changed and a balancing 619 + * of system resources is scheduled to run in the future. 620 + */ 621 + void vio_cmo_set_dev_desired(struct vio_dev *viodev, size_t desired) 622 + { 623 + unsigned long flags; 624 + struct vio_cmo_dev_entry *dev_ent; 625 + int found = 0; 626 + 627 + if (!firmware_has_feature(FW_FEATURE_CMO)) 628 + return; 629 + 630 + spin_lock_irqsave(&vio_cmo.lock, flags); 631 + if (desired < VIO_CMO_MIN_ENT) 632 + desired = VIO_CMO_MIN_ENT; 633 + 634 + /* 635 + * Changes will not be made for devices not in the device list. 636 + * If it is not in the device list, then no driver is loaded 637 + * for the device and it can not receive entitlement. 638 + */ 639 + list_for_each_entry(dev_ent, &vio_cmo.device_list, list) 640 + if (viodev == dev_ent->viodev) { 641 + found = 1; 642 + break; 643 + } 644 + if (!found) 645 + return; 646 + 647 + /* Increase/decrease in desired device entitlement */ 648 + if (desired >= viodev->cmo.desired) { 649 + /* Just bump the bus and device values prior to a balance*/ 650 + vio_cmo.desired += desired - viodev->cmo.desired; 651 + viodev->cmo.desired = desired; 652 + } else { 653 + /* Decrease bus and device values for desired entitlement */ 654 + vio_cmo.desired -= viodev->cmo.desired - desired; 655 + viodev->cmo.desired = desired; 656 + /* 657 + * If less entitlement is desired than current entitlement, move 658 + * any reserve memory in the change region to the excess pool. 659 + */ 660 + if (viodev->cmo.entitled > desired) { 661 + vio_cmo.reserve.size -= viodev->cmo.entitled - desired; 662 + vio_cmo.excess.size += viodev->cmo.entitled - desired; 663 + /* 664 + * If entitlement moving from the reserve pool to the 665 + * excess pool is currently unused, add to the excess 666 + * free counter. 667 + */ 668 + if (viodev->cmo.allocated < viodev->cmo.entitled) 669 + vio_cmo.excess.free += viodev->cmo.entitled - 670 + max(viodev->cmo.allocated, desired); 671 + viodev->cmo.entitled = desired; 672 + } 673 + } 674 + schedule_delayed_work(&vio_cmo.balance_q, 0); 675 + spin_unlock_irqrestore(&vio_cmo.lock, flags); 676 + } 677 + 678 + /** 679 + * vio_cmo_bus_probe - Handle CMO specific bus probe activities 680 + * 681 + * @viodev - Pointer to struct vio_dev for device 682 + * 683 + * Determine the devices IO memory entitlement needs, attempting 684 + * to satisfy the system minimum entitlement at first and scheduling 685 + * a balance operation to take care of the rest at a later time. 686 + * 687 + * Returns: 0 on success, -EINVAL when device doesn't support CMO, and 688 + * -ENOMEM when entitlement is not available for device or 689 + * device entry. 690 + * 691 + */ 692 + static int vio_cmo_bus_probe(struct vio_dev *viodev) 693 + { 694 + struct vio_cmo_dev_entry *dev_ent; 695 + struct device *dev = &viodev->dev; 696 + struct vio_driver *viodrv = to_vio_driver(dev->driver); 697 + unsigned long flags; 698 + size_t size; 699 + 700 + /* 701 + * Check to see that device has a DMA window and configure 702 + * entitlement for the device. 703 + */ 704 + if (of_get_property(viodev->dev.archdata.of_node, 705 + "ibm,my-dma-window", NULL)) { 706 + /* Check that the driver is CMO enabled and get desired DMA */ 707 + if (!viodrv->get_desired_dma) { 708 + dev_err(dev, "%s: device driver does not support CMO\n", 709 + __func__); 710 + return -EINVAL; 711 + } 712 + 713 + viodev->cmo.desired = IOMMU_PAGE_ALIGN(viodrv->get_desired_dma(viodev)); 714 + if (viodev->cmo.desired < VIO_CMO_MIN_ENT) 715 + viodev->cmo.desired = VIO_CMO_MIN_ENT; 716 + size = VIO_CMO_MIN_ENT; 717 + 718 + dev_ent = kmalloc(sizeof(struct vio_cmo_dev_entry), 719 + GFP_KERNEL); 720 + if (!dev_ent) 721 + return -ENOMEM; 722 + 723 + dev_ent->viodev = viodev; 724 + spin_lock_irqsave(&vio_cmo.lock, flags); 725 + list_add(&dev_ent->list, &vio_cmo.device_list); 726 + } else { 727 + viodev->cmo.desired = 0; 728 + size = 0; 729 + spin_lock_irqsave(&vio_cmo.lock, flags); 730 + } 731 + 732 + /* 733 + * If the needs for vio_cmo.min have not changed since they 734 + * were last set, the number of devices in the OF tree has 735 + * been constant and the IO memory for this is already in 736 + * the reserve pool. 737 + */ 738 + if (vio_cmo.min == ((vio_cmo_num_OF_devs() + 1) * 739 + VIO_CMO_MIN_ENT)) { 740 + /* Updated desired entitlement if device requires it */ 741 + if (size) 742 + vio_cmo.desired += (viodev->cmo.desired - 743 + VIO_CMO_MIN_ENT); 744 + } else { 745 + size_t tmp; 746 + 747 + tmp = vio_cmo.spare + vio_cmo.excess.free; 748 + if (tmp < size) { 749 + dev_err(dev, "%s: insufficient free " 750 + "entitlement to add device. " 751 + "Need %lu, have %lu\n", __func__, 752 + size, (vio_cmo.spare + tmp)); 753 + spin_unlock_irqrestore(&vio_cmo.lock, flags); 754 + return -ENOMEM; 755 + } 756 + 757 + /* Use excess pool first to fulfill request */ 758 + tmp = min(size, vio_cmo.excess.free); 759 + vio_cmo.excess.free -= tmp; 760 + vio_cmo.excess.size -= tmp; 761 + vio_cmo.reserve.size += tmp; 762 + 763 + /* Use spare if excess pool was insufficient */ 764 + vio_cmo.spare -= size - tmp; 765 + 766 + /* Update bus accounting */ 767 + vio_cmo.min += size; 768 + vio_cmo.desired += viodev->cmo.desired; 769 + } 770 + spin_unlock_irqrestore(&vio_cmo.lock, flags); 771 + return 0; 772 + } 773 + 774 + /** 775 + * vio_cmo_bus_remove - Handle CMO specific bus removal activities 776 + * 777 + * @viodev - Pointer to struct vio_dev for device 778 + * 779 + * Remove the device from the cmo device list. The minimum entitlement 780 + * will be reserved for the device as long as it is in the system. The 781 + * rest of the entitlement the device had been allocated will be returned 782 + * to the system. 783 + */ 784 + static void vio_cmo_bus_remove(struct vio_dev *viodev) 785 + { 786 + struct vio_cmo_dev_entry *dev_ent; 787 + unsigned long flags; 788 + size_t tmp; 789 + 790 + spin_lock_irqsave(&vio_cmo.lock, flags); 791 + if (viodev->cmo.allocated) { 792 + dev_err(&viodev->dev, "%s: device had %lu bytes of IO " 793 + "allocated after remove operation.\n", 794 + __func__, viodev->cmo.allocated); 795 + BUG(); 796 + } 797 + 798 + /* 799 + * Remove the device from the device list being maintained for 800 + * CMO enabled devices. 801 + */ 802 + list_for_each_entry(dev_ent, &vio_cmo.device_list, list) 803 + if (viodev == dev_ent->viodev) { 804 + list_del(&dev_ent->list); 805 + kfree(dev_ent); 806 + break; 807 + } 808 + 809 + /* 810 + * Devices may not require any entitlement and they do not need 811 + * to be processed. Otherwise, return the device's entitlement 812 + * back to the pools. 813 + */ 814 + if (viodev->cmo.entitled) { 815 + /* 816 + * This device has not yet left the OF tree, it's 817 + * minimum entitlement remains in vio_cmo.min and 818 + * vio_cmo.desired 819 + */ 820 + vio_cmo.desired -= (viodev->cmo.desired - VIO_CMO_MIN_ENT); 821 + 822 + /* 823 + * Save min allocation for device in reserve as long 824 + * as it exists in OF tree as determined by later 825 + * balance operation 826 + */ 827 + viodev->cmo.entitled -= VIO_CMO_MIN_ENT; 828 + 829 + /* Replenish spare from freed reserve pool */ 830 + if (viodev->cmo.entitled && (vio_cmo.spare < VIO_CMO_MIN_ENT)) { 831 + tmp = min(viodev->cmo.entitled, (VIO_CMO_MIN_ENT - 832 + vio_cmo.spare)); 833 + vio_cmo.spare += tmp; 834 + viodev->cmo.entitled -= tmp; 835 + } 836 + 837 + /* Remaining reserve goes to excess pool */ 838 + vio_cmo.excess.size += viodev->cmo.entitled; 839 + vio_cmo.excess.free += viodev->cmo.entitled; 840 + vio_cmo.reserve.size -= viodev->cmo.entitled; 841 + 842 + /* 843 + * Until the device is removed it will keep a 844 + * minimum entitlement; this will guarantee that 845 + * a module unload/load will result in a success. 846 + */ 847 + viodev->cmo.entitled = VIO_CMO_MIN_ENT; 848 + viodev->cmo.desired = VIO_CMO_MIN_ENT; 849 + atomic_set(&viodev->cmo.allocs_failed, 0); 850 + } 851 + 852 + spin_unlock_irqrestore(&vio_cmo.lock, flags); 853 + } 854 + 855 + static void vio_cmo_set_dma_ops(struct vio_dev *viodev) 856 + { 857 + vio_dma_mapping_ops.dma_supported = dma_iommu_ops.dma_supported; 858 + viodev->dev.archdata.dma_ops = &vio_dma_mapping_ops; 859 + } 860 + 861 + /** 862 + * vio_cmo_bus_init - CMO entitlement initialization at bus init time 863 + * 864 + * Set up the reserve and excess entitlement pools based on available 865 + * system entitlement and the number of devices in the OF tree that 866 + * require entitlement in the reserve pool. 867 + */ 868 + static void vio_cmo_bus_init(void) 869 + { 870 + struct hvcall_mpp_data mpp_data; 871 + int err; 872 + 873 + memset(&vio_cmo, 0, sizeof(struct vio_cmo)); 874 + spin_lock_init(&vio_cmo.lock); 875 + INIT_LIST_HEAD(&vio_cmo.device_list); 876 + INIT_DELAYED_WORK(&vio_cmo.balance_q, vio_cmo_balance); 877 + 878 + /* Get current system entitlement */ 879 + err = h_get_mpp(&mpp_data); 880 + 881 + /* 882 + * On failure, continue with entitlement set to 0, will panic() 883 + * later when spare is reserved. 884 + */ 885 + if (err != H_SUCCESS) { 886 + printk(KERN_ERR "%s: unable to determine system IO "\ 887 + "entitlement. (%d)\n", __func__, err); 888 + vio_cmo.entitled = 0; 889 + } else { 890 + vio_cmo.entitled = mpp_data.entitled_mem; 891 + } 892 + 893 + /* Set reservation and check against entitlement */ 894 + vio_cmo.spare = VIO_CMO_MIN_ENT; 895 + vio_cmo.reserve.size = vio_cmo.spare; 896 + vio_cmo.reserve.size += (vio_cmo_num_OF_devs() * 897 + VIO_CMO_MIN_ENT); 898 + if (vio_cmo.reserve.size > vio_cmo.entitled) { 899 + printk(KERN_ERR "%s: insufficient system entitlement\n", 900 + __func__); 901 + panic("%s: Insufficient system entitlement", __func__); 902 + } 903 + 904 + /* Set the remaining accounting variables */ 905 + vio_cmo.excess.size = vio_cmo.entitled - vio_cmo.reserve.size; 906 + vio_cmo.excess.free = vio_cmo.excess.size; 907 + vio_cmo.min = vio_cmo.reserve.size; 908 + vio_cmo.desired = vio_cmo.reserve.size; 909 + } 910 + 911 + /* sysfs device functions and data structures for CMO */ 912 + 913 + #define viodev_cmo_rd_attr(name) \ 914 + static ssize_t viodev_cmo_##name##_show(struct device *dev, \ 915 + struct device_attribute *attr, \ 916 + char *buf) \ 917 + { \ 918 + return sprintf(buf, "%lu\n", to_vio_dev(dev)->cmo.name); \ 919 + } 920 + 921 + static ssize_t viodev_cmo_allocs_failed_show(struct device *dev, 922 + struct device_attribute *attr, char *buf) 923 + { 924 + struct vio_dev *viodev = to_vio_dev(dev); 925 + return sprintf(buf, "%d\n", atomic_read(&viodev->cmo.allocs_failed)); 926 + } 927 + 928 + static ssize_t viodev_cmo_allocs_failed_reset(struct device *dev, 929 + struct device_attribute *attr, const char *buf, size_t count) 930 + { 931 + struct vio_dev *viodev = to_vio_dev(dev); 932 + atomic_set(&viodev->cmo.allocs_failed, 0); 933 + return count; 934 + } 935 + 936 + static ssize_t viodev_cmo_desired_set(struct device *dev, 937 + struct device_attribute *attr, const char *buf, size_t count) 938 + { 939 + struct vio_dev *viodev = to_vio_dev(dev); 940 + size_t new_desired; 941 + int ret; 942 + 943 + ret = strict_strtoul(buf, 10, &new_desired); 944 + if (ret) 945 + return ret; 946 + 947 + vio_cmo_set_dev_desired(viodev, new_desired); 948 + return count; 949 + } 950 + 951 + viodev_cmo_rd_attr(desired); 952 + viodev_cmo_rd_attr(entitled); 953 + viodev_cmo_rd_attr(allocated); 954 + 955 + static ssize_t name_show(struct device *, struct device_attribute *, char *); 956 + static ssize_t devspec_show(struct device *, struct device_attribute *, char *); 957 + static struct device_attribute vio_cmo_dev_attrs[] = { 958 + __ATTR_RO(name), 959 + __ATTR_RO(devspec), 960 + __ATTR(cmo_desired, S_IWUSR|S_IRUSR|S_IWGRP|S_IRGRP|S_IROTH, 961 + viodev_cmo_desired_show, viodev_cmo_desired_set), 962 + __ATTR(cmo_entitled, S_IRUGO, viodev_cmo_entitled_show, NULL), 963 + __ATTR(cmo_allocated, S_IRUGO, viodev_cmo_allocated_show, NULL), 964 + __ATTR(cmo_allocs_failed, S_IWUSR|S_IRUSR|S_IWGRP|S_IRGRP|S_IROTH, 965 + viodev_cmo_allocs_failed_show, viodev_cmo_allocs_failed_reset), 966 + __ATTR_NULL 967 + }; 968 + 969 + /* sysfs bus functions and data structures for CMO */ 970 + 971 + #define viobus_cmo_rd_attr(name) \ 972 + static ssize_t \ 973 + viobus_cmo_##name##_show(struct bus_type *bt, char *buf) \ 974 + { \ 975 + return sprintf(buf, "%lu\n", vio_cmo.name); \ 976 + } 977 + 978 + #define viobus_cmo_pool_rd_attr(name, var) \ 979 + static ssize_t \ 980 + viobus_cmo_##name##_pool_show_##var(struct bus_type *bt, char *buf) \ 981 + { \ 982 + return sprintf(buf, "%lu\n", vio_cmo.name.var); \ 983 + } 984 + 985 + static ssize_t viobus_cmo_high_reset(struct bus_type *bt, const char *buf, 986 + size_t count) 987 + { 988 + unsigned long flags; 989 + 990 + spin_lock_irqsave(&vio_cmo.lock, flags); 991 + vio_cmo.high = vio_cmo.curr; 992 + spin_unlock_irqrestore(&vio_cmo.lock, flags); 993 + 994 + return count; 995 + } 996 + 997 + viobus_cmo_rd_attr(entitled); 998 + viobus_cmo_pool_rd_attr(reserve, size); 999 + viobus_cmo_pool_rd_attr(excess, size); 1000 + viobus_cmo_pool_rd_attr(excess, free); 1001 + viobus_cmo_rd_attr(spare); 1002 + viobus_cmo_rd_attr(min); 1003 + viobus_cmo_rd_attr(desired); 1004 + viobus_cmo_rd_attr(curr); 1005 + viobus_cmo_rd_attr(high); 1006 + 1007 + static struct bus_attribute vio_cmo_bus_attrs[] = { 1008 + __ATTR(cmo_entitled, S_IRUGO, viobus_cmo_entitled_show, NULL), 1009 + __ATTR(cmo_reserve_size, S_IRUGO, viobus_cmo_reserve_pool_show_size, NULL), 1010 + __ATTR(cmo_excess_size, S_IRUGO, viobus_cmo_excess_pool_show_size, NULL), 1011 + __ATTR(cmo_excess_free, S_IRUGO, viobus_cmo_excess_pool_show_free, NULL), 1012 + __ATTR(cmo_spare, S_IRUGO, viobus_cmo_spare_show, NULL), 1013 + __ATTR(cmo_min, S_IRUGO, viobus_cmo_min_show, NULL), 1014 + __ATTR(cmo_desired, S_IRUGO, viobus_cmo_desired_show, NULL), 1015 + __ATTR(cmo_curr, S_IRUGO, viobus_cmo_curr_show, NULL), 1016 + __ATTR(cmo_high, S_IWUSR|S_IRUSR|S_IWGRP|S_IRGRP|S_IROTH, 1017 + viobus_cmo_high_show, viobus_cmo_high_reset), 1018 + __ATTR_NULL 1019 + }; 1020 + 1021 + static void vio_cmo_sysfs_init(void) 1022 + { 1023 + vio_bus_type.dev_attrs = vio_cmo_dev_attrs; 1024 + vio_bus_type.bus_attrs = vio_cmo_bus_attrs; 1025 + } 1026 + #else /* CONFIG_PPC_SMLPAR */ 1027 + /* Dummy functions for iSeries platform */ 1028 + int vio_cmo_entitlement_update(size_t new_entitlement) { return 0; } 1029 + void vio_cmo_set_dev_desired(struct vio_dev *viodev, size_t desired) {} 1030 + static int vio_cmo_bus_probe(struct vio_dev *viodev) { return 0; } 1031 + static void vio_cmo_bus_remove(struct vio_dev *viodev) {} 1032 + static void vio_cmo_set_dma_ops(struct vio_dev *viodev) {} 1033 + static void vio_cmo_bus_init() {} 1034 + static void vio_cmo_sysfs_init() { } 1035 + #endif /* CONFIG_PPC_SMLPAR */ 1036 + EXPORT_SYMBOL(vio_cmo_entitlement_update); 1037 + EXPORT_SYMBOL(vio_cmo_set_dev_desired); 49 1038 50 1039 static struct iommu_table *vio_build_iommu_table(struct vio_dev *dev) 51 1040 { ··· 1105 114 return error; 1106 115 1107 116 id = vio_match_device(viodrv->id_table, viodev); 1108 - if (id) 117 + if (id) { 118 + memset(&viodev->cmo, 0, sizeof(viodev->cmo)); 119 + if (firmware_has_feature(FW_FEATURE_CMO)) { 120 + error = vio_cmo_bus_probe(viodev); 121 + if (error) 122 + return error; 123 + } 1109 124 error = viodrv->probe(viodev, id); 125 + if (error) 126 + vio_cmo_bus_remove(viodev); 127 + } 1110 128 1111 129 return error; 1112 130 } ··· 1125 125 { 1126 126 struct vio_dev *viodev = to_vio_dev(dev); 1127 127 struct vio_driver *viodrv = to_vio_driver(dev->driver); 128 + struct device *devptr; 129 + int ret = 1; 130 + 131 + /* 132 + * Hold a reference to the device after the remove function is called 133 + * to allow for CMO accounting cleanup for the device. 134 + */ 135 + devptr = get_device(dev); 1128 136 1129 137 if (viodrv->remove) 1130 - return viodrv->remove(viodev); 138 + ret = viodrv->remove(viodev); 1131 139 1132 - /* driver can't remove */ 1133 - return 1; 140 + if (!ret && firmware_has_feature(FW_FEATURE_CMO)) 141 + vio_cmo_bus_remove(viodev); 142 + 143 + put_device(devptr); 144 + return ret; 1134 145 } 1135 146 1136 147 /** ··· 1226 215 viodev->unit_address = *unit_address; 1227 216 } 1228 217 viodev->dev.archdata.of_node = of_node_get(of_node); 1229 - viodev->dev.archdata.dma_ops = &dma_iommu_ops; 218 + 219 + if (firmware_has_feature(FW_FEATURE_CMO)) 220 + vio_cmo_set_dma_ops(viodev); 221 + else 222 + viodev->dev.archdata.dma_ops = &dma_iommu_ops; 1230 223 viodev->dev.archdata.dma_data = vio_build_iommu_table(viodev); 1231 224 viodev->dev.archdata.numa_node = of_node_to_nid(of_node); 1232 225 ··· 1260 245 int err; 1261 246 struct device_node *node_vroot; 1262 247 248 + if (firmware_has_feature(FW_FEATURE_CMO)) 249 + vio_cmo_sysfs_init(); 250 + 1263 251 err = bus_register(&vio_bus_type); 1264 252 if (err) { 1265 253 printk(KERN_ERR "failed to register VIO bus\n"); ··· 1279 261 __func__, err); 1280 262 return err; 1281 263 } 264 + 265 + if (firmware_has_feature(FW_FEATURE_CMO)) 266 + vio_cmo_bus_init(); 1282 267 1283 268 node_vroot = of_find_node_by_name(NULL, "vdevice"); 1284 269 if (node_vroot) {
+25 -2
include/asm-powerpc/vio.h
··· 39 39 #define VIO_IRQ_DISABLE 0UL 40 40 #define VIO_IRQ_ENABLE 1UL 41 41 42 + /* 43 + * VIO CMO minimum entitlement for all devices and spare entitlement 44 + */ 45 + #define VIO_CMO_MIN_ENT 1562624 46 + 42 47 struct iommu_table; 43 48 44 - /* 45 - * The vio_dev structure is used to describe virtual I/O devices. 49 + /** 50 + * vio_dev - This structure is used to describe virtual I/O devices. 51 + * 52 + * @desired: set from return of driver's get_desired_dma() function 53 + * @entitled: bytes of IO data that has been reserved for this device. 54 + * @allocated: bytes of IO data currently in use by the device. 55 + * @allocs_failed: number of DMA failures due to insufficient entitlement. 46 56 */ 47 57 struct vio_dev { 48 58 const char *name; 49 59 const char *type; 50 60 uint32_t unit_address; 51 61 unsigned int irq; 62 + struct { 63 + size_t desired; 64 + size_t entitled; 65 + size_t allocated; 66 + atomic_t allocs_failed; 67 + } cmo; 52 68 struct device dev; 53 69 }; 54 70 ··· 72 56 const struct vio_device_id *id_table; 73 57 int (*probe)(struct vio_dev *dev, const struct vio_device_id *id); 74 58 int (*remove)(struct vio_dev *dev); 59 + /* A driver must have a get_desired_dma() function to 60 + * be loaded in a CMO environment if it uses DMA. 61 + */ 62 + unsigned long (*get_desired_dma)(struct vio_dev *dev); 75 63 struct device_driver driver; 76 64 }; 77 65 78 66 extern int vio_register_driver(struct vio_driver *drv); 79 67 extern void vio_unregister_driver(struct vio_driver *drv); 68 + 69 + extern int vio_cmo_entitlement_update(size_t); 70 + extern void vio_cmo_set_dev_desired(struct vio_dev *viodev, size_t desired); 80 71 81 72 extern void __devinit vio_unregister_device(struct vio_dev *dev); 82 73