Esempio n. 1
0
void
find_descendants__rx_handler(struct intermon_binding *b, intermon_caprep_t caprep, genvaddr_t st)
{
    errval_t err;

    struct intermon_state *inter_st = (struct intermon_state*)b->st;
    coreid_t from = inter_st->core_id;

    struct capability cap;
    caprep_to_capability(&caprep, &cap);

    bool has_descendants;
    err = monitor_has_descendants(&cap, &has_descendants);
    assert(err_is_ok(err));

    struct find_descendants_result_msg_st *msg_st;
    msg_st = malloc(sizeof(*msg_st));
    if (!msg_st) {
        err = LIB_ERR_MALLOC_FAIL;
        USER_PANIC_ERR(err, "could not alloc find_descendants_result_msg_st");
    }
    msg_st->queue_elem.cont = find_descendants_result_send_cont;
    msg_st->st = st;

    if (err_is_ok(err)) {
        err = has_descendants ? SYS_ERR_OK : SYS_ERR_CAP_NOT_FOUND;
    }
    msg_st->status = err;

    err = capsend_target(from, (struct msg_queue_elem*)msg_st);
    if (err_is_fail(err)) {
        USER_PANIC_ERR(err, "could not enqueue find_descendants_result msg");
    }
}
Esempio n. 2
0
static void
capsend_mc_send_cont(struct intermon_binding *b, struct intermon_msg_queue_elem *e)
{
    struct capsend_mc_msg_st *msg_st = (struct capsend_mc_msg_st*)e;
    struct capsend_mc_st *mc_st = msg_st->mc_st;
    errval_t err = SYS_ERR_OK;

    // if do_send is false, an error occured in the multicast setup, so do not
    // send anything
    if (mc_st->do_send) {
        err = mc_st->send_fn(b, &mc_st->caprep, mc_st);
    }

    if (err_no(err) == FLOUNDER_ERR_TX_BUSY) {
        err = capsend_target(msg_st->dest, (struct msg_queue_elem*)msg_st);
    }

    if (err_is_fail(err)) {
        USER_PANIC_ERR(err, "sending dequeued capops message");
    }

    // decrement counter of number of queued messages
    if (!--mc_st->num_queued) {
        // if counter is zero, cleanup outgoing memory
        free(mc_st->msg_st_arr);
        mc_st->msg_st_arr = NULL;
        if (!mc_st->do_send || !mc_st->num_pending) {
            // if the send has been aborted, also cleanup cross-call state
            free(mc_st);
        }
    }
}
Esempio n. 3
0
static void
retrieve_result__enq(errval_t status, struct retrieve_response_st *st)
{
    errval_t err;
    st->status = status;
    st->iqn.cont = retrieve_result__send;

    err = capsend_target(st->from, (struct msg_queue_elem*)st);
    PANIC_IF_ERR(err, "enqueing retrieve result");
}
Esempio n. 4
0
static void
revoke_slave_steps__fin(void *st)
{
    errval_t err;
    struct revoke_slave_st *rvk_st = (struct revoke_slave_st*)st;

    rvk_st->im_qn.cont = revoke_done__send;
    err = capsend_target(rvk_st->from, (struct msg_queue_elem*)rvk_st);
    PANIC_IF_ERR(err, "enqueueing revoke_done");
}
Esempio n. 5
0
errval_t
capsend_owner(struct domcapref capref, struct msg_queue_elem *queue_elem)
{
    errval_t err;

    // read cap owner
    coreid_t owner;
    err = monitor_get_domcap_owner(capref, &owner);
    if (err_is_fail(err)) {
        return err;
    }

    // enqueue to owner
    return capsend_target(owner, queue_elem);
}
Esempio n. 6
0
void
revoke_mark__rx(struct intermon_binding *b,
                intermon_caprep_t caprep,
                genvaddr_t st)
{
    DEBUG_CAPOPS("%s\n", __FUNCTION__);
    errval_t err;
    struct intermon_state *inter_st = (struct intermon_state*)b->st;

    struct revoke_slave_st *rvk_st;
    err = calloce(1, sizeof(*rvk_st), &rvk_st);
    PANIC_IF_ERR(err, "allocating revoke slave state");

    rvk_st->from = inter_st->core_id;
    rvk_st->st = st;
    caprep_to_capability(&caprep, &rvk_st->rawcap);

    if (!slaves_head) {
        assert(!slaves_tail);
        slaves_head = slaves_tail = rvk_st;
    }
    else {
        assert(slaves_tail);
        assert(!slaves_tail->next);
        slaves_tail->next = rvk_st;
        slaves_tail = rvk_st;
    }

    // pause any ongoing "delete stepping" as mark phases on other nodes need
    // to delete all foreign copies before we can delete locally owned caps
    delete_steps_pause();

    // XXX: this invocation could create a scheduling hole that could be
    // problematic in RT systems and should probably be done in a loop.
    err = monitor_revoke_mark_relations(&rvk_st->rawcap);
    if (err_no(err) == SYS_ERR_CAP_NOT_FOUND) {
        // found no copies or descendants of capability on this core,
        // do nothing. -SG
        DEBUG_CAPOPS("no copies on core %d\n", disp_get_core_id());
    } else if (err_is_fail(err)) {
        USER_PANIC_ERR(err, "marking revoke");
    }

    rvk_st->im_qn.cont = revoke_ready__send;
    err = capsend_target(rvk_st->from, (struct msg_queue_elem*)rvk_st);
    PANIC_IF_ERR(err, "enqueing revoke_ready");
}
Esempio n. 7
0
static errval_t
owner_updated(coreid_t owner, genvaddr_t st)
{
    errval_t err;
    struct owner_updated_msg_st *msg_st = calloc(1, sizeof(struct owner_updated_msg_st));
    if (!msg_st) {
        return LIB_ERR_MALLOC_FAIL;
    }
    msg_st->queue_elem.cont = owner_updated_send_cont;
    msg_st->st = st;

    err = capsend_target(owner, (struct msg_queue_elem*)msg_st);
    if (err_is_fail(err)) {
        free(msg_st);
    }

    return err;
}
Esempio n. 8
0
static errval_t
find_cap_result(coreid_t dest, errval_t result, genvaddr_t st)
{
    errval_t err;
    struct find_cap_result_msg_st *msg_st = calloc(1, sizeof(struct find_cap_result_msg_st));
    if (!msg_st) {
        return LIB_ERR_MALLOC_FAIL;
    }
    msg_st->queue_elem.cont = find_cap_result_send_cont;
    msg_st->result = result;
    msg_st->st = st;

    err = capsend_target(dest, (struct msg_queue_elem*)msg_st);
    if (err_is_fail(err)) {
        free(msg_st);
    }

    return err;
}
Esempio n. 9
0
static errval_t
capsend_mc_enqueue(struct capsend_mc_st *mc_st, coreid_t dest)
{
    errval_t err;

    // get next msg_st
    struct capsend_mc_msg_st *msg_st = &mc_st->msg_st_arr[mc_st->num_queued];
    msg_st->queue_elem.cont = capsend_mc_send_cont;
    msg_st->mc_st = mc_st;
    msg_st->dest = dest;

    err = capsend_target(dest, (struct msg_queue_elem*)msg_st);
    if (err_is_ok(err)) {
        // count successful enqueue
        mc_st->num_queued++;
        if (mc_st->num_pending >= 0) {
            // also track number of pending exchanges if requested
            mc_st->num_pending++;
        }
    }
    return err;
}