Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rlmenge/new callback api rebase #1085

Draft
wants to merge 2 commits into
base: rust-next
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 52 additions & 5 deletions drivers/hv/channel.c
Original file line number Diff line number Diff line change
Expand Up @@ -632,8 +632,8 @@ static void vmbus_free_requestor(struct vmbus_requestor *rqstor)
}

static int __vmbus_open(struct vmbus_channel *newchannel,
void *userdata, u32 userdatalen,
void (*onchannelcallback)(void *context), void *context)
void *userdata, u32 userdatalen, bool channelapiv1,
void *onchannelcallback, void *context)
{
struct vmbus_channel_open_channel *open_msg;
struct vmbus_channel_msginfo *open_info = NULL;
Expand All @@ -658,7 +658,15 @@ static int __vmbus_open(struct vmbus_channel *newchannel,
}

newchannel->state = CHANNEL_OPENING_STATE;
newchannel->onchannel_callback = onchannelcallback;

if (channelapiv1) {
newchannel->onchannel_callback = NULL;
newchannel->onchannel_callback_v1 = onchannelcallback;
} else {
newchannel->onchannel_callback = onchannelcallback;
newchannel->onchannel_callback_v1 = NULL;
}

newchannel->channel_callback_context = context;

if (!newchannel->max_pkt_size)
Expand Down Expand Up @@ -775,10 +783,22 @@ static int __vmbus_open(struct vmbus_channel *newchannel,
int vmbus_connect_ring(struct vmbus_channel *newchannel,
void (*onchannelcallback)(void *context), void *context)
{
return __vmbus_open(newchannel, NULL, 0, onchannelcallback, context);
bool channelapiv1 = true;
return __vmbus_open(newchannel, NULL, 0, channelapiv1, onchannelcallback, context);
}
EXPORT_SYMBOL_GPL(vmbus_connect_ring);

/*
* vmbus_connect_ring - Open the channel but reuse ring buffer
*/
int vmbus_connect_ring_channel(struct vmbus_channel *newchannel,
onchannel_t *onchannelcallback, void *context)
{
bool channelapiv1 = false;
return __vmbus_open(newchannel, NULL, 0, channelapiv1, onchannelcallback, context);
}
EXPORT_SYMBOL_GPL(vmbus_connect_ring_channel);

/*
* vmbus_open - Open the specified channel.
*/
Expand All @@ -788,21 +808,47 @@ int vmbus_open(struct vmbus_channel *newchannel,
void (*onchannelcallback)(void *context), void *context)
{
int err;
bool channelapiv1 = true;

err = vmbus_alloc_ring(newchannel, send_ringbuffer_size,
recv_ringbuffer_size);
if (err)
return err;

err = __vmbus_open(newchannel, userdata, userdatalen,
onchannelcallback, context);
channelapiv1, onchannelcallback, context);
if (err)
vmbus_free_ring(newchannel);

return err;
}
EXPORT_SYMBOL_GPL(vmbus_open);

/*
* vmbus_open - Open the specified channel.
*/
int vmbus_open_channel(struct vmbus_channel *newchannel,
u32 send_ringbuffer_size, u32 recv_ringbuffer_size,
void *userdata, u32 userdatalen,
onchannel_t *onchannelcallback, void *context)
{
int err;
bool channelapiv1 = false;

err = vmbus_alloc_ring(newchannel, send_ringbuffer_size,
recv_ringbuffer_size);
if (err)
return err;

err = __vmbus_open(newchannel, userdata, userdatalen,
channelapiv1, onchannelcallback, context);
if (err)
vmbus_free_ring(newchannel);

return err;
}
EXPORT_SYMBOL_GPL(vmbus_open_channel);

/*
* vmbus_teardown_gpadl -Teardown the specified GPADL handle
*/
Expand Down Expand Up @@ -895,6 +941,7 @@ void vmbus_reset_channel_cb(struct vmbus_channel *channel)
/* See the inline comments in vmbus_chan_sched(). */
spin_lock_irqsave(&channel->sched_lock, flags);
channel->onchannel_callback = NULL;
channel->onchannel_callback_v1 = NULL;
spin_unlock_irqrestore(&channel->sched_lock, flags);

channel->sc_creation_callback = NULL;
Expand Down
17 changes: 11 additions & 6 deletions drivers/hv/connection.c
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,8 @@ struct vmbus_channel *relid2channel(u32 relid)
void vmbus_on_event(unsigned long data)
{
struct vmbus_channel *channel = (void *) data;
void (*callback_fn)(void *context);
void (*callback_fn_v1)(void *context);
onchannel_t *callback_fn;

trace_vmbus_on_event(channel);

Expand All @@ -403,12 +404,16 @@ void vmbus_on_event(unsigned long data)
* there is no driver handling the device. An
* unloading driver sets the onchannel_callback to NULL.
*/
callback_fn = READ_ONCE(channel->onchannel_callback);
if (unlikely(!callback_fn))
if (channel->onchannel_callback_v1 != NULL) {
callback_fn_v1 = READ_ONCE(channel->onchannel_callback_v1);
(*callback_fn_v1)(channel->channel_callback_context);
} else if (channel->onchannel_callback != NULL) {
callback_fn = READ_ONCE(channel->onchannel_callback);
(*callback_fn)(channel->channel_callback_context, channel);
} else {
return;

(*callback_fn)(channel->channel_callback_context);

}

if (channel->callback_mode != HV_CALL_BATCHED)
return;

Expand Down
6 changes: 3 additions & 3 deletions drivers/hv/hv_balloon.c
Original file line number Diff line number Diff line change
Expand Up @@ -1407,7 +1407,7 @@ static void balloon_down(struct hv_dynmem_device *dm,
dm->state = DM_INITIALIZED;
}

static void balloon_onchannelcallback(void *context);
static void balloon_onchannelcallback(void *context, struct vmbus_channel *chan);

static int dm_thread_func(void *dm_dev)
{
Expand Down Expand Up @@ -1511,7 +1511,7 @@ static void cap_resp(struct hv_dynmem_device *dm,
complete(&dm->host_event);
}

static void balloon_onchannelcallback(void *context)
static void balloon_onchannelcallback(void *context, struct vmbus_channel *chan)
{
struct hv_device *dev = context;
u32 recvlen;
Expand Down Expand Up @@ -1770,7 +1770,7 @@ static int balloon_connect_vsp(struct hv_device *dev)
*/
dev->channel->max_pkt_size = HV_HYP_PAGE_SIZE * 2;

ret = vmbus_open(dev->channel, dm_ring_size, dm_ring_size, NULL, 0,
ret = vmbus_open_channel(dev->channel, dm_ring_size, dm_ring_size, NULL, 0,
balloon_onchannelcallback, dev);
if (ret)
return ret;
Expand Down
2 changes: 1 addition & 1 deletion drivers/hv/hv_kvp.c
Original file line number Diff line number Diff line change
Expand Up @@ -632,7 +632,7 @@ kvp_respond_to_host(struct hv_kvp_msg *msg_to_host, int error)
* we stash away the transaction state in a set of global variables.
*/

void hv_kvp_onchannelcallback(void *context)
void hv_kvp_onchannelcallback(void *context, struct vmbus_channel *chan)
{
struct vmbus_channel *channel = context;
u32 recvlen;
Expand Down
2 changes: 1 addition & 1 deletion drivers/hv/hv_snapshot.c
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ vss_respond_to_host(int error)
* The host ensures that only one VSS transaction can be active at a time.
*/

void hv_vss_onchannelcallback(void *context)
void hv_vss_onchannelcallback(void *context, struct vmbus_channel *chan)
{
struct vmbus_channel *channel = context;
u32 recvlen;
Expand Down
19 changes: 11 additions & 8 deletions drivers/hv/hv_util.c
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,8 @@ static int hv_shutdown_init(struct hv_util_service *srv)
return 0;
}

static void shutdown_onchannelcallback(void *context);
static void shutdown_onchannelcallback(void *context,
struct vmbus_channel *chan);
static struct hv_util_service util_shutdown = {
.util_cb = shutdown_onchannelcallback,
.util_init = hv_shutdown_init,
Expand All @@ -125,15 +126,17 @@ static int hv_timesync_init(struct hv_util_service *srv);
static int hv_timesync_pre_suspend(void);
static void hv_timesync_deinit(void);

static void timesync_onchannelcallback(void *context);
static void timesync_onchannelcallback(void *context,
struct vmbus_channel *chan);
static struct hv_util_service util_timesynch = {
.util_cb = timesync_onchannelcallback,
.util_init = hv_timesync_init,
.util_pre_suspend = hv_timesync_pre_suspend,
.util_deinit = hv_timesync_deinit,
};

static void heartbeat_onchannelcallback(void *context);
static void heartbeat_onchannelcallback(void *context,
struct vmbus_channel *chan);
static struct hv_util_service util_heartbeat = {
.util_cb = heartbeat_onchannelcallback,
};
Expand Down Expand Up @@ -174,7 +177,7 @@ static DECLARE_WORK(shutdown_work, perform_shutdown);
*/
static DECLARE_WORK(restart_work, perform_restart);

static void shutdown_onchannelcallback(void *context)
static void shutdown_onchannelcallback(void *context, struct vmbus_channel *chan)
{
struct vmbus_channel *channel = context;
struct work_struct *work = NULL;
Expand Down Expand Up @@ -412,7 +415,7 @@ static inline void adj_guesttime(u64 hosttime, u64 reftime, u8 adj_flags)
/*
* Time Sync Channel message handler.
*/
static void timesync_onchannelcallback(void *context)
static void timesync_onchannelcallback(void *context, struct vmbus_channel *chan)
{
struct vmbus_channel *channel = context;
u32 recvlen;
Expand Down Expand Up @@ -505,7 +508,7 @@ static void timesync_onchannelcallback(void *context)
* Every two seconds, Hyper-V send us a heartbeat request message.
* we respond to this message, and Hyper-V knows we are alive.
*/
static void heartbeat_onchannelcallback(void *context)
static void heartbeat_onchannelcallback(void *context, struct vmbus_channel *chan)
{
struct vmbus_channel *channel = context;
u32 recvlen;
Expand Down Expand Up @@ -607,7 +610,7 @@ static int util_probe(struct hv_device *dev,

hv_set_drvdata(dev, srv);

ret = vmbus_open(dev->channel, HV_UTIL_RING_SEND_SIZE,
ret = vmbus_open_channel(dev->channel, HV_UTIL_RING_SEND_SIZE,
HV_UTIL_RING_RECV_SIZE, NULL, 0, srv->util_cb,
dev->channel);
if (ret)
Expand Down Expand Up @@ -665,7 +668,7 @@ static int util_resume(struct hv_device *dev)
return ret;
}

ret = vmbus_open(dev->channel, HV_UTIL_RING_SEND_SIZE,
ret = vmbus_open_channel(dev->channel, HV_UTIL_RING_SEND_SIZE,
HV_UTIL_RING_RECV_SIZE, NULL, 0, srv->util_cb,
dev->channel);
return ret;
Expand Down
6 changes: 3 additions & 3 deletions drivers/hv/hyperv_vmbus.h
Original file line number Diff line number Diff line change
Expand Up @@ -373,19 +373,19 @@ int hv_kvp_init(struct hv_util_service *srv);
void hv_kvp_deinit(void);
int hv_kvp_pre_suspend(void);
int hv_kvp_pre_resume(void);
void hv_kvp_onchannelcallback(void *context);
onchannel_t hv_kvp_onchannelcallback;

int hv_vss_init(struct hv_util_service *srv);
void hv_vss_deinit(void);
int hv_vss_pre_suspend(void);
int hv_vss_pre_resume(void);
void hv_vss_onchannelcallback(void *context);
onchannel_t hv_vss_onchannelcallback;

int hv_fcopy_init(struct hv_util_service *srv);
void hv_fcopy_deinit(void);
int hv_fcopy_pre_suspend(void);
int hv_fcopy_pre_resume(void);
void hv_fcopy_onchannelcallback(void *context);
onchannel_t hv_fcopy_onchannelcallback;
void vmbus_initiate_unload(bool crash);

static inline void hv_poll_channel(struct vmbus_channel *channel,
Expand Down
19 changes: 15 additions & 4 deletions drivers/hv/vmbus_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -1214,7 +1214,8 @@ static void vmbus_chan_sched(struct hv_per_cpu_context *hv_cpu)
return;

for_each_set_bit(relid, recv_int_page, maxbits) {
void (*callback_fn)(void *context);
void (*callback_fn_v1)(void *context);
onchannel_t *callback_fn;
struct vmbus_channel *channel;

if (!sync_test_and_clear_bit(relid, recv_int_page))
Expand Down Expand Up @@ -1249,17 +1250,27 @@ static void vmbus_chan_sched(struct hv_per_cpu_context *hv_cpu)
*/
spin_lock(&channel->sched_lock);

callback_fn = channel->onchannel_callback;
if (unlikely(callback_fn == NULL))
bool channelapiv1 = false;
if (channel->onchannel_callback_v1 != NULL) {
callback_fn_v1 = channel->onchannel_callback_v1;
} else if (channel->onchannel_callback != NULL) {
callback_fn =channel->onchannel_callback;
channelapiv1 = true;
} else {
goto sched_unlock;
}

trace_vmbus_chan_sched(channel);

++channel->interrupts;

switch (channel->callback_mode) {
case HV_CALL_ISR:
(*callback_fn)(channel->channel_callback_context);
if (channelapiv1) {
(*callback_fn_v1)(channel->channel_callback_context);
} else {
(*callback_fn)(channel->channel_callback_context, channel);
}
break;

case HV_CALL_BATCHED:
Expand Down
18 changes: 16 additions & 2 deletions include/linux/hyperv.h
Original file line number Diff line number Diff line change
Expand Up @@ -837,6 +837,8 @@ struct vmbus_gpadl {
bool decrypted;
};

typedef void onchannel_t(void *context, struct vmbus_channel *chan);

struct vmbus_channel {
struct list_head listentry;

Expand Down Expand Up @@ -886,7 +888,8 @@ struct vmbus_channel {

/* Channel callback's invoked in softirq context */
struct tasklet_struct callback_event;
void (*onchannel_callback)(void *context);
void (*onchannel_callback_v1)(void *context);
onchannel_t *onchannel_callback;
void *channel_callback_context;

void (*change_target_cpu_callback)(struct vmbus_channel *channel,
Expand Down Expand Up @@ -1200,6 +1203,9 @@ void vmbus_free_ring(struct vmbus_channel *channel);
int vmbus_connect_ring(struct vmbus_channel *channel,
void (*onchannel_callback)(void *context),
void *context);
int vmbus_connect_ring_channel(struct vmbus_channel *channel,
onchannel_t *onchannel_callback,
void *context);
int vmbus_disconnect_ring(struct vmbus_channel *channel);

extern int vmbus_open(struct vmbus_channel *channel,
Expand All @@ -1210,6 +1216,14 @@ extern int vmbus_open(struct vmbus_channel *channel,
void (*onchannel_callback)(void *context),
void *context);

extern int vmbus_open_channel(struct vmbus_channel *channel,
u32 send_ringbuffersize,
u32 recv_ringbuffersize,
void *userdata,
u32 userdatalen,
onchannel_t *onchannelcallback,
void *context);

extern void vmbus_close(struct vmbus_channel *channel);

extern int vmbus_sendpacket_getid(struct vmbus_channel *channel,
Expand Down Expand Up @@ -1561,7 +1575,7 @@ void vmbus_free_mmio(resource_size_t start, resource_size_t size);
struct hv_util_service {
u8 *recv_buffer;
void *channel;
void (*util_cb)(void *);
onchannel_t *util_cb;
int (*util_init)(struct hv_util_service *);
void (*util_deinit)(void);
int (*util_pre_suspend)(void);
Expand Down