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

ibmvnic: Handle processing of CRQ messages in a tasklet

Create a tasklet to process queued commands or messages received from
firmware instead of processing them in the interrupt handler. Note that
this handler does not process network traffic, but communications related
to resource allocation and device settings.

Signed-off-by: Thomas Falcon <tlfalcon@linux.vnet.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Thomas Falcon and committed by
David S. Miller
6c267b3d 1e128c81

+18 -1
+17 -1
drivers/net/ethernet/ibm/ibmvnic.c
··· 3420 3420 static irqreturn_t ibmvnic_interrupt(int irq, void *instance) 3421 3421 { 3422 3422 struct ibmvnic_adapter *adapter = instance; 3423 + unsigned long flags; 3424 + 3425 + spin_lock_irqsave(&adapter->crq.lock, flags); 3426 + vio_disable_interrupts(adapter->vdev); 3427 + tasklet_schedule(&adapter->tasklet); 3428 + spin_unlock_irqrestore(&adapter->crq.lock, flags); 3429 + return IRQ_HANDLED; 3430 + } 3431 + 3432 + static void ibmvnic_tasklet(void *data) 3433 + { 3434 + struct ibmvnic_adapter *adapter = data; 3423 3435 struct ibmvnic_crq_queue *queue = &adapter->crq; 3424 3436 struct vio_dev *vdev = adapter->vdev; 3425 3437 union ibmvnic_crq *crq; ··· 3457 3445 } 3458 3446 } 3459 3447 spin_unlock_irqrestore(&queue->lock, flags); 3460 - return IRQ_HANDLED; 3461 3448 } 3462 3449 3463 3450 static int ibmvnic_reenable_crq_queue(struct ibmvnic_adapter *adapter) ··· 3511 3500 3512 3501 netdev_dbg(adapter->netdev, "Releasing CRQ\n"); 3513 3502 free_irq(vdev->irq, adapter); 3503 + tasklet_kill(&adapter->tasklet); 3514 3504 do { 3515 3505 rc = plpar_hcall_norets(H_FREE_CRQ, vdev->unit_address); 3516 3506 } while (rc == H_BUSY || H_IS_LONG_BUSY(rc)); ··· 3557 3545 3558 3546 retrc = 0; 3559 3547 3548 + tasklet_init(&adapter->tasklet, (void *)ibmvnic_tasklet, 3549 + (unsigned long)adapter); 3550 + 3560 3551 netdev_dbg(adapter->netdev, "registering irq 0x%x\n", vdev->irq); 3561 3552 rc = request_irq(vdev->irq, ibmvnic_interrupt, 0, IBMVNIC_NAME, 3562 3553 adapter); ··· 3581 3566 return retrc; 3582 3567 3583 3568 req_irq_failed: 3569 + tasklet_kill(&adapter->tasklet); 3584 3570 do { 3585 3571 rc = plpar_hcall_norets(H_FREE_CRQ, vdev->unit_address); 3586 3572 } while (rc == H_BUSY || H_IS_LONG_BUSY(rc));
+1
drivers/net/ethernet/ibm/ibmvnic.h
··· 1049 1049 1050 1050 struct work_struct vnic_crq_init; 1051 1051 struct work_struct ibmvnic_xport; 1052 + struct tasklet_struct tasklet; 1052 1053 bool failover; 1053 1054 };