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

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'rpmsg-v7.0' of git://git.kernel.org/pub/scm/linux/kernel/git/remoteproc/linux

Pull rpmsg updates from Bjorn Andersson:

- Fix a race in rpmsg driver_override_show() and use the existing
helper to implement the store()

- Implement support for EPOLLOUT in the virtio rpmsg driver

* tag 'rpmsg-v7.0' of git://git.kernel.org/pub/scm/linux/kernel/git/remoteproc/linux:
rpmsg: core: fix race in driver_override_show() and use core helper
rpmsg: virtio: EPOLLOUT support

+59 -108
+27 -39
drivers/rpmsg/rpmsg_core.c
··· 352 352 } \ 353 353 static DEVICE_ATTR_RO(field); 354 354 355 - #define rpmsg_string_attr(field, member) \ 356 - static ssize_t \ 357 - field##_store(struct device *dev, struct device_attribute *attr, \ 358 - const char *buf, size_t sz) \ 359 - { \ 360 - struct rpmsg_device *rpdev = to_rpmsg_device(dev); \ 361 - const char *old; \ 362 - char *new; \ 363 - \ 364 - new = kstrndup(buf, sz, GFP_KERNEL); \ 365 - if (!new) \ 366 - return -ENOMEM; \ 367 - new[strcspn(new, "\n")] = '\0'; \ 368 - \ 369 - device_lock(dev); \ 370 - old = rpdev->member; \ 371 - if (strlen(new)) { \ 372 - rpdev->member = new; \ 373 - } else { \ 374 - kfree(new); \ 375 - rpdev->member = NULL; \ 376 - } \ 377 - device_unlock(dev); \ 378 - \ 379 - kfree(old); \ 380 - \ 381 - return sz; \ 382 - } \ 383 - static ssize_t \ 384 - field##_show(struct device *dev, \ 385 - struct device_attribute *attr, char *buf) \ 386 - { \ 387 - struct rpmsg_device *rpdev = to_rpmsg_device(dev); \ 388 - \ 389 - return sprintf(buf, "%s\n", rpdev->member); \ 390 - } \ 391 - static DEVICE_ATTR_RW(field) 392 - 393 355 /* for more info, see Documentation/ABI/testing/sysfs-bus-rpmsg */ 394 356 rpmsg_show_attr(name, id.name, "%s\n"); 395 357 rpmsg_show_attr(src, src, "0x%x\n"); 396 358 rpmsg_show_attr(dst, dst, "0x%x\n"); 397 359 rpmsg_show_attr(announce, announce ? "true" : "false", "%s\n"); 398 - rpmsg_string_attr(driver_override, driver_override); 360 + 361 + static ssize_t driver_override_store(struct device *dev, 362 + struct device_attribute *attr, 363 + const char *buf, size_t count) 364 + { 365 + struct rpmsg_device *rpdev = to_rpmsg_device(dev); 366 + int ret; 367 + 368 + ret = driver_set_override(dev, &rpdev->driver_override, buf, count); 369 + if (ret) 370 + return ret; 371 + 372 + return count; 373 + } 374 + 375 + static ssize_t driver_override_show(struct device *dev, 376 + struct device_attribute *attr, char *buf) 377 + { 378 + struct rpmsg_device *rpdev = to_rpmsg_device(dev); 379 + ssize_t len; 380 + 381 + device_lock(dev); 382 + len = sysfs_emit(buf, "%s\n", rpdev->driver_override); 383 + device_unlock(dev); 384 + return len; 385 + } 386 + static DEVICE_ATTR_RW(driver_override); 399 387 400 388 static ssize_t modalias_show(struct device *dev, 401 389 struct device_attribute *attr, char *buf)
+32 -69
drivers/rpmsg/virtio_rpmsg_bus.c
··· 41 41 * @buf_size: size of one rx or tx buffer 42 42 * @last_sbuf: index of last tx buffer used 43 43 * @bufs_dma: dma base addr of the buffers 44 - * @tx_lock: protects svq, sbufs and sleepers, to allow concurrent senders. 44 + * @tx_lock: protects svq and sbufs, to allow concurrent senders. 45 45 * sending a message might require waking up a dozing remote 46 46 * processor, which involves sleeping, hence the mutex. 47 47 * @endpoints: idr of local endpoints, allows fast retrieval 48 48 * @endpoints_lock: lock of the endpoints set 49 49 * @sendq: wait queue of sending contexts waiting for a tx buffers 50 - * @sleepers: number of senders that are waiting for a tx buffer 51 50 * 52 51 * This structure stores the rpmsg state of a given virtio remote processor 53 52 * device (there might be several virtio proc devices for each physical ··· 64 65 struct idr endpoints; 65 66 struct mutex endpoints_lock; 66 67 wait_queue_head_t sendq; 67 - atomic_t sleepers; 68 68 }; 69 69 70 70 /* The feature bitmap for virtio rpmsg */ ··· 142 144 static int virtio_rpmsg_trysend(struct rpmsg_endpoint *ept, void *data, int len); 143 145 static int virtio_rpmsg_trysendto(struct rpmsg_endpoint *ept, void *data, 144 146 int len, u32 dst); 147 + static __poll_t virtio_rpmsg_poll(struct rpmsg_endpoint *ept, struct file *filp, 148 + poll_table *wait); 145 149 static ssize_t virtio_rpmsg_get_mtu(struct rpmsg_endpoint *ept); 146 150 static struct rpmsg_device *__rpmsg_create_channel(struct virtproc_info *vrp, 147 151 struct rpmsg_channel_info *chinfo); ··· 154 154 .sendto = virtio_rpmsg_sendto, 155 155 .trysend = virtio_rpmsg_trysend, 156 156 .trysendto = virtio_rpmsg_trysendto, 157 + .poll = virtio_rpmsg_poll, 157 158 .get_mtu = virtio_rpmsg_get_mtu, 158 159 }; 159 160 ··· 437 436 unsigned int len; 438 437 void *ret; 439 438 440 - /* support multiple concurrent senders */ 441 439 mutex_lock(&vrp->tx_lock); 442 440 443 441 /* ··· 452 452 mutex_unlock(&vrp->tx_lock); 453 453 454 454 return ret; 455 - } 456 - 457 - /** 458 - * rpmsg_upref_sleepers() - enable "tx-complete" interrupts, if needed 459 - * @vrp: virtual remote processor state 460 - * 461 - * This function is called before a sender is blocked, waiting for 462 - * a tx buffer to become available. 463 - * 464 - * If we already have blocking senders, this function merely increases 465 - * the "sleepers" reference count, and exits. 466 - * 467 - * Otherwise, if this is the first sender to block, we also enable 468 - * virtio's tx callbacks, so we'd be immediately notified when a tx 469 - * buffer is consumed (we rely on virtio's tx callback in order 470 - * to wake up sleeping senders as soon as a tx buffer is used by the 471 - * remote processor). 472 - */ 473 - static void rpmsg_upref_sleepers(struct virtproc_info *vrp) 474 - { 475 - /* support multiple concurrent senders */ 476 - mutex_lock(&vrp->tx_lock); 477 - 478 - /* are we the first sleeping context waiting for tx buffers ? */ 479 - if (atomic_inc_return(&vrp->sleepers) == 1) 480 - /* enable "tx-complete" interrupts before dozing off */ 481 - virtqueue_enable_cb(vrp->svq); 482 - 483 - mutex_unlock(&vrp->tx_lock); 484 - } 485 - 486 - /** 487 - * rpmsg_downref_sleepers() - disable "tx-complete" interrupts, if needed 488 - * @vrp: virtual remote processor state 489 - * 490 - * This function is called after a sender, that waited for a tx buffer 491 - * to become available, is unblocked. 492 - * 493 - * If we still have blocking senders, this function merely decreases 494 - * the "sleepers" reference count, and exits. 495 - * 496 - * Otherwise, if there are no more blocking senders, we also disable 497 - * virtio's tx callbacks, to avoid the overhead incurred with handling 498 - * those (now redundant) interrupts. 499 - */ 500 - static void rpmsg_downref_sleepers(struct virtproc_info *vrp) 501 - { 502 - /* support multiple concurrent senders */ 503 - mutex_lock(&vrp->tx_lock); 504 - 505 - /* are we the last sleeping context waiting for tx buffers ? */ 506 - if (atomic_dec_and_test(&vrp->sleepers)) 507 - /* disable "tx-complete" interrupts */ 508 - virtqueue_disable_cb(vrp->svq); 509 - 510 - mutex_unlock(&vrp->tx_lock); 511 455 } 512 456 513 457 /** ··· 526 582 527 583 /* no free buffer ? wait for one (but bail after 15 seconds) */ 528 584 while (!msg) { 529 - /* enable "tx-complete" interrupts, if not already enabled */ 530 - rpmsg_upref_sleepers(vrp); 531 - 532 585 /* 533 586 * sleep until a free buffer is available or 15 secs elapse. 534 587 * the timeout period is not configurable because there's ··· 535 594 err = wait_event_interruptible_timeout(vrp->sendq, 536 595 (msg = get_a_tx_buf(vrp)), 537 596 msecs_to_jiffies(15000)); 538 - 539 - /* disable "tx-complete" interrupts if we're the last sleeper */ 540 - rpmsg_downref_sleepers(vrp); 541 597 542 598 /* timeout ? */ 543 599 if (!err) { ··· 612 674 u32 src = ept->addr; 613 675 614 676 return rpmsg_send_offchannel_raw(rpdev, src, dst, data, len, false); 677 + } 678 + 679 + static __poll_t virtio_rpmsg_poll(struct rpmsg_endpoint *ept, struct file *filp, 680 + poll_table *wait) 681 + { 682 + struct rpmsg_device *rpdev = ept->rpdev; 683 + struct virtio_rpmsg_channel *vch = to_virtio_rpmsg_channel(rpdev); 684 + struct virtproc_info *vrp = vch->vrp; 685 + __poll_t mask = 0; 686 + 687 + poll_wait(filp, &vrp->sendq, wait); 688 + 689 + /* support multiple concurrent senders */ 690 + mutex_lock(&vrp->tx_lock); 691 + 692 + /* 693 + * check for a free buffer, either: 694 + * - we haven't used all of the available transmit buffers (half of the 695 + * allocated buffers are used for transmit, hence num_bufs / 2), or, 696 + * - we ask the virtqueue if there's a buffer available 697 + */ 698 + if (vrp->last_sbuf < vrp->num_bufs / 2 || 699 + !virtqueue_enable_cb(vrp->svq)) 700 + mask |= EPOLLOUT; 701 + 702 + mutex_unlock(&vrp->tx_lock); 703 + 704 + return mask; 615 705 } 616 706 617 707 static ssize_t virtio_rpmsg_get_mtu(struct rpmsg_endpoint *ept) ··· 887 921 GFP_KERNEL); 888 922 WARN_ON(err); /* sanity check; this can't really happen */ 889 923 } 890 - 891 - /* suppress "tx-complete" interrupts */ 892 - virtqueue_disable_cb(vrp->svq); 893 924 894 925 vdev->priv = vrp; 895 926