Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=a1e6ef2f1e01f2aa9ed930e1089fc85dc745bf7a
Commit:     a1e6ef2f1e01f2aa9ed930e1089fc85dc745bf7a
Parent:     cd12fb906d2591e80da9edcbd4794b9b916d7489
Author:     Evgeniy Polyakov <[EMAIL PROTECTED]>
AuthorDate: Sat Nov 10 20:24:18 2007 +0800
Committer:  Herbert Xu <[EMAIL PROTECTED]>
CommitDate: Fri Jan 11 08:16:12 2008 +1100

    [CRYPTO] hifn: Schedule callback invocation to tasklet.
    
    This patch forces HIFN driver to invoke crypto request callbacks from
    tasklet (softirq context) instead of hardirq context, since network
    stack expects it to be called from bottom halves.
    
    It is done by simply scheduling callback invocation via dedicated
    tasklet. Workqueue solution was dropped because of tooo slow
    rescheduling performance (7 times slower than tasklet, for mode details
    one can check this link:
    http://tservice.net.ru/~s0mbre/blog/devel/other/2007_11_09.html).
    
    Driver passed all AES and DES tests in tcryt.c module.
    
    Signed-off-by: Evgeniy Polyakov <[EMAIL PROTECTED]>
    Signed-off-by: Herbert Xu <[EMAIL PROTECTED]>
---
 drivers/crypto/hifn_795x.c |   22 +++++++++++++++++++++-
 1 files changed, 21 insertions(+), 1 deletions(-)

diff --git a/drivers/crypto/hifn_795x.c b/drivers/crypto/hifn_795x.c
index 391c20a..7b7c854 100644
--- a/drivers/crypto/hifn_795x.c
+++ b/drivers/crypto/hifn_795x.c
@@ -26,6 +26,7 @@
 #include <linux/delay.h>
 #include <linux/mm.h>
 #include <linux/highmem.h>
+#include <linux/interrupt.h>
 #include <linux/crypto.h>
 
 #include <crypto/algapi.h>
@@ -426,6 +427,8 @@ struct hifn_device
 
        u8                      snum;
 
+       struct tasklet_struct   tasklet;
+
        struct crypto_queue     queue;
        struct list_head        alg_list;
 };
@@ -1879,7 +1882,7 @@ static irqreturn_t hifn_interrupt(int irq, void *data)
                hifn_write_1(dev, HIFN_1_DMA_IER, dev->dmareg);
        }
 
-       hifn_check_for_completion(dev, 0);
+       tasklet_schedule(&dev->tasklet);
        hifn_clear_rings(dev);
 
        return IRQ_HANDLED;
@@ -2408,6 +2411,19 @@ err_out_exit:
        return err;
 }
 
+static void hifn_tasklet_callback(unsigned long data)
+{
+       struct hifn_device *dev = (struct hifn_device *)data;
+
+       /*
+        * This is ok to call this without lock being held,
+        * althogh it modifies some parameters used in parallel,
+        * (like dev->success), but they are used in process
+        * context or update is atomic (like setting dev->sa[i] to NULL).
+        */
+       hifn_check_for_completion(dev, 0);
+}
+
 static int hifn_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 {
        int err, i;
@@ -2489,6 +2505,8 @@ static int hifn_probe(struct pci_dev *pdev, const struct 
pci_device_id *id)
 
        pci_set_drvdata(pdev, dev);
 
+       tasklet_init(&dev->tasklet, hifn_tasklet_callback, (unsigned long)dev);
+
        crypto_init_queue(&dev->queue, 1);
 
        err = request_irq(dev->irq, hifn_interrupt, IRQF_SHARED, dev->name, 
dev);
@@ -2524,6 +2542,7 @@ err_out_stop_device:
        hifn_stop_device(dev);
 err_out_free_irq:
        free_irq(dev->irq, dev->name);
+       tasklet_kill(&dev->tasklet);
 err_out_free_desc:
        pci_free_consistent(pdev, sizeof(struct hifn_dma),
                        dev->desc_virt, dev->desc_dma);
@@ -2563,6 +2582,7 @@ static void hifn_remove(struct pci_dev *pdev)
                hifn_stop_device(dev);
 
                free_irq(dev->irq, dev->name);
+               tasklet_kill(&dev->tasklet);
 
                hifn_flush(dev);
 
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to