[PATCH 00/14] RFC: VMCI for Linux

February 14th, 2012 - 08:20 pm ET by Andrew Stiegmann (stieg) | Report spam
In an effort to improve the out-of-the-box experience with Linux
kernels for VMware users, VMware is working on readying the Virtual
Machine Communication Interface (VMCI) and VMCI Sockets (vsock) kernel
modules for inclusion in the Linux kernel. The purpose of this initial
post is to both show how much we love Linux on Valentine's day and
request early feedback on the VMCI kernel module with the
intent of addressing any major issues early in the process. The VMCI
Socket kernel module will be presented in a later post.

VMCI allows virtual machines to communicate with host kernel modules
and the VMware hypervisors. User level applications both in a virtual
machine and on the host can use VMCI through VMCI Sockets, a socket
address family designed to be compatible with UDP and TCP at the
interface level. Today, VMCI and VMCI Sockets are used by the VMware
shared folders (HGFS) and various VMware Tools components inside the
guest for zero-config, network-less access to VMware host services. In
addition to this, VMware's users are using VMCI Sockets for various
applications, where network access of the virtual machine is
restricted or non-existent. Examples of this are VMs communicating
with device proxies for proprietary hardware running as host
applications and automated testing of applications running within
virtual machines.

In a virtual machine, VMCI is exposed as a regular PCI device. The
primary communication mechanisms supported are a point-to-point
bidirectional transport based on a pair of memory-mapped queues, and
asynchronous notifications in the form of datagrams and
doorbells. These features are available to kernel level components
such as HGFS and VMCI Sockets through the VMCI kernel API. In addition
to this, the VMCI kernel API provides support for receiving events
related to the state of the VMCI communication channels, and the
virtual machine itself.

Outside the virtual machine, the host side support of the VMCI kernel
module makes the same VMCI kernel API available to VMCI endpoints on
the host. In addition to this, the host side manages each VMCI device
in a virtual machine through a context object. This context object
serves to identify the virtual machine for communication, and to track
the resource consumption of the given VMCI device. Both operations
related to communication between the virtual machine and the host
kernel, and those related to the management of the VMCI device state
in the host kernel, are invoked by the user level component of the
hypervisor through a set of ioctls on the VMCI device node. To
provide seamless support for nested virtualization, where a virtual
machine may use both a VMCI PCI device to talk to its hypervisor, and
the VMCI host side support to run nested virtual machines, the VMCI
host and virtual machine support are combined in a single kernel
module.

For additional information about the use of VMCI and in particular
VMCI Sockets, please refer to the VMCI Socket Programming Guide
available at https://www.vmware.com/support/deve...vmci-sdk/.

Andrew Stiegmann (stieg) (14):
Add vmciContext.*
Add vmciDatagram.*
Add vmciDoorbell.*
Add vmciDriver.*
Add vmciEvent.*
Add vmciHashtable.*
Add vmciQueuePair.*
Add vmciResource.*
Add vmciRoute.*
Add accessor methods for Queue Pairs in VMCI
Add VMCI kernel API defs and the internal header file
Add misc header files used by VMCI
Add main driver and kernel interface file
Add Kconfig and Makefiles for VMCI

