Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset f3baab1 in mainline


Ignore:
Timestamp:
2018-01-11T21:41:36Z (4 years ago)
Author:
Ondřej Hlavatý <aearsis@…>
Branches:
lfn, master
Children:
49e62998
Parents:
665368c
git-author:
Ondřej Hlavatý <aearsis@…> (2018-01-11 21:41:34)
git-committer:
Ondřej Hlavatý <aearsis@…> (2018-01-11 21:41:36)
Message:

xhci: do not rely on internal fibril quirks

Previousy, we abused the fact new fibrils are spawned for handling
notifications, so we could afford blocking the event handler. We were
told this is a subject to change and we should stop doing it.

This commit removes the abuse, but newly requires event handlers not to
block waiting for another event (e.g. commands do wait for events). To
quickly detect this situation, deadlock detection was added.

This commit breaks current functionality. Our current job is to identify
processes which do block and have them moved to separate fibril / spawn
fibril for the process alone.

Location:
uspace/drv/bus/usb/xhci
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/bus/usb/xhci/commands.c

    r665368c rf3baab1  
    666666        int rv = EOK;
    667667
     668        if (fibril_get_id() == hc->event_handler) {
     669                usb_log_error("Deadlock detected in waiting for command.");
     670                abort();
     671        }
     672
    668673        fibril_mutex_lock(&cmd->_header.completed_mtx);
    669674        while (!cmd->_header.completed) {
  • uspace/drv/bus/usb/xhci/hc.c

    r665368c rf3baab1  
    511511{
    512512        int err;
    513         ssize_t size = 16;
    514         xhci_trb_t *queue = malloc(sizeof(xhci_trb_t) * size);
    515         if (!queue) {
    516                 usb_log_error("Not enough memory to run the event ring.");
    517                 return;
    518         }
    519 
    520         xhci_trb_t *head = queue;
    521 
    522         while ((err = xhci_event_ring_dequeue(event_ring, head)) != ENOENT) {
    523                 if (err != EOK) {
    524                         usb_log_warning("Error while accessing event ring: %s", str_error(err));
    525                         break;
    526                 }
    527 
    528                 usb_log_debug2("Dequeued trb from event ring: %s", xhci_trb_str_type(TRB_TYPE(*head)));
    529                 head++;
    530 
    531                 /* Expand the array if needed. */
    532                 if (head - queue >= size) {
    533                         size *= 2;
    534                         xhci_trb_t *new_queue = realloc(queue, size);
    535                         if (new_queue == NULL)
    536                                 break; /* Will process only those TRBs we have memory for. */
    537 
    538                         head = new_queue + (head - queue);
     513
     514        xhci_trb_t trb;
     515        hc->event_handler = fibril_get_id();
     516
     517        while ((err = xhci_event_ring_dequeue(event_ring, &trb)) != ENOENT) {
     518                if ((err = hc_handle_event(hc, &trb, intr)) != EOK) {
     519                        usb_log_error("Failed to handle event: %s", str_error(err));
    539520                }
    540521
     
    543524                XHCI_REG_WR(intr, XHCI_INTR_ERDP_HI, UPPER32(erdp));
    544525        }
     526
     527        hc->event_handler = 0;
    545528
    546529        /* Update the ERDP to make room in the ring. */
     
    551534        XHCI_REG_WR(intr, XHCI_INTR_ERDP_HI, UPPER32(erdp));
    552535
    553         /* Handle all of the collected events if possible. */
    554         if (head == queue)
    555                 usb_log_warning("No events to be handled!");
    556 
    557         for (xhci_trb_t *tail = queue; tail != head; tail++) {
    558                 if ((err = hc_handle_event(hc, tail, intr)) != EOK) {
    559                         usb_log_error("Failed to handle event: %s", str_error(err));
    560                 }
    561         }
    562 
    563         free(queue);
    564536        usb_log_debug2("Event ring run finished.");
    565537}
  • uspace/drv/bus/usb/xhci/hc.h

    r665368c rf3baab1  
    8181        xhci_bus_t bus;
    8282
     83        /* Fibril that is currently hanling events */
     84        fid_t event_handler;
     85
    8386        /* Cached capabilities */
    8487        unsigned max_slots;
Note: See TracChangeset for help on using the changeset viewer.