The deletion process is performed by ipc_rmid, as shown in Figure 10. This function is called with the lock held, and returns with it held. Lines 4-9 obtain a pointer to the sem_array structure. Line 10 NULLs the pointer to sem_array, removing any path from a permanent variable to this structure. Lines 11-12 perform a debug check, which could be triggered by locking design bugs, among other things. Lines 13-22 adjust the count of semaphores in response to the removal of this one, and then, if this semaphore had the largest ID, scans down the array of ipc_ids to find the new largest ID. Line 23 sets the deleted flag, so that the next acquisition of the lock will fail (see Section 4.3 below), and Line 24 returns a pointer to the newly removed semaphore. The semaphore's memory is freed up by a call to ipc_rcu_free() by freeary(), which is ipc_rmid()'s caller and which also performs other cleanup actions, including waking up any processes that were sleeping on the newly removed semaphore.
The deleted flag, once set, makes the corresponding semaphore set appear to be freed up even though it is still in memory awaiting expiration of its grace period, as will be shown in the next section.