Ignore:
Timestamp:
2018-03-15T17:40:20Z (7 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
530f2de, e9e4068
Parents:
30f1a25 (diff), a36f442 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
git-author:
Jakub Jermar <jakub@…> (2018-03-15 17:25:56)
git-committer:
Jakub Jermar <jakub@…> (2018-03-15 17:40:20)
Message:

Merge branch 'noreclaimers'

This commit removes the left-over from the original IPC phone life-cycle
management in which phones were freed lazily during an attempt to
allocate a new phone when the allocator found a hung-up phone with zero
active calls. This mechanism is the reason why kernel objects had to
have the reclaim method. This commit changes the behavior in that phones
are deallocated with their last reference. At the same time it makes
sure that each active call has its own reference on the phone.

This change also makes sure that each connected phone has a capability
via which it can be hung up by the user or cleaned up in ipc_cleanup().
A special mode for phone_alloc() was introduced that allows calls such
as IPC_M_CONNECT_ME_TO and IPC_M_CONNECT_TO_ME to allocate an
unpublished capability and publish it only when the phone is
successfully connected. This fixes a nasty race condition when the user
destroys the capability before the phone is connected and then this
phone becomes essentially invisible for ipc_cleanup().

Last but not least, ipc_cleanup() was slightly streamlined in that it
now knows for how many calls it has to wait from the answerbox's active
call count.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/src/ipc/ops/conctmeto.c

    r30f1a25 r67f11a0  
    4242static errno_t request_preprocess(call_t *call, phone_t *phone)
    4343{
     44        /*
     45         * Create the new phone and capability, but don't publish them yet.
     46         * That will be done once the phone is connected.
     47         */
    4448        cap_handle_t phone_handle;
    45         errno_t rc = phone_alloc(TASK, &phone_handle);
    46 
    47         /* Remember the phone capability or that an error occured. */
    48         call->priv = (rc == EOK) ? phone_handle : -1;
    49 
     49        kobject_t *phone_obj;
     50        errno_t rc = phone_alloc(TASK, false, &phone_handle, &phone_obj);
    5051        if (rc != EOK) {
     52                call->priv = -1;
    5153                return rc;
    5254        }
    5355
    54         /* Set arg5 for server */
    55         kobject_t *phone_obj = kobject_get(TASK, phone_handle,
    56             KOBJECT_TYPE_PHONE);
    5756        /* Hand over phone_obj's reference to ARG5 */
    5857        IPC_SET_ARG5(call->data, (sysarg_t) phone_obj->phone);
     58
     59        /* Remember the handle */
     60        call->priv = phone_handle;
    5961
    6062        return EOK;
     
    6567        cap_handle_t phone_handle = (cap_handle_t) call->priv;
    6668
    67         if (phone_handle < 0) {
     69        if (phone_handle < 0)
    6870                return EOK;
    69         }
    7071
    71         phone_dealloc(phone_handle);
    7272        /* Hand over reference from ARG5 to phone->kobject */
    7373        phone_t *phone = (phone_t *) IPC_GET_ARG5(call->data);
    74         /* Drop phone_obj's reference */
     74        /* Drop phone->kobject's reference */
    7575        kobject_put(phone->kobject);
     76        cap_free(TASK, phone_handle);
     77
    7678        return EOK;
    7779}
     
    8284        phone_t *phone = (phone_t *) IPC_GET_ARG5(*olddata);
    8385
    84         /* If the user accepted call, connect */
     86        /*
     87         * Get an extra reference and pass it in the answer data.
     88         */
     89        kobject_add_ref(phone->kobject);
     90        IPC_SET_ARG5(answer->data, (sysarg_t) phone);
     91
     92        /* If the user accepted the call, connect */
    8593        if (IPC_GET_RETVAL(answer->data) == EOK) {
    8694                /* Hand over reference from phone to the answerbox */
     
    96104{
    97105        cap_handle_t phone_handle = (cap_handle_t) answer->priv;
     106        phone_t *phone = (phone_t *) IPC_GET_ARG5(answer->data);
    98107
    99108        if (IPC_GET_RETVAL(answer->data)) {
    100109                if (phone_handle >= 0) {
    101110                        /*
    102                          * The phone was indeed allocated and now needs
    103                          * to be deallocated.
     111                         * Cleanup the unpublished capability and drop
     112                         * phone->kobject's reference.
    104113                         */
    105                         phone_dealloc(phone_handle);
     114                        kobject_put(phone->kobject);
     115                        cap_free(TASK, phone_handle);
    106116                }
    107117        } else {
     118                /*
     119                 * Publish the capability. Publishing the capability this late
     120                 * is important for ipc_cleanup() where we want to have a
     121                 * capability for each phone that wasn't hung up by the user.
     122                 */
     123                cap_publish(TASK, phone_handle, phone->kobject);
     124
    108125                IPC_SET_ARG5(answer->data, phone_handle);
    109126        }
Note: See TracChangeset for help on using the changeset viewer.