drivers/misc/Kconfig | 1 +
drivers/misc/Makefile | 1 +
drivers/misc/vmw_vmci/Kconfig | 16 +
drivers/misc/vmw_vmci/Makefile | 36 +
drivers/misc/vmw_vmci/driver.c | 2352 +++++++++++++++++++++++
drivers/misc/vmw_vmci/vmciCommonInt.h | 105 ++
drivers/misc/vmw_vmci/vmciContext.c | 1763 +++++++++++++++++
drivers/misc/vmw_vmci/vmciContext.h | 77 +
drivers/misc/vmw_vmci/vmciDatagram.c | 842 +++++++++
drivers/misc/vmw_vmci/vmciDatagram.h | 42 +
drivers/misc/vmw_vmci/vmciDoorbell.c | 1072 +++++++++++
drivers/misc/vmw_vmci/vmciDoorbell.h | 37 +
drivers/misc/vmw_vmci/vmciDriver.c | 663 +++++++
drivers/misc/vmw_vmci/vmciDriver.h | 57 +
drivers/misc/vmw_vmci/vmciEvent.c | 648 +++++++
drivers/misc/vmw_vmci/vmciEvent.h | 32 +
drivers/misc/vmw_vmci/vmciHashtable.c | 519 +++++
drivers/misc/vmw_vmci/vmciHashtable.h | 58 +
drivers/misc/vmw_vmci/vmciKernelAPI.h | 28 +
drivers/misc/vmw_vmci/vmciKernelAPI1.h | 148 ++
drivers/misc/vmw_vmci/vmciKernelAPI2.h | 48 +
drivers/misc/vmw_vmci/vmciKernelIf.c | 1351 ++++++++++++++
drivers/misc/vmw_vmci/vmciQPair.c | 1164 ++++++++++++
drivers/misc/vmw_vmci/vmciQueue.h | 108 ++
drivers/misc/vmw_vmci/vmciQueuePair.c | 2696 +++++++++++++++++++++++++++
drivers/misc/vmw_vmci/vmciQueuePair.h | 95 +
drivers/misc/vmw_vmci/vmciResource.c | 383 ++++
drivers/misc/vmw_vmci/vmciResource.h | 68 +
drivers/misc/vmw_vmci/vmciRoute.c | 249 +++
drivers/misc/vmw_vmci/vmciRoute.h | 36 +
drivers/misc/vmw_vmci/vmci_call_defs.h | 264 +++
drivers/misc/vmw_vmci/vmci_defs.h | 772 ++++++++
drivers/misc/vmw_vmci/vmci_handle_array.h | 339 ++++
drivers/misc/vmw_vmci/vmci_infrastructure.h | 119 ++
drivers/misc/vmw_vmci/vmci_iocontrols.h | 411 ++++
drivers/misc/vmw_vmci/vmci_kernel_if.h | 111 ++
36 files changed, 16711 insertions(+), 0 deletions(-)
create mode 100644 drivers/misc/vmw_vmci/Kconfig
create mode 100644 drivers/misc/vmw_vmci/Makefile
create mode 100644 drivers/misc/vmw_vmci/driver.c
create mode 100644 drivers/misc/vmw_vmci/vmciCommonInt.h
create mode 100644 drivers/misc/vmw_vmci/vmciContext.c
create mode 100644 drivers/misc/vmw_vmci/vmciContext.h
create mode 100644 drivers/misc/vmw_vmci/vmciDatagram.c
create mode 100644 drivers/misc/vmw_vmci/vmciDatagram.h
create mode 100644 drivers/misc/vmw_vmci/vmciDoorbell.c
create mode 100644 drivers/misc/vmw_vmci/vmciDoorbell.h
create mode 100644 drivers/misc/vmw_vmci/vmciDriver.c
create mode 100644 drivers/misc/vmw_vmci/vmciDriver.h
create mode 100644 drivers/misc/vmw_vmci/vmciEvent.c
create mode 100644 drivers/misc/vmw_vmci/vmciEvent.h
create mode 100644 drivers/misc/vmw_vmci/vmciHashtable.c
create mode 100644 drivers/misc/vmw_vmci/vmciHashtable.h
create mode 100644 drivers/misc/vmw_vmci/vmciKernelAPI.h
create mode 100644 drivers/misc/vmw_vmci/vmciKernelAPI1.h
create mode 100644 drivers/misc/vmw_vmci/vmciKernelAPI2.h
create mode 100644 drivers/misc/vmw_vmci/vmciKernelIf.c
create mode 100644 drivers/misc/vmw_vmci/vmciQPair.c
create mode 100644 drivers/misc/vmw_vmci/vmciQueue.h
create mode 100644 drivers/misc/vmw_vmci/vmciQueuePair.c
create mode 100644 drivers/misc/vmw_vmci/vmciQueuePair.h
create mode 100644 drivers/misc/vmw_vmci/vmciResource.c
create mode 100644 drivers/misc/vmw_vmci/vmciResource.h
create mode 100644 drivers/misc/vmw_vmci/vmciRoute.c
create mode 100644 drivers/misc/vmw_vmci/vmciRoute.h
create mode 100644 drivers/misc/vmw_vmci/vmci_call_defs.h
create mode 100644 drivers/misc/vmw_vmci/vmci_defs.h
create mode 100644 drivers/misc/vmw_vmci/vmci_handle_array.h
create mode 100644 drivers/misc/vmw_vmci/vmci_infrastructure.h
create mode 100644 drivers/misc/vmw_vmci/vmci_iocontrols.h
create mode 100644 drivers/misc/vmw_vmci/vmci_kernel_if.h
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
email Follow the discussionReplies 9 repliesReplies Make a reply

