Page 1 of 1

Process quota handling for client/server transactions

Posted: Fri Sep 13, 2013 11:00 am
by Gigasoft
Suppose that A and B are different users running programs on a central shared computer. Each user has a designated maximum resource usage limit. User B is running a program that services requests from arbitrary other programs. B is at his memory usage limit. User A then requests an operation from user B's service, causing memory pages to be allocated (and charged to A's account). A then cancels the operation before it is complete. After allowing B a reasonable amount of time to respond, B has still not released the pages that were allocated on behalf of A, and the pages must be transferred to B's account, which is full. What would be the ideal action to take in this situation? Should I just forcibly terminate B's program?

Re: Process quota handling for client/server transactions

Posted: Fri Sep 13, 2013 11:10 am
by OSwhatever
No, reboot and recompile the internet.

Re: Process quota handling for client/server transactions

Posted: Fri Sep 13, 2013 11:32 am
by cxzuk
Gigasoft wrote:Suppose that A and B are different users running programs on a central shared computer. Each user has a designated maximum resource usage limit. User B is running a program that services requests from arbitrary other programs. B is at his memory usage limit. User A then requests an operation from user B's service[2], causing memory pages to be allocated (and charged to A's account)[1]. A then cancels the operation before it is complete. After allowing B a reasonable amount of time to respond, B has still not released the pages that were allocated on behalf of A, and the pages must be transferred to B's account, which is full. What would be the ideal action to take in this situation? Should I just forcibly terminate B's program?
I can only presume the page allocated[1] is to deal with the service request[2]?

If so, I feel this is a mistake. I dont see why the allocation must be done in User A's space and not in B's.

The right action for me seems to be to fail at the point A sends the request to B, because B will try to allocate any required memory and will fail.

Re: Process quota handling for client/server transactions

Posted: Fri Sep 13, 2013 1:29 pm
by Gigasoft
I was hoping to provide a way for charging resource usage to the party which initiates an operation, even though it may be in part be implemented by a different party. Otherwise, any user would be able to interfere with the availability of any service it has access to by submitting many resource intensive requests at once (unless we also associated an usage limit with each user's access to B's service, which would make things a bit complicated). But I guess, one could create a new process for every client, which would allocate resources from the client's quota and terminate automatically after a set time when no more requests are outstanding, while communicating with a main process which only ever allocates from the service provider's quota, thereby preventing unexpected shutdowns of the service itself due to circumstances that are hard to control. Or, one could let the client specify a "maximum allowed cancellation time" when initiating a request, and the service provider would then be able to reserve some cancellation time for itself while passing the rest to any other service it uses as part of servicing the initial user. Canceling an operation would then also automatically cancel any operation that is connected to the first, if they have not been already canceled when the first timer expires. I suppose that ought to work.

Re: Process quota handling for client/server transactions

Posted: Fri Sep 13, 2013 5:57 pm
by linguofreak
cxzuk wrote:If so, I feel this is a mistake. I dont see why the allocation must be done in User A's space and not in B's.
As I understand it, the memory is allocated in B's address space, but is to be counted against A's resource limits.

The question is "If B leaks memory allocated for A's request, how do we prevent that from counting against A once the request has been completed or canceled?".

One way I could see it being done is if there's a mechanism for processes to donate resource quota to other processes. You might have a situation something like this:
  • A makes a request and passes a request number to B as a parameter.

    B allocates memory to process the request using its own heap and memory quota, and marks the memory with the request number it got from A.

    B allocates memory for its own use and runs up against its memory limit. It looks through its heap for memory allocated to handle other processes' requests, and finds the allocation it made for A. It sends a "I need a larger memory quota to process your request" message to A, passing the request number as a parameter.

    A makes a system call to donate some of its memory quota to B, using the request number as a parameter. An amount is subtracted from A's quota and an equal amount is added to B's, and the system call handler logs the request number. A then signals B to tell it that the memory is available. If A refuses to donate from its quota, B may cancel A's request and send an error back to A, though it might also try to get memory from other processes with outstanding requests if it can.

    After a while, A cancels the request, or B completes it. A bug causes B to leak some of the memory that it used to process A's request.

    If A has canceled the request, A then makes a system call to revoke the memory donation it made to B, using the request number as a parameter. The system call handler makes sure that the request number matches a donation A had previously made to B, (to prevent A from stealing memory from, and potentially DOS'ing, B by revoking a donation it never made, or by revoking the same donation twice). The system call handler then signals B with the request number (so that, if A had revoked the donation before canceling the request, B could cancel the request and deallocate the memory). The system call handler expects that when B's signal handler returns, B will be under its quota. Since it has leaked memory, it is not under quota and gets killed,

    Alternatively, if B completed the request, B can make its own system call to release the donated memory. The system call handler expects B to be under its post-release quota when it makes the call. Since it has leaked memory, it is killed.