Skip to content

Commit 2ac061c

Browse files
jgross1Jakub Kicinski
authored andcommitted
xen/netback: cleanup init and deinit code
Do some cleanup of the netback init and deinit code: - add an omnipotent queue deinit function usable from xenvif_disconnect_data() and the error path of xenvif_connect_data() - only install the irq handlers after initializing all relevant items (especially the kthreads related to the queue) - there is no need to use get_task_struct() after creating a kthread and using put_task_struct() again after having stopped it. - use kthread_run() instead of kthread_create() to spare the call of wake_up_process(). Signed-off-by: Juergen Gross <[email protected]> Reviewed-by: Paul Durrant <[email protected]> Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 88238d2 commit 2ac061c

File tree

1 file changed

+54
-60
lines changed

1 file changed

+54
-60
lines changed

drivers/net/xen-netback/interface.c

Lines changed: 54 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -626,6 +626,38 @@ int xenvif_connect_ctrl(struct xenvif *vif, grant_ref_t ring_ref,
626626
return err;
627627
}
628628

629+
static void xenvif_disconnect_queue(struct xenvif_queue *queue)
630+
{
631+
if (queue->tx_irq) {
632+
unbind_from_irqhandler(queue->tx_irq, queue);
633+
if (queue->tx_irq == queue->rx_irq)
634+
queue->rx_irq = 0;
635+
queue->tx_irq = 0;
636+
}
637+
638+
if (queue->rx_irq) {
639+
unbind_from_irqhandler(queue->rx_irq, queue);
640+
queue->rx_irq = 0;
641+
}
642+
643+
if (queue->task) {
644+
kthread_stop(queue->task);
645+
queue->task = NULL;
646+
}
647+
648+
if (queue->dealloc_task) {
649+
kthread_stop(queue->dealloc_task);
650+
queue->dealloc_task = NULL;
651+
}
652+
653+
if (queue->napi.poll) {
654+
netif_napi_del(&queue->napi);
655+
queue->napi.poll = NULL;
656+
}
657+
658+
xenvif_unmap_frontend_data_rings(queue);
659+
}
660+
629661
int xenvif_connect_data(struct xenvif_queue *queue,
630662
unsigned long tx_ring_ref,
631663
unsigned long rx_ring_ref,
@@ -651,13 +683,27 @@ int xenvif_connect_data(struct xenvif_queue *queue,
651683
netif_napi_add(queue->vif->dev, &queue->napi, xenvif_poll,
652684
XENVIF_NAPI_WEIGHT);
653685

686+
queue->stalled = true;
687+
688+
task = kthread_run(xenvif_kthread_guest_rx, queue,
689+
"%s-guest-rx", queue->name);
690+
if (IS_ERR(task))
691+
goto kthread_err;
692+
queue->task = task;
693+
694+
task = kthread_run(xenvif_dealloc_kthread, queue,
695+
"%s-dealloc", queue->name);
696+
if (IS_ERR(task))
697+
goto kthread_err;
698+
queue->dealloc_task = task;
699+
654700
if (tx_evtchn == rx_evtchn) {
655701
/* feature-split-event-channels == 0 */
656702
err = bind_interdomain_evtchn_to_irqhandler(
657703
queue->vif->domid, tx_evtchn, xenvif_interrupt, 0,
658704
queue->name, queue);
659705
if (err < 0)
660-
goto err_unmap;
706+
goto err;
661707
queue->tx_irq = queue->rx_irq = err;
662708
disable_irq(queue->tx_irq);
663709
} else {
@@ -668,7 +714,7 @@ int xenvif_connect_data(struct xenvif_queue *queue,
668714
queue->vif->domid, tx_evtchn, xenvif_tx_interrupt, 0,
669715
queue->tx_irq_name, queue);
670716
if (err < 0)
671-
goto err_unmap;
717+
goto err;
672718
queue->tx_irq = err;
673719
disable_irq(queue->tx_irq);
674720

@@ -678,47 +724,18 @@ int xenvif_connect_data(struct xenvif_queue *queue,
678724
queue->vif->domid, rx_evtchn, xenvif_rx_interrupt, 0,
679725
queue->rx_irq_name, queue);
680726
if (err < 0)
681-
goto err_tx_unbind;
727+
goto err;
682728
queue->rx_irq = err;
683729
disable_irq(queue->rx_irq);
684730
}
685731

686-
queue->stalled = true;
687-
688-
task = kthread_create(xenvif_kthread_guest_rx,
689-
(void *)queue, "%s-guest-rx", queue->name);
690-
if (IS_ERR(task)) {
691-
pr_warn("Could not allocate kthread for %s\n", queue->name);
692-
err = PTR_ERR(task);
693-
goto err_rx_unbind;
694-
}
695-
queue->task = task;
696-
get_task_struct(task);
697-
698-
task = kthread_create(xenvif_dealloc_kthread,
699-
(void *)queue, "%s-dealloc", queue->name);
700-
if (IS_ERR(task)) {
701-
pr_warn("Could not allocate kthread for %s\n", queue->name);
702-
err = PTR_ERR(task);
703-
goto err_rx_unbind;
704-
}
705-
queue->dealloc_task = task;
706-
707-
wake_up_process(queue->task);
708-
wake_up_process(queue->dealloc_task);
709-
710732
return 0;
711733

712-
err_rx_unbind:
713-
unbind_from_irqhandler(queue->rx_irq, queue);
714-
queue->rx_irq = 0;
715-
err_tx_unbind:
716-
unbind_from_irqhandler(queue->tx_irq, queue);
717-
queue->tx_irq = 0;
718-
err_unmap:
719-
xenvif_unmap_frontend_data_rings(queue);
720-
netif_napi_del(&queue->napi);
734+
kthread_err:
735+
pr_warn("Could not allocate kthread for %s\n", queue->name);
736+
err = PTR_ERR(task);
721737
err:
738+
xenvif_disconnect_queue(queue);
722739
return err;
723740
}
724741

@@ -746,30 +763,7 @@ void xenvif_disconnect_data(struct xenvif *vif)
746763
for (queue_index = 0; queue_index < num_queues; ++queue_index) {
747764
queue = &vif->queues[queue_index];
748765

749-
netif_napi_del(&queue->napi);
750-
751-
if (queue->task) {
752-
kthread_stop(queue->task);
753-
put_task_struct(queue->task);
754-
queue->task = NULL;
755-
}
756-
757-
if (queue->dealloc_task) {
758-
kthread_stop(queue->dealloc_task);
759-
queue->dealloc_task = NULL;
760-
}
761-
762-
if (queue->tx_irq) {
763-
if (queue->tx_irq == queue->rx_irq)
764-
unbind_from_irqhandler(queue->tx_irq, queue);
765-
else {
766-
unbind_from_irqhandler(queue->tx_irq, queue);
767-
unbind_from_irqhandler(queue->rx_irq, queue);
768-
}
769-
queue->tx_irq = 0;
770-
}
771-
772-
xenvif_unmap_frontend_data_rings(queue);
766+
xenvif_disconnect_queue(queue);
773767
}
774768

775769
xenvif_mcast_addr_list_free(vif);

0 commit comments

Comments
 (0)