Replies

#1 Andrew Stiegmann (stieg)
February 14th, 2012 - 08:20 pm ET | Report spam
drivers/misc/vmw_vmci/vmciHashtable.c | 519 +++++++++++++++++++++++++++++++++
drivers/misc/vmw_vmci/vmciHashtable.h | 58 ++++
2 files changed, 577 insertions(+), 0 deletions(-)
create mode 100644 drivers/misc/vmw_vmci/vmciHashtable.c
create mode 100644 drivers/misc/vmw_vmci/vmciHashtable.h

diff --git a/drivers/misc/vmw_vmci/vmciHashtable.c b/drivers/misc/vmw_vmci/vmciHashtable.c
new file mode 100644
index 0000000..dd5c4cd
/dev/null
+++ b/drivers/misc/vmw_vmci/vmciHashtable.c
@@ -0,0 +1,519 @@
+/*
+ *
+ * VMware VMCI Driver
+ *
+ * Copyright (C) 2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2 and no later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "vmci_defs.h"
+#include "vmci_infrastructure.h"
+#include "vmci_kernel_if.h"
+#include "vmciCommonInt.h"
+#include "vmciDriver.h"
+#include "vmciHashtable.h"
+
+#define LGPFX "VMCIHashTable: "
+
+#define VMCI_HASHTABLE_HASH(_h, _sz) \
+ VMCI_HashId(VMCI_HANDLE_TO_RESOURCE_ID(_h), (_sz))
+
+/* static int HashTableUnlinkEntry(struct vmci_hash_table *table, */
+/* struct vmci_hash_entry *entry); */
+/* static bool VMCIHashTableEntryExistsLocked(struct vmci_hash_table *table, */
+/* struct vmci_handle handle); */
+
+/*
+ *
+ *
+ * VMCIHashTable_Create --
+ * XXX: Factor out the hashtable code to be shared amongst host and guest.
+ *
+ * Result:
+ * None.
+ *
+ *
+ */
+
+struct vmci_hash_table *VMCIHashTable_Create(int size)
+{
+
+ struct vmci_hash_table *table = kmalloc(sizeof *table, GFP_KERNEL);
+ if (table == NULL)
+ return NULL;
+
+ table->entries = kmalloc(sizeof *table->entries * size, GFP_KERNEL);
+ if (table->entries == NULL) {
+ kfree(table);
+ return NULL;
+ }
+ memset(table->entries, 0, sizeof *table->entries * size);
+ table->size = size;
+
+ spin_lock_init(&table->lock);
+
+ return table;
+}
+
+/*
+ *
+ *
+ * VMCIHashTable_Destroy --
+ * This function should be called at module exit time.
+ * We rely on the module ref count to insure that no one is accessing any
+ * hash table entries at this point in time. Hence we should be able to just
+ * remove all entries from the hash table.
+ *
+ * Result:
+ * None.
+ *
+ *
+ */
+
+void VMCIHashTable_Destroy(struct vmci_hash_table *table)
+{
+ ASSERT(table);
+
+ spin_lock_bh(&table->lock);
+ kfree(table->entries);
+ table->entries = NULL;
+ spin_unlock_bh(&table->lock);
+ kfree(table);
+}
+
+/*
+ *
+ *
+ * VMCIHashTable_InitEntry --
+ * Initializes a hash entry;
+ *
+ * Result:
+ * None.
+ *
+ *
+ */
+void VMCIHashTable_InitEntry(struct vmci_hash_entry *entry, // IN
+ struct vmci_handle handle) // IN
+{
+ ASSERT(entry);
+ entry->handle = handle;
+ entry->refCount = 0;
+}
+
+/*
+ *
+ *
+ * VMCIHashTableEntryExistsLocked --
+ *
+ * Unlocked version of VMCIHashTable_EntryExists.
+ *
+ * Result:
+ * true if handle already in hashtable. false otherwise.
+ *
+ * Side effects:
+ * None.
+ *
+ *
+ */
+
+static bool VMCIHashTableEntryExistsLocked(struct vmci_hash_table *table, // IN
+ struct vmci_handle handle) // IN
+{
+ struct vmci_hash_entry *entry;
+ int idx;
+
+ ASSERT(table);
+
+ idx = VMCI_HASHTABLE_HASH(handle, table->size);
+
+ for (entry = table->entries[idx]; entry; entry = entry->next) {
+ if (VMCI_HANDLE_TO_RESOURCE_ID(entry->handle) =+ VMCI_HANDLE_TO_RESOURCE_ID(handle) &&
+ ((VMCI_HANDLE_TO_CONTEXT_ID(entry->handle) =+ VMCI_HANDLE_TO_CONTEXT_ID(handle)) ||
+ (VMCI_INVALID_ID == VMCI_HANDLE_TO_CONTEXT_ID(handle))
+ || (VMCI_INVALID_ID =+ VMCI_HANDLE_TO_CONTEXT_ID(entry->handle)))) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+/*
+ *
+ *
+ * HashTableUnlinkEntry --
+ * XXX Factor out the hashtable code to shared amongst API and perhaps
+ * host and guest.
+ * Assumes caller holds table lock.
+ *
+ * Result:
+ * None.
+ *
+ *
+ */
+
+static int HashTableUnlinkEntry(struct vmci_hash_table *table, // IN
+ struct vmci_hash_entry *entry) // IN
+{
+ int result;
+ struct vmci_hash_entry *prev, *cur;
+ int idx;
+
+ idx = VMCI_HASHTABLE_HASH(entry->handle, table->size);
+
+ prev = NULL;
+ cur = table->entries[idx];
+ while (true) {
+ if (cur == NULL) {
+ result = VMCI_ERROR_NOT_FOUND;
+ break;
+ }
+ if (VMCI_HANDLE_EQUAL(cur->handle, entry->handle)) {
+ ASSERT(cur == entry);
+
+ /* Remove entry and break. */
+ if (prev) {
+ prev->next = cur->next;
+ } else {
+ table->entries[idx] = cur->next;
+ }
+ cur->next = NULL;
+ result = VMCI_SUCCESS;
+ break;
+ }
+ prev = cur;
+ cur = cur->next;
+ }
+ return result;
+}
+
+/*
+ *
+ *
+ * VMCIHashTable_AddEntry --
+ * XXX Factor out the hashtable code to be shared amongst host and guest.
+ *
+ * Result:
+ * None.
+ *
+ *
+ */
+
+int VMCIHashTable_AddEntry(struct vmci_hash_table *table, // IN
+ struct vmci_hash_entry *entry) // IN
+{
+ int idx;
+
+ ASSERT(entry);
+ ASSERT(table);
+
+ spin_lock_bh(&table->lock);
+
+ /* Creation of a new hashtable entry is always allowed. */
+ if (VMCIHashTableEntryExistsLocked(table, entry->handle)) {
+ VMCI_DEBUG_LOG(4,
+ (LGPFX
+ "Entry (handle=0x%x:0x%x) already exists.",
+ entry->handle.context, entry->handle.resource));
+ spin_unlock_bh(&table->lock);
+ return VMCI_ERROR_DUPLICATE_ENTRY;
+ }
+
+ idx = VMCI_HASHTABLE_HASH(entry->handle, table->size);
+ ASSERT(idx < table->size);
+
+ /* New entry is added to top/front of hash bucket. */
+ entry->refCount++;
+ entry->next = table->entries[idx];
+ table->entries[idx] = entry;
+ spin_unlock_bh(&table->lock);
+
+ return VMCI_SUCCESS;
+}
+
+/*
+ *
+ *
+ * VMCIHashTable_RemoveEntry --
+ * XXX Factor out the hashtable code to shared amongst API and perhaps
+ * host and guest.
+ *
+ * Result:
+ * None.
+ *
+ *
+ */
+
+int VMCIHashTable_RemoveEntry(struct vmci_hash_table *table, // IN
+ struct vmci_hash_entry *entry) // IN
+{
+ int result;
+
+ ASSERT(table);
+ ASSERT(entry);
+
+ spin_lock_bh(&table->lock);
+
+ /* First unlink the entry. */
+ result = HashTableUnlinkEntry(table, entry);
+ if (result != VMCI_SUCCESS) {
+ /* We failed to find the entry. */
+ goto done;
+ }
+
+ /* Decrement refcount and check if this is last reference. */
+ entry->refCount--;
+ if (entry->refCount == 0) {
+ result = VMCI_SUCCESS_ENTRY_DEAD;
+ goto done;
+ }
+
+ done:
+ spin_unlock_bh(&table->lock);
+
+ return result;
+}
+
+/*
+ *
+ *
+ * VMCIHashTableGetEntryLocked --
+ *
+ * Looks up an entry in the hash table, that is already locked.
+ *
+ * Result:
+ * If the element is found, a pointer to the element is returned.
+ * Otherwise NULL is returned.
+ *
+ * Side effects:
+ * The reference count of the returned element is increased.
+ *
+ *
+ */
+
+static inline struct vmci_hash_entry *VMCIHashTableGetEntryLocked(struct vmci_hash_table *table, // IN
+ struct vmci_handle handle) // IN
+{
+ struct vmci_hash_entry *cur = NULL;
+ int idx;
+
+ ASSERT(!VMCI_HANDLE_EQUAL(handle, VMCI_INVALID_HANDLE));
+ ASSERT(table);
+
+ idx = VMCI_HASHTABLE_HASH(handle, table->size);
+
+ for (cur = table->entries[idx]; cur != NULL; cur = cur->next) {
+ if (VMCI_HANDLE_TO_RESOURCE_ID(cur->handle) =+ VMCI_HANDLE_TO_RESOURCE_ID(handle) &&
+ ((VMCI_HANDLE_TO_CONTEXT_ID(cur->handle) =+ VMCI_HANDLE_TO_CONTEXT_ID(handle)) ||
+ (VMCI_INVALID_ID =+ VMCI_HANDLE_TO_CONTEXT_ID(cur->handle)))) {
+ cur->refCount++;
+ break;
+ }
+ }
+
+ return cur;
+}
+
+/*
+ *
+ *
+ * VMCIHashTable_GetEntry --
+ * XXX Factor out the hashtable code to shared amongst API and perhaps
+ * host and guest.
+ *
+ * Result:
+ * None.
+ *
+ *
+ */
+
+struct vmci_hash_entry *VMCIHashTable_GetEntry(struct vmci_hash_table *table, // IN
+ struct vmci_handle handle) // IN
+{
+ struct vmci_hash_entry *entry;
+
+ if (VMCI_HANDLE_EQUAL(handle, VMCI_INVALID_HANDLE))
+ return NULL;
+
+ ASSERT(table);
+
+ spin_lock_bh(&table->lock);
+ entry = VMCIHashTableGetEntryLocked(table, handle);
+ spin_unlock_bh(&table->lock);
+
+ return entry;
+}
+
+/*
+ *
+ *
+ * VMCIHashTable_HoldEntry --
+ *
+ * Hold the given entry. This will increment the entry's reference count.
+ * This is like a GetEntry() but without having to lookup the entry by
+ * handle.
+ *
+ * Result:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *
+ */
+
+void VMCIHashTable_HoldEntry(struct vmci_hash_table *table, // IN
+ struct vmci_hash_entry *entry) // IN/OUT
+{
+ ASSERT(table);
+ ASSERT(entry);
+
+ spin_lock_bh(&table->lock);
+ entry->refCount++;
+ spin_unlock_bh(&table->lock);
+}
+
+/*
+ *
+ *
+ * VMCIHashTableReleaseEntryLocked --
+ *
+ * Releases an element previously obtained with
+ * VMCIHashTableGetEntryLocked.
+ *
+ * Result:
+ * If the entry is removed from the hash table, VMCI_SUCCESS_ENTRY_DEAD
+ * is returned. Otherwise, VMCI_SUCCESS is returned.
+ *
+ * Side effects:
+ * The reference count of the entry is decreased and the entry is removed
+ * from the hash table on 0.
+ *
+ *
+ */
+
+static inline int VMCIHashTableReleaseEntryLocked(struct vmci_hash_table *table, // IN
+ struct vmci_hash_entry *entry) // IN
+{
+ int result = VMCI_SUCCESS;
+
+ ASSERT(table);
+ ASSERT(entry);
+
+ entry->refCount--;
+ /* Check if this is last reference and report if so. */
+ if (entry->refCount == 0) {
+
+ /*
+ * Remove entry from hash table if not already removed. This could have
+ * happened already because VMCIHashTable_RemoveEntry was called to unlink
+ * it. We ignore if it is not found. Datagram handles will often have
+ * RemoveEntry called, whereas SharedMemory regions rely on ReleaseEntry
+ * to unlink the entry, since the creator does not call RemoveEntry when
+ * it detaches.
+ */
+
+ HashTableUnlinkEntry(table, entry);
+ result = VMCI_SUCCESS_ENTRY_DEAD;
+ }
+
+ return result;
+}
+
+/*
+ *
+ *
+ * VMCIHashTable_ReleaseEntry --
+ * XXX Factor out the hashtable code to shared amongst API and perhaps
+ * host and guest.
+ *
+ * Result:
+ * None.
+ *
+ *
+ */
+
+int VMCIHashTable_ReleaseEntry(struct vmci_hash_table *table, // IN
+ struct vmci_hash_entry *entry) // IN
+{
+ int result;
+
+ ASSERT(table);
+ spin_lock_bh(&table->lock);
+ result = VMCIHashTableReleaseEntryLocked(table, entry);
+ spin_unlock_bh(&table->lock);
+
+ return result;
+}
+
+/*
+ *
+ *
+ * VMCIHashTable_EntryExists --
+ * XXX Factor out the hashtable code to shared amongst API and perhaps
+ * host and guest.
+ *
+ * Result:
+ * true if handle already in hashtable. false otherwise.
+ *
+ * Side effects:
+ * None.
+ *
+ *
+ */
+
+bool VMCIHashTable_EntryExists(struct vmci_hash_table * table, // IN
+ struct vmci_handle handle) // IN
+{
+ bool exists;
+
+ ASSERT(table);
+
+ spin_lock_bh(&table->lock);
+ exists = VMCIHashTableEntryExistsLocked(table, handle);
+ spin_unlock_bh(&table->lock);
+
+ return exists;
+}
+
+/*
+ *--
+ *
+ * VMCIHashTable_Sync --
+ *
+ * Use this as a synchronization point when setting globals, for example,
+ * during device shutdown.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *--
+ */
+
+void VMCIHashTable_Sync(struct vmci_hash_table *table)
+{
+ ASSERT(table);
+ spin_lock_bh(&table->lock);
+ spin_unlock_bh(&table->lock);
+}
diff --git a/drivers/misc/vmw_vmci/vmciHashtable.h b/drivers/misc/vmw_vmci/vmciHashtable.h
new file mode 100644
index 0000000..33d5503
/dev/null
+++ b/drivers/misc/vmw_vmci/vmciHashtable.h
@@ -0,0 +1,58 @@
+/*
+ *
+ * VMware VMCI Driver
+ *
+ * Copyright (C) 2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2 and no later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _VMCI_HASHTABLE_H_
+#define _VMCI_HASHTABLE_H_
+
+#include "vmci_defs.h"
+#include "vmci_kernel_if.h"
+
+struct vmci_hash_entry {
+ struct vmci_handle handle;
+ int refCount;
+ struct vmci_hash_entry *next;
+};
+
+struct vmci_hash_table {
+ struct vmci_hash_entry **entries;
+ int size; /* Number of buckets in above array. */
+ spinlock_t lock;
+};
+
+struct vmci_hash_table *VMCIHashTable_Create(int size);
+void VMCIHashTable_Destroy(struct vmci_hash_table *table);
+void VMCIHashTable_InitEntry(struct vmci_hash_entry *entry,
+ struct vmci_handle handle);
+int VMCIHashTable_AddEntry(struct vmci_hash_table *table,
+ struct vmci_hash_entry *entry);
+int VMCIHashTable_RemoveEntry(struct vmci_hash_table *table,
+ struct vmci_hash_entry *entry);
+struct vmci_hash_entry *VMCIHashTable_GetEntry(struct vmci_hash_table
+ *table,
+ struct vmci_handle handle);
+void VMCIHashTable_HoldEntry(struct vmci_hash_table *table,
+ struct vmci_hash_entry *entry);
+int VMCIHashTable_ReleaseEntry(struct vmci_hash_table *table,
+ struct vmci_hash_entry *entry);
+bool VMCIHashTable_EntryExists(struct vmci_hash_table *table,
+ struct vmci_handle handle);
+void VMCIHashTable_Sync(struct vmci_hash_table *table);
+
+#endif // _VMCI_HASHTABLE_H_
1.7.0.4

To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

Similar topics