Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset d51a0d6 in mainline


Ignore:
Timestamp:
2017-11-21T22:23:00Z (3 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
master
Children:
35f2bb1
Parents:
c4c6025
Message:

Associate a kobject_t with a call_t

Let all the reference counting be done on call_t::kobject.

Location:
kernel/generic
Files:
4 edited

Legend:

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

    rc4c6025 rd51a0d6  
    5353
    5454typedef enum {
     55        KOBJECT_TYPE_CALL,
     56        KOBJECT_TYPE_IRQ,
    5557        KOBJECT_TYPE_PHONE,
    56         KOBJECT_TYPE_IRQ,
    5758        KOBJECT_TYPE_MAX
    5859} kobject_type_t;
    5960
    6061struct task;
     62
     63struct call;
     64struct irq;
    6165struct phone;
    62 struct irq;
    6366
    6467struct kobject;
     
    7982        union {
    8083                void *raw;
     84                struct call *call;
     85                struct irq *irq;
    8186                struct phone *phone;
    82                 struct irq *irq;
    8387        };
    8488} kobject_t;
  • kernel/generic/include/ipc/ipc.h

    rc4c6025 rd51a0d6  
    109109
    110110typedef struct {
     111        kobject_t *kobject;
     112
    111113        /**
    112114         * Task link.
     
    115117         */
    116118        link_t ta_link;
    117 
    118         atomic_t refcnt;
    119119
    120120        /** Answerbox link. */
  • kernel/generic/src/ipc/ipc.c

    rc4c6025 rd51a0d6  
    8787}
    8888
    89 void ipc_call_hold(call_t *call)
    90 {
    91         atomic_inc(&call->refcnt);
    92 }
    93 
    94 void ipc_call_release(call_t *call)
    95 {
    96         if (atomic_predec(&call->refcnt) == 0) {
    97                 if (call->buffer)
    98                         free(call->buffer);
    99                 if (call->caller_phone)
    100                         kobject_put(call->caller_phone->kobject);
    101                 slab_free(call_slab, call);
    102         }
    103 }
     89static void call_destroy(void *arg)
     90{
     91        call_t *call = (call_t *) arg;
     92
     93        if (call->buffer)
     94                free(call->buffer);
     95        if (call->caller_phone)
     96                kobject_put(call->caller_phone->kobject);
     97        slab_free(call_slab, call);
     98}
     99
     100static kobject_ops_t call_kobject_ops = {
     101        .destroy = call_destroy
     102};
    104103
    105104/** Allocate and initialize a call structure.
     
    117116{
    118117        call_t *call = slab_alloc(call_slab, flags);
    119         if (call) {
    120                 _ipc_call_init(call);
    121                 ipc_call_hold(call);
    122         }
     118        if (!call)
     119                return NULL;
     120        kobject_t *kobj = (kobject_t *) malloc(sizeof(kobject_t), flags);
     121        if (!kobj) {
     122                slab_free(call_slab, call);
     123                return NULL;
     124        }
     125
     126        _ipc_call_init(call);
     127        kobject_initialize(kobj, KOBJECT_TYPE_CALL, call, &call_kobject_ops);
     128        call->kobject = kobj;
    123129       
    124130        return call;
    125 }
    126 
    127 /** Deallocate a call structure.
    128  *
    129  * @param call Call structure to be freed.
    130  *
    131  */
    132 void ipc_call_free(call_t *call)
    133 {
    134         ipc_call_release(call);
    135131}
    136132
     
    290286                /* This is a forgotten call and call->sender is not valid. */
    291287                spinlock_unlock(&call->forget_lock);
    292                 ipc_call_free(call);
     288                kobject_put(call->kobject);
    293289                return;
    294290        } else {
     
    705701         * must hold a reference to it.
    706702         */
    707         ipc_call_hold(call);
     703        kobject_add_ref(call->kobject);
    708704
    709705        spinlock_unlock(&call->forget_lock);
     
    714710        SYSIPC_OP(request_forget, call);
    715711
    716         ipc_call_release(call);
     712        kobject_put(call->kobject);
    717713}
    718714
     
    822818        SYSIPC_OP(answer_process, call);
    823819
    824         ipc_call_free(call);
     820        kobject_put(call->kobject);
    825821        goto restart;
    826822}
  • kernel/generic/src/ipc/sysipc.c

    rc4c6025 rd51a0d6  
    286286#endif
    287287
    288                 ipc_call_hold(call);
     288                kobject_add_ref(call->kobject);
    289289                rc = ipc_call_sync(kobj->phone, call);
    290290                spinlock_lock(&call->forget_lock);
    291291                bool forgotten = call->forget;
    292292                spinlock_unlock(&call->forget_lock);
    293                 ipc_call_release(call);
     293                kobject_put(call->kobject);
    294294
    295295#ifdef CONFIG_UDEBUG
     
    306306                                 * deallocation.
    307307                                 */
    308                                 ipc_call_free(call);
     308                                kobject_put(call->kobject);
    309309                        } else {
    310310                                /*
     
    323323       
    324324        memcpy(data->args, call->data.args, sizeof(data->args));
    325         ipc_call_free(call);
     325        kobject_put(call->kobject);
    326326        kobject_put(kobj);
    327327       
     
    420420            sizeof(call->data.args));
    421421        if (rc != 0) {
    422                 ipc_call_free(call);
     422                kobject_put(call->kobject);
    423423                kobject_put(kobj);
    424424                return (sysarg_t) rc;
     
    753753                STRUCT_TO_USPACE(calldata, &call->data);
    754754               
    755                 ipc_call_free(call);
     755                kobject_put(call->kobject);
    756756               
    757757                return ((sysarg_t) call) | IPC_CALLID_NOTIFICATION;
     
    762762               
    763763                if (call->flags & IPC_CALL_DISCARD_ANSWER) {
    764                         ipc_call_free(call);
     764                        kobject_put(call->kobject);
    765765                        goto restart;
    766766                }
    767767               
    768768                STRUCT_TO_USPACE(calldata, &call->data);
    769                 ipc_call_free(call);
     769                kobject_put(call->kobject);
    770770               
    771771                return ((sysarg_t) call) | IPC_CALLID_ANSWERED;
Note: See TracChangeset for help on using the changeset viewer.