lkml.org 
[lkml]   [2019]   [Nov]   [4]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    Date
    From
    SubjectRe: [PATCH net-next 12/14] vsock/vmci: register vmci_transport only when VMCI guest/host are active
    Hi Jorgen,
    I'm preparing the v2, but first, if you have time, I'd like to have
    a comment from you on this patch that modifies a bit vmci.

    Thank you very much,
    Stefano

    On Wed, Oct 23, 2019 at 11:55:52AM +0200, Stefano Garzarella wrote:
    > To allow other transports to be loaded with vmci_transport,
    > we register the vmci_transport as G2H or H2G only when a VMCI guest
    > or host is active.
    >
    > To do that, this patch adds a callback registered in the vmci driver
    > that will be called when a new host or guest become active.
    > This callback will register the vmci_transport in the VSOCK core.
    > If the transport is already registered, we ignore the error coming
    > from vsock_core_register().
    >
    > Cc: Jorgen Hansen <jhansen@vmware.com>
    > Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
    > ---
    > drivers/misc/vmw_vmci/vmci_driver.c | 50 +++++++++++++++++++++++++++++
    > drivers/misc/vmw_vmci/vmci_driver.h | 2 ++
    > drivers/misc/vmw_vmci/vmci_guest.c | 2 ++
    > drivers/misc/vmw_vmci/vmci_host.c | 7 ++++
    > include/linux/vmw_vmci_api.h | 2 ++
    > net/vmw_vsock/vmci_transport.c | 29 +++++++++++------
    > 6 files changed, 82 insertions(+), 10 deletions(-)
    >
    > diff --git a/drivers/misc/vmw_vmci/vmci_driver.c b/drivers/misc/vmw_vmci/vmci_driver.c
    > index 819e35995d32..195afbd7edc1 100644
    > --- a/drivers/misc/vmw_vmci/vmci_driver.c
    > +++ b/drivers/misc/vmw_vmci/vmci_driver.c
    > @@ -28,6 +28,9 @@ MODULE_PARM_DESC(disable_guest,
    > static bool vmci_guest_personality_initialized;
    > static bool vmci_host_personality_initialized;
    >
    > +static DEFINE_MUTEX(vmci_vsock_mutex); /* protects vmci_vsock_transport_cb */
    > +static vmci_vsock_cb vmci_vsock_transport_cb;
    > +
    > /*
    > * vmci_get_context_id() - Gets the current context ID.
    > *
    > @@ -45,6 +48,53 @@ u32 vmci_get_context_id(void)
    > }
    > EXPORT_SYMBOL_GPL(vmci_get_context_id);
    >
    > +/*
    > + * vmci_register_vsock_callback() - Register the VSOCK vmci_transport callback.
    > + *
    > + * The callback will be called every time a new host or guest become active,
    > + * or if they are already active when this function is called.
    > + * To unregister the callback, call this function with NULL parameter.
    > + *
    > + * Returns 0 on success. -EBUSY if a callback is already registered.
    > + */
    > +int vmci_register_vsock_callback(vmci_vsock_cb callback)
    > +{
    > + int err = 0;
    > +
    > + mutex_lock(&vmci_vsock_mutex);
    > +
    > + if (vmci_vsock_transport_cb && callback) {
    > + err = -EBUSY;
    > + goto out;
    > + }
    > +
    > + vmci_vsock_transport_cb = callback;
    > +
    > + if (!vmci_vsock_transport_cb)
    > + goto out;
    > +
    > + if (vmci_guest_code_active())
    > + vmci_vsock_transport_cb(false);
    > +
    > + if (vmci_host_users() > 0)
    > + vmci_vsock_transport_cb(true);
    > +
    > +out:
    > + mutex_unlock(&vmci_vsock_mutex);
    > + return err;
    > +}
    > +EXPORT_SYMBOL_GPL(vmci_register_vsock_callback);
    > +
    > +void vmci_call_vsock_callback(bool is_host)
    > +{
    > + mutex_lock(&vmci_vsock_mutex);
    > +
    > + if (vmci_vsock_transport_cb)
    > + vmci_vsock_transport_cb(is_host);
    > +
    > + mutex_unlock(&vmci_vsock_mutex);
    > +}
    > +
    > static int __init vmci_drv_init(void)
    > {
    > int vmci_err;
    > diff --git a/drivers/misc/vmw_vmci/vmci_driver.h b/drivers/misc/vmw_vmci/vmci_driver.h
    > index aab81b67670c..990682480bf6 100644
    > --- a/drivers/misc/vmw_vmci/vmci_driver.h
    > +++ b/drivers/misc/vmw_vmci/vmci_driver.h
    > @@ -36,10 +36,12 @@ extern struct pci_dev *vmci_pdev;
    >
    > u32 vmci_get_context_id(void);
    > int vmci_send_datagram(struct vmci_datagram *dg);
    > +void vmci_call_vsock_callback(bool is_host);
    >
    > int vmci_host_init(void);
    > void vmci_host_exit(void);
    > bool vmci_host_code_active(void);
    > +int vmci_host_users(void);
    >
    > int vmci_guest_init(void);
    > void vmci_guest_exit(void);
    > diff --git a/drivers/misc/vmw_vmci/vmci_guest.c b/drivers/misc/vmw_vmci/vmci_guest.c
    > index 7a84a48c75da..cc8eeb361fcd 100644
    > --- a/drivers/misc/vmw_vmci/vmci_guest.c
    > +++ b/drivers/misc/vmw_vmci/vmci_guest.c
    > @@ -637,6 +637,8 @@ static int vmci_guest_probe_device(struct pci_dev *pdev,
    > vmci_dev->iobase + VMCI_CONTROL_ADDR);
    >
    > pci_set_drvdata(pdev, vmci_dev);
    > +
    > + vmci_call_vsock_callback(false);
    > return 0;
    >
    > err_free_irq:
    > diff --git a/drivers/misc/vmw_vmci/vmci_host.c b/drivers/misc/vmw_vmci/vmci_host.c
    > index 833e2bd248a5..ff3c396146ff 100644
    > --- a/drivers/misc/vmw_vmci/vmci_host.c
    > +++ b/drivers/misc/vmw_vmci/vmci_host.c
    > @@ -108,6 +108,11 @@ bool vmci_host_code_active(void)
    > atomic_read(&vmci_host_active_users) > 0);
    > }
    >
    > +int vmci_host_users(void)
    > +{
    > + return atomic_read(&vmci_host_active_users);
    > +}
    > +
    > /*
    > * Called on open of /dev/vmci.
    > */
    > @@ -338,6 +343,8 @@ static int vmci_host_do_init_context(struct vmci_host_dev *vmci_host_dev,
    > vmci_host_dev->ct_type = VMCIOBJ_CONTEXT;
    > atomic_inc(&vmci_host_active_users);
    >
    > + vmci_call_vsock_callback(true);
    > +
    > retval = 0;
    >
    > out:
    > diff --git a/include/linux/vmw_vmci_api.h b/include/linux/vmw_vmci_api.h
    > index acd9fafe4fc6..f28907345c80 100644
    > --- a/include/linux/vmw_vmci_api.h
    > +++ b/include/linux/vmw_vmci_api.h
    > @@ -19,6 +19,7 @@
    > struct msghdr;
    > typedef void (vmci_device_shutdown_fn) (void *device_registration,
    > void *user_data);
    > +typedef void (*vmci_vsock_cb) (bool is_host);
    >
    > int vmci_datagram_create_handle(u32 resource_id, u32 flags,
    > vmci_datagram_recv_cb recv_cb,
    > @@ -37,6 +38,7 @@ int vmci_doorbell_destroy(struct vmci_handle handle);
    > int vmci_doorbell_notify(struct vmci_handle handle, u32 priv_flags);
    > u32 vmci_get_context_id(void);
    > bool vmci_is_context_owner(u32 context_id, kuid_t uid);
    > +int vmci_register_vsock_callback(vmci_vsock_cb callback);
    >
    > int vmci_event_subscribe(u32 event,
    > vmci_event_cb callback, void *callback_data,
    > diff --git a/net/vmw_vsock/vmci_transport.c b/net/vmw_vsock/vmci_transport.c
    > index 2eb3f16d53e7..04437f822d82 100644
    > --- a/net/vmw_vsock/vmci_transport.c
    > +++ b/net/vmw_vsock/vmci_transport.c
    > @@ -2053,19 +2053,22 @@ static bool vmci_check_transport(struct vsock_sock *vsk)
    > return vsk->transport == &vmci_transport;
    > }
    >
    > -static int __init vmci_transport_init(void)
    > +void vmci_vsock_transport_cb(bool is_host)
    > {
    > - int features = VSOCK_TRANSPORT_F_DGRAM | VSOCK_TRANSPORT_F_H2G;
    > - int cid;
    > - int err;
    > + int features;
    >
    > - cid = vmci_get_context_id();
    > + if (is_host)
    > + features = VSOCK_TRANSPORT_F_H2G;
    > + else
    > + features = VSOCK_TRANSPORT_F_G2H;
    >
    > - if (cid == VMCI_INVALID_ID)
    > - return -EINVAL;
    > + vsock_core_register(&vmci_transport, features);
    > +}
    >
    > - if (cid != VMCI_HOST_CONTEXT_ID)
    > - features |= VSOCK_TRANSPORT_F_G2H;
    > +static int __init vmci_transport_init(void)
    > +{
    > + int features = VSOCK_TRANSPORT_F_DGRAM;
    > + int err;
    >
    > /* Create the datagram handle that we will use to send and receive all
    > * VSocket control messages for this context.
    > @@ -2079,7 +2082,6 @@ static int __init vmci_transport_init(void)
    > pr_err("Unable to create datagram handle. (%d)\n", err);
    > return vmci_transport_error_to_vsock_error(err);
    > }
    > -
    > err = vmci_event_subscribe(VMCI_EVENT_QP_RESUMED,
    > vmci_transport_qp_resumed_cb,
    > NULL, &vmci_transport_qp_resumed_sub_id);
    > @@ -2094,8 +2096,14 @@ static int __init vmci_transport_init(void)
    > if (err < 0)
    > goto err_unsubscribe;
    >
    > + err = vmci_register_vsock_callback(vmci_vsock_transport_cb);
    > + if (err < 0)
    > + goto err_unregister;
    > +
    > return 0;
    >
    > +err_unregister:
    > + vsock_core_unregister(&vmci_transport);
    > err_unsubscribe:
    > vmci_event_unsubscribe(vmci_transport_qp_resumed_sub_id);
    > err_destroy_stream_handle:
    > @@ -2121,6 +2129,7 @@ static void __exit vmci_transport_exit(void)
    > vmci_transport_qp_resumed_sub_id = VMCI_INVALID_ID;
    > }
    >
    > + vmci_register_vsock_callback(NULL);
    > vsock_core_unregister(&vmci_transport);
    > }
    > module_exit(vmci_transport_exit);
    > --
    > 2.21.0
    >

    --

    \
     
     \ /
      Last update: 2019-11-04 11:11    [W:5.568 / U:0.032 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site