1 /* 2 * core routines for the asynchronous memory transfer/transform api 3 * 4 * Copyright © 2006, Intel Corporation. 5 * 6 * Dan Williams <[email protected]> 7 * 8 * with architecture considerations by: 9 * Neil Brown <[email protected]> 10 * Jeff Garzik <[email protected]> 11 * 12 * This program is free software; you can redistribute it and/or modify it 13 * under the terms and conditions of the GNU General Public License, 14 * version 2, as published by the Free Software Foundation. 15 * 16 * This program is distributed in the hope it will be useful, but WITHOUT 17 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 18 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 19 * more details. 20 * 21 * You should have received a copy of the GNU General Public License along with 22 * this program; if not, write to the Free Software Foundation, Inc., 23 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. 24 * 25 */ 26 #include <linux/rculist.h> 27 #include <linux/kernel.h> 28 #include <linux/async_tx.h> 29 30 #ifdef CONFIG_DMA_ENGINE 31 static enum dma_state_client 32 dma_channel_add_remove(struct dma_client *client, 33 struct dma_chan *chan, enum dma_state state); 34 35 static struct dma_client async_tx_dma = { 36 .event_callback = dma_channel_add_remove, 37 /* .cap_mask == 0 defaults to all channels */ 38 }; 39 40 /** 41 * dma_cap_mask_all - enable iteration over all operation types 42 */ 43 static dma_cap_mask_t dma_cap_mask_all; 44 45 /** 46 * chan_ref_percpu - tracks channel allocations per core/opertion 47 */ 48 struct chan_ref_percpu { 49 struct dma_chan_ref *ref; 50 }; 51 52 static int channel_table_initialized; 53 static struct chan_ref_percpu *channel_table[DMA_TX_TYPE_END]; 54 55 /** 56 * async_tx_lock - protect modification of async_tx_master_list and serialize 57 * rebalance operations 58 */ 59 static spinlock_t async_tx_lock; 60 61 static LIST_HEAD(async_tx_master_list); 62 63 /* async_tx_issue_pending_all - start all transactions on all channels */ 64 void async_tx_issue_pending_all(void) 65 { 66 struct dma_chan_ref *ref; 67 68 rcu_read_lock(); 69 list_for_each_entry_rcu(ref, &async_tx_master_list, node) 70 ref->chan->device->device_issue_pending(ref->chan); 71 rcu_read_unlock(); 72 } 73 EXPORT_SYMBOL_GPL(async_tx_issue_pending_all); 74 75 static void 76 free_dma_chan_ref(struct rcu_head *rcu) 77 { 78 struct dma_chan_ref *ref; 79 ref = container_of(rcu, struct dma_chan_ref, rcu); 80 kfree(ref); 81 } 82 83 static void 84 init_dma_chan_ref(struct dma_chan_ref *ref, struct dma_chan *chan) 85 { 86 INIT_LIST_HEAD(&ref->node); 87 INIT_RCU_HEAD(&ref->rcu); 88 ref->chan = chan; 89 atomic_set(&ref->count, 0); 90 } 91 92 /** 93 * get_chan_ref_by_cap - returns the nth channel of the given capability 94 * defaults to returning the channel with the desired capability and the 95 * lowest reference count if the index can not be satisfied 96 * @cap: capability to match 97 * @index: nth channel desired, passing -1 has the effect of forcing the 98 * default return value 99 */ 100 static struct dma_chan_ref * 101 get_chan_ref_by_cap(enum dma_transaction_type cap, int index) 102 { 103 struct dma_chan_ref *ret_ref = NULL, *min_ref = NULL, *ref; 104 105 rcu_read_lock(); 106 list_for_each_entry_rcu(ref, &async_tx_master_list, node) 107 if (dma_has_cap(cap, ref->chan->device->cap_mask)) { 108 if (!min_ref) 109 min_ref = ref; 110 else if (atomic_read(&ref->count) < 111 atomic_read(&min_ref->count)) 112 min_ref = ref; 113 114 if (index-- == 0) { 115 ret_ref = ref; 116 break; 117 } 118 } 119 rcu_read_unlock(); 120 121 if (!ret_ref) 122 ret_ref = min_ref; 123 124 if (ret_ref) 125 atomic_inc(&ret_ref->count); 126 127 return ret_ref; 128 } 129 130 /** 131 * async_tx_rebalance - redistribute the available channels, optimize 132 * for cpu isolation in the SMP case, and opertaion isolation in the 133 * uniprocessor case 134 */ 135 static void async_tx_rebalance(void) 136 { 137 int cpu, cap, cpu_idx = 0; 138 unsigned long flags; 139 140 if (!channel_table_initialized) 141 return; 142 143 spin_lock_irqsave(&async_tx_lock, flags); 144 145 /* undo the last distribution */ 146 for_each_dma_cap_mask(cap, dma_cap_mask_all) 147 for_each_possible_cpu(cpu) { 148 struct dma_chan_ref *ref = 149 per_cpu_ptr(channel_table[cap], cpu)->ref; 150 if (ref) { 151 atomic_set(&ref->count, 0); 152 per_cpu_ptr(channel_table[cap], cpu)->ref = 153 NULL; 154 } 155 } 156 157 for_each_dma_cap_mask(cap, dma_cap_mask_all) 158 for_each_online_cpu(cpu) { 159 struct dma_chan_ref *new; 160 if (NR_CPUS > 1) 161 new = get_chan_ref_by_cap(cap, cpu_idx++); 162 else 163 new = get_chan_ref_by_cap(cap, -1); 164 165 per_cpu_ptr(channel_table[cap], cpu)->ref = new; 166 } 167 168 spin_unlock_irqrestore(&async_tx_lock, flags); 169 } 170 171 static enum dma_state_client 172 dma_channel_add_remove(struct dma_client *client, 173 struct dma_chan *chan, enum dma_state state) 174 { 175 unsigned long found, flags; 176 struct dma_chan_ref *master_ref, *ref; 177 enum dma_state_client ack = DMA_DUP; /* default: take no action */ 178 179 switch (state) { 180 case DMA_RESOURCE_AVAILABLE: 181 found = 0; 182 rcu_read_lock(); 183 list_for_each_entry_rcu(ref, &async_tx_master_list, node) 184 if (ref->chan == chan) { 185 found = 1; 186 break; 187 } 188 rcu_read_unlock(); 189 190 pr_debug("async_tx: dma resource available [%s]\n", 191 found ? "old" : "new"); 192 193 if (!found) 194 ack = DMA_ACK; 195 else 196 break; 197 198 /* add the channel to the generic management list */ 199 master_ref = kmalloc(sizeof(*master_ref), GFP_KERNEL); 200 if (master_ref) { 201 init_dma_chan_ref(master_ref, chan); 202 spin_lock_irqsave(&async_tx_lock, flags); 203 list_add_tail_rcu(&master_ref->node, 204 &async_tx_master_list); 205 spin_unlock_irqrestore(&async_tx_lock, 206 flags); 207 } else { 208 printk(KERN_WARNING "async_tx: unable to create" 209 " new master entry in response to" 210 " a DMA_RESOURCE_ADDED event" 211 " (-ENOMEM)\n"); 212 return 0; 213 } 214 215 async_tx_rebalance(); 216 break; 217 case DMA_RESOURCE_REMOVED: 218 found = 0; 219 spin_lock_irqsave(&async_tx_lock, flags); 220 list_for_each_entry(ref, &async_tx_master_list, node) 221 if (ref->chan == chan) { 222 list_del_rcu(&ref->node); 223 call_rcu(&ref->rcu, free_dma_chan_ref); 224 found = 1; 225 break; 226 } 227 spin_unlock_irqrestore(&async_tx_lock, flags); 228 229 pr_debug("async_tx: dma resource removed [%s]\n", 230 found ? "ours" : "not ours"); 231 232 if (found) 233 ack = DMA_ACK; 234 else 235 break; 236 237 async_tx_rebalance(); 238 break; 239 case DMA_RESOURCE_SUSPEND: 240 case DMA_RESOURCE_RESUME: 241 printk(KERN_WARNING "async_tx: does not support dma channel" 242 " suspend/resume\n"); 243 break; 244 default: 245 BUG(); 246 } 247 248 return ack; 249 } 250 251 static int __init 252 async_tx_init(void) 253 { 254 enum dma_transaction_type cap; 255 256 spin_lock_init(&async_tx_lock); 257 bitmap_fill(dma_cap_mask_all.bits, DMA_TX_TYPE_END); 258 259 /* an interrupt will never be an explicit operation type. 260 * clearing this bit prevents allocation to a slot in 'channel_table' 261 */ 262 clear_bit(DMA_INTERRUPT, dma_cap_mask_all.bits); 263 264 for_each_dma_cap_mask(cap, dma_cap_mask_all) { 265 channel_table[cap] = alloc_percpu(struct chan_ref_percpu); 266 if (!channel_table[cap]) 267 goto err; 268 } 269 270 channel_table_initialized = 1; 271 dma_async_client_register(&async_tx_dma); 272 dma_async_client_chan_request(&async_tx_dma); 273 274 printk(KERN_INFO "async_tx: api initialized (async)\n"); 275 276 return 0; 277 err: 278 printk(KERN_ERR "async_tx: initialization failure\n"); 279 280 while (--cap >= 0) 281 free_percpu(channel_table[cap]); 282 283 return 1; 284 } 285 286 static void __exit async_tx_exit(void) 287 { 288 enum dma_transaction_type cap; 289 290 channel_table_initialized = 0; 291 292 for_each_dma_cap_mask(cap, dma_cap_mask_all) 293 if (channel_table[cap]) 294 free_percpu(channel_table[cap]); 295 296 dma_async_client_unregister(&async_tx_dma); 297 } 298 299 /** 300 * __async_tx_find_channel - find a channel to carry out the operation or let 301 * the transaction execute synchronously 302 * @depend_tx: transaction dependency 303 * @tx_type: transaction type 304 */ 305 struct dma_chan * 306 __async_tx_find_channel(struct dma_async_tx_descriptor *depend_tx, 307 enum dma_transaction_type tx_type) 308 { 309 /* see if we can keep the chain on one channel */ 310 if (depend_tx && 311 dma_has_cap(tx_type, depend_tx->chan->device->cap_mask)) 312 return depend_tx->chan; 313 else if (likely(channel_table_initialized)) { 314 struct dma_chan_ref *ref; 315 int cpu = get_cpu(); 316 ref = per_cpu_ptr(channel_table[tx_type], cpu)->ref; 317 put_cpu(); 318 return ref ? ref->chan : NULL; 319 } else 320 return NULL; 321 } 322 EXPORT_SYMBOL_GPL(__async_tx_find_channel); 323 #else 324 static int __init async_tx_init(void) 325 { 326 printk(KERN_INFO "async_tx: api initialized (sync-only)\n"); 327 return 0; 328 } 329 330 static void __exit async_tx_exit(void) 331 { 332 do { } while (0); 333 } 334 #endif 335 336 337 /** 338 * async_tx_channel_switch - queue an interrupt descriptor with a dependency 339 * pre-attached. 340 * @depend_tx: the operation that must finish before the new operation runs 341 * @tx: the new operation 342 */ 343 static void 344 async_tx_channel_switch(struct dma_async_tx_descriptor *depend_tx, 345 struct dma_async_tx_descriptor *tx) 346 { 347 struct dma_chan *chan; 348 struct dma_device *device; 349 struct dma_async_tx_descriptor *intr_tx = (void *) ~0; 350 351 /* first check to see if we can still append to depend_tx */ 352 spin_lock_bh(&depend_tx->lock); 353 if (depend_tx->parent && depend_tx->chan == tx->chan) { 354 tx->parent = depend_tx; 355 depend_tx->next = tx; 356 intr_tx = NULL; 357 } 358 spin_unlock_bh(&depend_tx->lock); 359 360 if (!intr_tx) 361 return; 362 363 chan = depend_tx->chan; 364 device = chan->device; 365 366 /* see if we can schedule an interrupt 367 * otherwise poll for completion 368 */ 369 if (dma_has_cap(DMA_INTERRUPT, device->cap_mask)) 370 intr_tx = device->device_prep_dma_interrupt(chan, 0); 371 else 372 intr_tx = NULL; 373 374 if (intr_tx) { 375 intr_tx->callback = NULL; 376 intr_tx->callback_param = NULL; 377 tx->parent = intr_tx; 378 /* safe to set ->next outside the lock since we know we are 379 * not submitted yet 380 */ 381 intr_tx->next = tx; 382 383 /* check if we need to append */ 384 spin_lock_bh(&depend_tx->lock); 385 if (depend_tx->parent) { 386 intr_tx->parent = depend_tx; 387 depend_tx->next = intr_tx; 388 async_tx_ack(intr_tx); 389 intr_tx = NULL; 390 } 391 spin_unlock_bh(&depend_tx->lock); 392 393 if (intr_tx) { 394 intr_tx->parent = NULL; 395 intr_tx->tx_submit(intr_tx); 396 async_tx_ack(intr_tx); 397 } 398 } else { 399 if (dma_wait_for_async_tx(depend_tx) == DMA_ERROR) 400 panic("%s: DMA_ERROR waiting for depend_tx\n", 401 __func__); 402 tx->tx_submit(tx); 403 } 404 } 405 406 407 /** 408 * submit_disposition - while holding depend_tx->lock we must avoid submitting 409 * new operations to prevent a circular locking dependency with 410 * drivers that already hold a channel lock when calling 411 * async_tx_run_dependencies. 412 * @ASYNC_TX_SUBMITTED: we were able to append the new operation under the lock 413 * @ASYNC_TX_CHANNEL_SWITCH: when the lock is dropped schedule a channel switch 414 * @ASYNC_TX_DIRECT_SUBMIT: when the lock is dropped submit directly 415 */ 416 enum submit_disposition { 417 ASYNC_TX_SUBMITTED, 418 ASYNC_TX_CHANNEL_SWITCH, 419 ASYNC_TX_DIRECT_SUBMIT, 420 }; 421 422 void 423 async_tx_submit(struct dma_chan *chan, struct dma_async_tx_descriptor *tx, 424 enum async_tx_flags flags, struct dma_async_tx_descriptor *depend_tx, 425 dma_async_tx_callback cb_fn, void *cb_param) 426 { 427 tx->callback = cb_fn; 428 tx->callback_param = cb_param; 429 430 if (depend_tx) { 431 enum submit_disposition s; 432 433 /* sanity check the dependency chain: 434 * 1/ if ack is already set then we cannot be sure 435 * we are referring to the correct operation 436 * 2/ dependencies are 1:1 i.e. two transactions can 437 * not depend on the same parent 438 */ 439 BUG_ON(async_tx_test_ack(depend_tx) || depend_tx->next || 440 tx->parent); 441 442 /* the lock prevents async_tx_run_dependencies from missing 443 * the setting of ->next when ->parent != NULL 444 */ 445 spin_lock_bh(&depend_tx->lock); 446 if (depend_tx->parent) { 447 /* we have a parent so we can not submit directly 448 * if we are staying on the same channel: append 449 * else: channel switch 450 */ 451 if (depend_tx->chan == chan) { 452 tx->parent = depend_tx; 453 depend_tx->next = tx; 454 s = ASYNC_TX_SUBMITTED; 455 } else 456 s = ASYNC_TX_CHANNEL_SWITCH; 457 } else { 458 /* we do not have a parent so we may be able to submit 459 * directly if we are staying on the same channel 460 */ 461 if (depend_tx->chan == chan) 462 s = ASYNC_TX_DIRECT_SUBMIT; 463 else 464 s = ASYNC_TX_CHANNEL_SWITCH; 465 } 466 spin_unlock_bh(&depend_tx->lock); 467 468 switch (s) { 469 case ASYNC_TX_SUBMITTED: 470 break; 471 case ASYNC_TX_CHANNEL_SWITCH: 472 async_tx_channel_switch(depend_tx, tx); 473 break; 474 case ASYNC_TX_DIRECT_SUBMIT: 475 tx->parent = NULL; 476 tx->tx_submit(tx); 477 break; 478 } 479 } else { 480 tx->parent = NULL; 481 tx->tx_submit(tx); 482 } 483 484 if (flags & ASYNC_TX_ACK) 485 async_tx_ack(tx); 486 487 if (depend_tx && (flags & ASYNC_TX_DEP_ACK)) 488 async_tx_ack(depend_tx); 489 } 490 EXPORT_SYMBOL_GPL(async_tx_submit); 491 492 /** 493 * async_trigger_callback - schedules the callback function to be run after 494 * any dependent operations have been completed. 495 * @flags: ASYNC_TX_ACK, ASYNC_TX_DEP_ACK 496 * @depend_tx: 'callback' requires the completion of this transaction 497 * @cb_fn: function to call after depend_tx completes 498 * @cb_param: parameter to pass to the callback routine 499 */ 500 struct dma_async_tx_descriptor * 501 async_trigger_callback(enum async_tx_flags flags, 502 struct dma_async_tx_descriptor *depend_tx, 503 dma_async_tx_callback cb_fn, void *cb_param) 504 { 505 struct dma_chan *chan; 506 struct dma_device *device; 507 struct dma_async_tx_descriptor *tx; 508 509 if (depend_tx) { 510 chan = depend_tx->chan; 511 device = chan->device; 512 513 /* see if we can schedule an interrupt 514 * otherwise poll for completion 515 */ 516 if (device && !dma_has_cap(DMA_INTERRUPT, device->cap_mask)) 517 device = NULL; 518 519 tx = device ? device->device_prep_dma_interrupt(chan, 0) : NULL; 520 } else 521 tx = NULL; 522 523 if (tx) { 524 pr_debug("%s: (async)\n", __func__); 525 526 async_tx_submit(chan, tx, flags, depend_tx, cb_fn, cb_param); 527 } else { 528 pr_debug("%s: (sync)\n", __func__); 529 530 /* wait for any prerequisite operations */ 531 async_tx_quiesce(&depend_tx); 532 533 async_tx_sync_epilog(cb_fn, cb_param); 534 } 535 536 return tx; 537 } 538 EXPORT_SYMBOL_GPL(async_trigger_callback); 539 540 /** 541 * async_tx_quiesce - ensure tx is complete and freeable upon return 542 * @tx - transaction to quiesce 543 */ 544 void async_tx_quiesce(struct dma_async_tx_descriptor **tx) 545 { 546 if (*tx) { 547 /* if ack is already set then we cannot be sure 548 * we are referring to the correct operation 549 */ 550 BUG_ON(async_tx_test_ack(*tx)); 551 if (dma_wait_for_async_tx(*tx) == DMA_ERROR) 552 panic("DMA_ERROR waiting for transaction\n"); 553 async_tx_ack(*tx); 554 *tx = NULL; 555 } 556 } 557 EXPORT_SYMBOL_GPL(async_tx_quiesce); 558 559 module_init(async_tx_init); 560 module_exit(async_tx_exit); 561 562 MODULE_AUTHOR("Intel Corporation"); 563 MODULE_DESCRIPTION("Asynchronous Bulk Memory Transactions API"); 564 MODULE_LICENSE("GPL"); 565