Changeset 6769005 in mainline for kernel


Ignore:
Timestamp:
2018-10-31T06:03:38Z (7 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
53ee7a0
Parents:
94ab1fee
git-author:
Jakub Jermar <jakub@…> (2018-10-28 12:42:35)
git-committer:
Jakub Jermar <jakub@…> (2018-10-31 06:03:38)
Message:

Use user-defined labels instead of phone hashes

This commit changes the way how the async framework maps incomming calls
to connections. Instead of abusing the kernel addresses of attached
phones as identifiers, the IPC_M_CONNECT_TO_ME and IPC_M_CONNECT_ME_TO
messages allow the server to specify an arbitrary label which is
remembered in the connected phone and consequently imprinted on each
call which is routed through this phone.

The async framework uses the address of the connection structure as the
label. This removes the need for a connection hash table because each
incoming call already remembers the connection in its label.

To disambiguate this new label and the other user-defined label used for
answers, the call structure now has the request_label member for the
former and answer_label member for the latter.

This commit also moves the kernel definition of ipc_data_t to abi/ and
removes the uspace redefinition thereof. Finally, when forwarding the
IPC_M_CONNECT_TO_ME call, the phone capability and the kernel object
allocated in request_process are now correctly disposed of.

Location:
kernel/generic
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/include/ipc/ipc.h

    r94ab1fee r6769005  
    6969        ipc_phone_state_t state;
    7070        atomic_t active_calls;
     71        /** User-defined label */
     72        sysarg_t label;
    7173        kobject_t *kobject;
    7274} phone_t;
     
    101103        list_t irq_notifs;
    102104} answerbox_t;
    103 
    104 typedef struct {
    105         sysarg_t args[IPC_CALL_LEN];
    106         /**
    107          * Task which made or forwarded the call with IPC_FF_ROUTE_FROM_ME,
    108          * or the task which answered the call.
    109          */
    110         task_id_t task_id;
    111         /** Phone which made or last masqueraded this call. */
    112         phone_t *phone;
    113         /** Flags */
    114         unsigned flags;
    115         /** User-defined label */
    116         sysarg_t label;
    117         /** Capability handle */
    118         cap_call_handle_t cap_handle;
    119 } ipc_data_t;
    120105
    121106typedef struct call {
  • kernel/generic/src/ipc/ipc.c

    r94ab1fee r6769005  
    205205        phone->state = IPC_PHONE_FREE;
    206206        atomic_store(&phone->active_calls, 0);
     207        phone->label = 0;
    207208        phone->kobject = NULL;
    208209}
     
    371372        }
    372373
    373         call->data.phone = phone;
     374        call->data.request_label = phone->label;
    374375        call->data.task_id = caller->taskid;
    375376}
     
    520521
    521522        if (mode & IPC_FF_ROUTE_FROM_ME) {
    522                 call->data.phone = newphone;
     523                call->data.request_label = newphone->label;
    523524                call->data.task_id = TASK->taskid;
    524525        }
     
    670671                list_remove(&phone->link);
    671672                phone->state = IPC_PHONE_SLAMMED;
     673                phone->label = 0;
    672674
    673675                if (notify_box) {
  • kernel/generic/src/ipc/ops/conctmeto.c

    r94ab1fee r6769005  
    4646         * That will be done once the phone is connected.
    4747         */
    48         cap_phone_handle_t phone_handle;
    49         kobject_t *phone_obj;
    50         errno_t rc = phone_alloc(TASK, false, &phone_handle, &phone_obj);
     48        cap_phone_handle_t phandle;
     49        kobject_t *pobj;
     50        errno_t rc = phone_alloc(TASK, false, &phandle, &pobj);
    5151        if (rc != EOK) {
    52                 call->priv = -1;
     52                call->priv = 0;
    5353                return rc;
    5454        }
    5555
    56         /* Hand over phone_obj's reference to ARG5 */
    57         IPC_SET_ARG5(call->data, (sysarg_t) phone_obj->phone);
     56        /* Move pobj's reference to call->priv */
     57        call->priv = (sysarg_t) pobj;
     58        pobj = NULL;
    5859
    5960        /* Remember the handle */
    60         call->priv = CAP_HANDLE_RAW(phone_handle);
     61        IPC_SET_ARG5(call->data, (sysarg_t) phandle);
    6162
    6263        return EOK;
     
    6566static errno_t request_forget(call_t *call)
    6667{
    67         cap_phone_handle_t phone_handle = (cap_handle_t) call->priv;
     68        cap_phone_handle_t phandle = (cap_handle_t) IPC_GET_ARG5(call->data);
    6869
    69         if (CAP_HANDLE_RAW(phone_handle) < 0)
     70        if (CAP_HANDLE_RAW(phandle) < 0)
    7071                return EOK;
    7172
    72         /* Hand over reference from ARG5 to phone->kobject */
    73         phone_t *phone = (phone_t *) IPC_GET_ARG5(call->data);
    74         /* Drop phone->kobject's reference */
    75         kobject_put(phone->kobject);
    76         cap_free(TASK, phone_handle);
     73        /* Move reference from call->priv to pobj */
     74        kobject_t *pobj = (kobject_t *) call->priv;
     75        call->priv = 0;
     76        /* Drop pobj's reference */
     77        kobject_put(pobj);
     78        cap_free(TASK, phandle);
    7779
    7880        return EOK;
     
    8183static errno_t answer_preprocess(call_t *answer, ipc_data_t *olddata)
    8284{
    83         /* Hand over reference from ARG5 to phone */
    84         phone_t *phone = (phone_t *) IPC_GET_ARG5(*olddata);
     85        /* Get an extra reference for phone */
     86        kobject_t *pobj = (kobject_t *) answer->priv;
     87        kobject_add_ref(pobj);
    8588
    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);
     89        /* Set the recipient-assigned label */
     90        pobj->phone->label = IPC_GET_ARG5(answer->data);
     91
     92        /* Restore phone handle in answer's ARG5 */
     93        IPC_SET_ARG5(answer->data, IPC_GET_ARG5(*olddata));
    9194
    9295        /* If the user accepted the call, connect */
    9396        if (IPC_GET_RETVAL(answer->data) == EOK) {
    94                 /* Hand over reference from phone to the answerbox */
    95                 (void) ipc_phone_connect(phone, &TASK->answerbox);
     97                /* Hand over reference from pobj to the answerbox */
     98                (void) ipc_phone_connect(pobj->phone, &TASK->answerbox);
    9699        } else {
    97                 kobject_put(phone->kobject);
     100                /* Drop the extra reference */
     101                kobject_put(pobj);
    98102        }
    99103
     
    103107static errno_t answer_process(call_t *answer)
    104108{
    105         cap_phone_handle_t phone_handle = (cap_handle_t) answer->priv;
    106         phone_t *phone = (phone_t *) IPC_GET_ARG5(answer->data);
     109        cap_phone_handle_t phandle = (cap_handle_t) IPC_GET_ARG5(answer->data);
     110        /* Move the reference from answer->priv to pobj */
     111        kobject_t *pobj = (kobject_t *) answer->priv;
     112        answer->priv = 0;
    107113
    108114        if (IPC_GET_RETVAL(answer->data)) {
    109                 if (CAP_HANDLE_RAW(phone_handle) >= 0) {
     115                if (CAP_HANDLE_RAW(phandle) >= 0) {
    110116                        /*
    111117                         * Cleanup the unpublished capability and drop
    112118                         * phone->kobject's reference.
    113119                         */
    114                         kobject_put(phone->kobject);
    115                         cap_free(TASK, phone_handle);
     120                        kobject_put(pobj);
     121                        cap_free(TASK, phandle);
    116122                }
    117123        } else {
     
    121127                 * capability for each phone that wasn't hung up by the user.
    122128                 */
    123                 cap_publish(TASK, phone_handle, phone->kobject);
    124 
    125                 IPC_SET_ARG5(answer->data, CAP_HANDLE_RAW(phone_handle));
     129                cap_publish(TASK, phandle, pobj);
    126130        }
    127131
  • kernel/generic/src/ipc/ops/concttome.c

    r94ab1fee r6769005  
    4242static int request_process(call_t *call, answerbox_t *box)
    4343{
    44         cap_phone_handle_t phone_handle;
    45         kobject_t *phone_obj;
    46         errno_t rc = phone_alloc(TASK, false, &phone_handle, &phone_obj);
    47         call->priv = (sysarg_t) phone_obj;
    48         IPC_SET_ARG5(call->data,
    49             (rc == EOK) ? CAP_HANDLE_RAW(phone_handle) : CAP_NIL);
     44        cap_phone_handle_t phandle = CAP_NIL;
     45        kobject_t *pobj = NULL;
     46        errno_t rc = phone_alloc(TASK, false, &phandle, &pobj);
     47        if (rc == EOK) {
     48                /*
     49                 * Set the sender-assigned label to the new phone.
     50                 */
     51                pobj->phone->label = IPC_GET_ARG5(call->data);
     52        }
     53        call->priv = (sysarg_t) pobj;
     54        IPC_SET_ARG5(call->data, CAP_HANDLE_RAW(phandle));
    5055        return 0;
    5156}
     
    5358static errno_t answer_cleanup(call_t *answer, ipc_data_t *olddata)
    5459{
    55         cap_phone_handle_t phone_handle = (cap_handle_t) IPC_GET_ARG5(*olddata);
    56         kobject_t *phone_obj = (kobject_t *) answer->priv;
     60        cap_phone_handle_t phandle = (cap_handle_t) IPC_GET_ARG5(*olddata);
     61        kobject_t *pobj = (kobject_t *) answer->priv;
    5762
    58         if (CAP_HANDLE_VALID(phone_handle)) {
    59                 kobject_put(phone_obj);
    60                 cap_free(TASK, phone_handle);
     63        if (CAP_HANDLE_VALID(phandle)) {
     64                kobject_put(pobj);
     65                cap_free(TASK, phandle);
    6166        }
    6267
     
    6671static errno_t answer_preprocess(call_t *answer, ipc_data_t *olddata)
    6772{
    68         cap_phone_handle_t phone_handle = (cap_handle_t) IPC_GET_ARG5(*olddata);
    69         kobject_t *phone_obj = (kobject_t *) answer->priv;
     73        cap_phone_handle_t phandle = (cap_handle_t) IPC_GET_ARG5(*olddata);
     74        kobject_t *pobj = (kobject_t *) answer->priv;
    7075
    7176        if (IPC_GET_RETVAL(answer->data) != EOK) {
    7277                /* The connection was not accepted */
    7378                answer_cleanup(answer, olddata);
    74         } else if (CAP_HANDLE_VALID(phone_handle)) {
     79        } else if (CAP_HANDLE_VALID(phandle)) {
    7580                /*
    7681                 * The connection was accepted
     
    8186                 * will be consumed by ipc_phone_connect().
    8287                 */
    83                 kobject_add_ref(phone_obj);
     88                kobject_add_ref(pobj);
    8489
    85                 if (ipc_phone_connect(phone_obj->phone,
     90                if (ipc_phone_connect(pobj->phone,
    8691                    &answer->sender->answerbox)) {
    8792                        /* Pass the reference to the capability */
    88                         cap_publish(TASK, phone_handle, phone_obj);
    89                         /* Set 'phone hash' as ARG5 of response */
    90                         IPC_SET_ARG5(answer->data,
    91                             (sysarg_t) phone_obj->phone);
     93                        cap_publish(TASK, phandle, pobj);
    9294                } else {
    9395                        /* The answerbox is shutting down. */
  • kernel/generic/src/ipc/sysipc.c

    r94ab1fee r6769005  
    202202                        kobject_put(phone->kobject);
    203203                        phone->state = IPC_PHONE_SLAMMED;
     204                        phone->label = 0;
    204205                        irq_spinlock_unlock(&phone->callee->lock, true);
    205206                }
     
    386387
    387388        /* Set the user-defined label */
    388         call->data.label = label;
     389        call->data.answer_label = label;
    389390
    390391        errno_t res = request_preprocess(call, kobj->phone);
     
    430431
    431432        /* Set the user-defined label */
    432         call->data.label = label;
     433        call->data.answer_label = label;
    433434
    434435        errno_t res = request_preprocess(call, kobj->phone);
     
    504505        if (!method_is_immutable(IPC_GET_IMETHOD(call->data))) {
    505506                if (method_is_system(IPC_GET_IMETHOD(call->data))) {
    506                         if (IPC_GET_IMETHOD(call->data) == IPC_M_CONNECT_TO_ME)
    507                                 phone_dealloc((cap_phone_handle_t)
    508                                     IPC_GET_ARG5(call->data));
     507                        if (IPC_GET_IMETHOD(call->data) ==
     508                            IPC_M_CONNECT_TO_ME) {
     509                                kobject_put((kobject_t *) call->priv);
     510                                call->priv = 0;
     511                                cap_free(TASK,
     512                                    (cap_handle_t) IPC_GET_ARG5(call->data));
     513                        }
    509514
    510515                        IPC_SET_ARG1(call->data, imethod);
     
    771776        call->data.flags = call->flags;
    772777        if (call->flags & IPC_CALL_NOTIF) {
    773                 /* Set in_phone_hash to the interrupt counter */
    774                 call->data.phone = (void *) call->priv;
     778                /* Set the request_label to the interrupt counter */
     779                call->data.request_label = (sysarg_t) call->priv;
    775780
    776781                call->data.cap_handle = CAP_NIL;
Note: See TracChangeset for help on using the changeset viewer.