diff options
author | José Pekkarinen <jose.pekkarinen@nokia.com> | 2016-04-11 10:41:07 +0300 |
---|---|---|
committer | José Pekkarinen <jose.pekkarinen@nokia.com> | 2016-04-13 08:17:18 +0300 |
commit | e09b41010ba33a20a87472ee821fa407a5b8da36 (patch) | |
tree | d10dc367189862e7ca5c592f033dc3726e1df4e3 /kernel/drivers/infiniband/hw/amso1100/c2_vq.c | |
parent | f93b97fd65072de626c074dbe099a1fff05ce060 (diff) |
These changes are the raw update to linux-4.4.6-rt14. Kernel sources
are taken from kernel.org, and rt patch from the rt wiki download page.
During the rebasing, the following patch collided:
Force tick interrupt and get rid of softirq magic(I70131fb85).
Collisions have been removed because its logic was found on the
source already.
Change-Id: I7f57a4081d9deaa0d9ccfc41a6c8daccdee3b769
Signed-off-by: José Pekkarinen <jose.pekkarinen@nokia.com>
Diffstat (limited to 'kernel/drivers/infiniband/hw/amso1100/c2_vq.c')
-rw-r--r-- | kernel/drivers/infiniband/hw/amso1100/c2_vq.c | 260 |
1 files changed, 0 insertions, 260 deletions
diff --git a/kernel/drivers/infiniband/hw/amso1100/c2_vq.c b/kernel/drivers/infiniband/hw/amso1100/c2_vq.c deleted file mode 100644 index 2ec716fb2..000000000 --- a/kernel/drivers/infiniband/hw/amso1100/c2_vq.c +++ /dev/null @@ -1,260 +0,0 @@ -/* - * Copyright (c) 2005 Ammasso, Inc. All rights reserved. - * Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved. - * - * This software is available to you under a choice of one of two - * licenses. You may choose to be licensed under the terms of the GNU - * General Public License (GPL) Version 2, available from the file - * COPYING in the main directory of this source tree, or the - * OpenIB.org BSD license below: - * - * Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * - Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * - * - Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -#include <linux/slab.h> -#include <linux/spinlock.h> - -#include "c2_vq.h" -#include "c2_provider.h" - -/* - * Verbs Request Objects: - * - * VQ Request Objects are allocated by the kernel verbs handlers. - * They contain a wait object, a refcnt, an atomic bool indicating that the - * adapter has replied, and a copy of the verb reply work request. - * A pointer to the VQ Request Object is passed down in the context - * field of the work request message, and reflected back by the adapter - * in the verbs reply message. The function handle_vq() in the interrupt - * path will use this pointer to: - * 1) append a copy of the verbs reply message - * 2) mark that the reply is ready - * 3) wake up the kernel verbs handler blocked awaiting the reply. - * - * - * The kernel verbs handlers do a "get" to put a 2nd reference on the - * VQ Request object. If the kernel verbs handler exits before the adapter - * can respond, this extra reference will keep the VQ Request object around - * until the adapter's reply can be processed. The reason we need this is - * because a pointer to this object is stuffed into the context field of - * the verbs work request message, and reflected back in the reply message. - * It is used in the interrupt handler (handle_vq()) to wake up the appropriate - * kernel verb handler that is blocked awaiting the verb reply. - * So handle_vq() will do a "put" on the object when it's done accessing it. - * NOTE: If we guarantee that the kernel verb handler will never bail before - * getting the reply, then we don't need these refcnts. - * - * - * VQ Request objects are freed by the kernel verbs handlers only - * after the verb has been processed, or when the adapter fails and - * does not reply. - * - * - * Verbs Reply Buffers: - * - * VQ Reply bufs are local host memory copies of a - * outstanding Verb Request reply - * message. The are always allocated by the kernel verbs handlers, and _may_ be - * freed by either the kernel verbs handler -or- the interrupt handler. The - * kernel verbs handler _must_ free the repbuf, then free the vq request object - * in that order. - */ - -int vq_init(struct c2_dev *c2dev) -{ - sprintf(c2dev->vq_cache_name, "c2-vq:dev%c", - (char) ('0' + c2dev->devnum)); - c2dev->host_msg_cache = - kmem_cache_create(c2dev->vq_cache_name, c2dev->rep_vq.msg_size, 0, - SLAB_HWCACHE_ALIGN, NULL); - if (c2dev->host_msg_cache == NULL) { - return -ENOMEM; - } - return 0; -} - -void vq_term(struct c2_dev *c2dev) -{ - kmem_cache_destroy(c2dev->host_msg_cache); -} - -/* vq_req_alloc - allocate a VQ Request Object and initialize it. - * The refcnt is set to 1. - */ -struct c2_vq_req *vq_req_alloc(struct c2_dev *c2dev) -{ - struct c2_vq_req *r; - - r = kmalloc(sizeof(struct c2_vq_req), GFP_KERNEL); - if (r) { - init_waitqueue_head(&r->wait_object); - r->reply_msg = 0; - r->event = 0; - r->cm_id = NULL; - r->qp = NULL; - atomic_set(&r->refcnt, 1); - atomic_set(&r->reply_ready, 0); - } - return r; -} - - -/* vq_req_free - free the VQ Request Object. It is assumed the verbs handler - * has already free the VQ Reply Buffer if it existed. - */ -void vq_req_free(struct c2_dev *c2dev, struct c2_vq_req *r) -{ - r->reply_msg = 0; - if (atomic_dec_and_test(&r->refcnt)) { - kfree(r); - } -} - -/* vq_req_get - reference a VQ Request Object. Done - * only in the kernel verbs handlers. - */ -void vq_req_get(struct c2_dev *c2dev, struct c2_vq_req *r) -{ - atomic_inc(&r->refcnt); -} - - -/* vq_req_put - dereference and potentially free a VQ Request Object. - * - * This is only called by handle_vq() on the - * interrupt when it is done processing - * a verb reply message. If the associated - * kernel verbs handler has already bailed, - * then this put will actually free the VQ - * Request object _and_ the VQ Reply Buffer - * if it exists. - */ -void vq_req_put(struct c2_dev *c2dev, struct c2_vq_req *r) -{ - if (atomic_dec_and_test(&r->refcnt)) { - if (r->reply_msg != 0) - vq_repbuf_free(c2dev, - (void *) (unsigned long) r->reply_msg); - kfree(r); - } -} - - -/* - * vq_repbuf_alloc - allocate a VQ Reply Buffer. - */ -void *vq_repbuf_alloc(struct c2_dev *c2dev) -{ - return kmem_cache_alloc(c2dev->host_msg_cache, GFP_ATOMIC); -} - -/* - * vq_send_wr - post a verbs request message to the Verbs Request Queue. - * If a message is not available in the MQ, then block until one is available. - * NOTE: handle_mq() on the interrupt context will wake up threads blocked here. - * When the adapter drains the Verbs Request Queue, - * it inserts MQ index 0 in to the - * adapter->host activity fifo and interrupts the host. - */ -int vq_send_wr(struct c2_dev *c2dev, union c2wr *wr) -{ - void *msg; - wait_queue_t __wait; - - /* - * grab adapter vq lock - */ - spin_lock(&c2dev->vqlock); - - /* - * allocate msg - */ - msg = c2_mq_alloc(&c2dev->req_vq); - - /* - * If we cannot get a msg, then we'll wait - * When a messages are available, the int handler will wake_up() - * any waiters. - */ - while (msg == NULL) { - pr_debug("%s:%d no available msg in VQ, waiting...\n", - __func__, __LINE__); - init_waitqueue_entry(&__wait, current); - add_wait_queue(&c2dev->req_vq_wo, &__wait); - spin_unlock(&c2dev->vqlock); - for (;;) { - set_current_state(TASK_INTERRUPTIBLE); - if (!c2_mq_full(&c2dev->req_vq)) { - break; - } - if (!signal_pending(current)) { - schedule_timeout(1 * HZ); /* 1 second... */ - continue; - } - set_current_state(TASK_RUNNING); - remove_wait_queue(&c2dev->req_vq_wo, &__wait); - return -EINTR; - } - set_current_state(TASK_RUNNING); - remove_wait_queue(&c2dev->req_vq_wo, &__wait); - spin_lock(&c2dev->vqlock); - msg = c2_mq_alloc(&c2dev->req_vq); - } - - /* - * copy wr into adapter msg - */ - memcpy(msg, wr, c2dev->req_vq.msg_size); - - /* - * post msg - */ - c2_mq_produce(&c2dev->req_vq); - - /* - * release adapter vq lock - */ - spin_unlock(&c2dev->vqlock); - return 0; -} - - -/* - * vq_wait_for_reply - block until the adapter posts a Verb Reply Message. - */ -int vq_wait_for_reply(struct c2_dev *c2dev, struct c2_vq_req *req) -{ - if (!wait_event_timeout(req->wait_object, - atomic_read(&req->reply_ready), - 60*HZ)) - return -ETIMEDOUT; - - return 0; -} - -/* - * vq_repbuf_free - Free a Verbs Reply Buffer. - */ -void vq_repbuf_free(struct c2_dev *c2dev, void *reply) -{ - kmem_cache_free(c2dev->host_msg_cache, reply); -} |